vm: faster data_root and <array> primitive
							parent
							
								
									a46671e3ad
								
							
						
					
					
						commit
						11075828e5
					
				| 
						 | 
					@ -7,9 +7,9 @@ namespace factor
 | 
				
			||||||
array *factor_vm::allot_array(cell capacity, cell fill_)
 | 
					array *factor_vm::allot_array(cell capacity, cell fill_)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	data_root<object> fill(fill_,this);
 | 
						data_root<object> fill(fill_,this);
 | 
				
			||||||
	data_root<array> new_array(allot_uninitialized_array<array>(capacity),this);
 | 
						array *new_array = allot_uninitialized_array<array>(capacity);
 | 
				
			||||||
	memset_cell(new_array->data(),fill.value(),capacity * sizeof(cell));
 | 
						memset_cell(new_array->data(),fill.value(),capacity * sizeof(cell));
 | 
				
			||||||
	return new_array.untagged();
 | 
						return new_array;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* push a new array on the stack */
 | 
					/* push a new array on the stack */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -245,13 +245,11 @@ cell factor_vm::instances(cell type)
 | 
				
			||||||
	each_object(accum);
 | 
						each_object(accum);
 | 
				
			||||||
	cell object_count = accum.objects.size();
 | 
						cell object_count = accum.objects.size();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data_roots.push_back((cell)&accum.objects[0]);
 | 
						data_roots.push_back(data_root_range(&accum.objects[0],object_count));
 | 
				
			||||||
	data_roots.push_back(object_count);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	array *objects = allot_array(object_count,false_object);
 | 
						array *objects = allot_array(object_count,false_object);
 | 
				
			||||||
	memcpy(objects->data(),&accum.objects[0],object_count * sizeof(cell));
 | 
						memcpy(objects->data(),&accum.objects[0],object_count * sizeof(cell));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data_roots.pop_back();
 | 
					 | 
				
			||||||
	data_roots.pop_back();
 | 
						data_roots.pop_back();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return tag<array>(objects);
 | 
						return tag<array>(objects);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,8 +7,7 @@ struct data_root : public tagged<Type> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void push()
 | 
						void push()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		parent->data_roots.push_back((cell)this);
 | 
							parent->data_roots.push_back(data_root_range(&this->value_,1));
 | 
				
			||||||
		parent->data_roots.push_back(1);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	explicit data_root(cell value_, factor_vm *parent_)
 | 
						explicit data_root(cell value_, factor_vm *parent_)
 | 
				
			||||||
| 
						 | 
					@ -28,13 +27,6 @@ struct data_root : public tagged<Type> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	~data_root()
 | 
						~data_root()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
#ifdef FACTOR_DEBUG
 | 
					 | 
				
			||||||
		assert(parent->data_roots.back() == 1);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
		parent->data_roots.pop_back();
 | 
					 | 
				
			||||||
#ifdef FACTOR_DEBUG
 | 
					 | 
				
			||||||
		assert(parent->data_roots.back() == (cell)this);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
		parent->data_roots.pop_back();
 | 
							parent->data_roots.pop_back();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										10
									
								
								vm/gc.cpp
								
								
								
								
							
							
						
						
									
										10
									
								
								vm/gc.cpp
								
								
								
								
							| 
						 | 
					@ -218,18 +218,14 @@ void factor_vm::primitive_compact_gc()
 | 
				
			||||||
		true /* trace contexts? */);
 | 
							true /* trace contexts? */);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void factor_vm::inline_gc(cell data_roots_base, cell data_roots_size)
 | 
					void factor_vm::inline_gc(cell *data_roots_base, cell data_roots_size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	data_roots.push_back(data_roots_base);
 | 
						data_roots.push_back(data_root_range(data_roots_base,data_roots_size));
 | 
				
			||||||
	data_roots.push_back(data_roots_size);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	primitive_minor_gc();
 | 
						primitive_minor_gc();
 | 
				
			||||||
 | 
					 | 
				
			||||||
	data_roots.pop_back();
 | 
					 | 
				
			||||||
	data_roots.pop_back();
 | 
						data_roots.pop_back();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
VM_C_API void inline_gc(cell data_roots_base, cell data_roots_size, factor_vm *parent)
 | 
					VM_C_API void inline_gc(cell *data_roots_base, cell data_roots_size, factor_vm *parent)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	parent->inline_gc(data_roots_base,data_roots_size);
 | 
						parent->inline_gc(data_roots_base,data_roots_size);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,6 +53,6 @@ struct gc_state {
 | 
				
			||||||
	void start_again(gc_op op_, factor_vm *parent);
 | 
						void start_again(gc_op op_, factor_vm *parent);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
VM_C_API void inline_gc(cell data_roots_base, cell data_roots_size, factor_vm *parent);
 | 
					VM_C_API void inline_gc(cell *data_roots_base, cell data_roots_size, factor_vm *parent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -373,4 +373,12 @@ struct tuple : public object {
 | 
				
			||||||
	cell *data() const { return (cell *)(this + 1); }
 | 
						cell *data() const { return (cell *)(this + 1); }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct data_root_range {
 | 
				
			||||||
 | 
						cell *start;
 | 
				
			||||||
 | 
						cell len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						explicit data_root_range(cell *start_, cell len_) :
 | 
				
			||||||
 | 
							start(start_), len(len_) {}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,15 +43,14 @@ template<typename Visitor> struct slot_visitor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void visit_data_roots()
 | 
						void visit_data_roots()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		std::vector<cell>::const_iterator iter = parent->data_roots.begin();
 | 
							std::vector<data_root_range>::const_iterator iter = parent->data_roots.begin();
 | 
				
			||||||
		std::vector<cell>::const_iterator end = parent->data_roots.end();
 | 
							std::vector<data_root_range>::const_iterator end = parent->data_roots.end();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		while(iter < end)
 | 
							for(; iter < end; iter++)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			cell start = *iter++;
 | 
								data_root_range r = *iter;
 | 
				
			||||||
			cell len = *iter++;
 | 
								for(cell index = 0; index < r.len; index++)
 | 
				
			||||||
			for(cell index = 0; index < len; index++)
 | 
									visit_handle(r.start + index);
 | 
				
			||||||
				visit_handle((cell *)start + index);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,7 +62,7 @@ struct factor_vm
 | 
				
			||||||
	   allocates memory, it must wrap any references to the data and code
 | 
						   allocates memory, it must wrap any references to the data and code
 | 
				
			||||||
	   heaps with data_root and code_root smart pointers, which register
 | 
						   heaps with data_root and code_root smart pointers, which register
 | 
				
			||||||
	   themselves here. See data_roots.hpp and code_roots.hpp */
 | 
						   themselves here. See data_roots.hpp and code_roots.hpp */
 | 
				
			||||||
	std::vector<cell> data_roots;
 | 
						std::vector<data_root_range> data_roots;
 | 
				
			||||||
	std::vector<cell> bignum_roots;
 | 
						std::vector<cell> bignum_roots;
 | 
				
			||||||
	std::vector<code_root *> code_roots;
 | 
						std::vector<code_root *> code_roots;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -281,7 +281,7 @@ struct factor_vm
 | 
				
			||||||
	void primitive_minor_gc();
 | 
						void primitive_minor_gc();
 | 
				
			||||||
	void primitive_full_gc();
 | 
						void primitive_full_gc();
 | 
				
			||||||
	void primitive_compact_gc();
 | 
						void primitive_compact_gc();
 | 
				
			||||||
	void inline_gc(cell data_roots_base, cell data_roots_size);
 | 
						void inline_gc(cell *data_roots_base, cell data_roots_size);
 | 
				
			||||||
	void primitive_enable_gc_events();
 | 
						void primitive_enable_gc_events();
 | 
				
			||||||
	void primitive_disable_gc_events();
 | 
						void primitive_disable_gc_events();
 | 
				
			||||||
	object *allot_object(header header, cell size);
 | 
						object *allot_object(header header, cell size);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue