VM: use an std::vector instead of a fixed-size buffer for GC roots
							parent
							
								
									8b6ec8e030
								
							
						
					
					
						commit
						81c4670619
					
				|  | @ -266,19 +266,21 @@ static void copy_stack_elements(segment *region, cell top) | |||
| 
 | ||||
| static void copy_registered_locals() | ||||
| { | ||||
| 	cell scan = gc_locals_region->start; | ||||
| 	std::vector<cell>::const_iterator iter = gc_locals.begin(); | ||||
| 	std::vector<cell>::const_iterator end = gc_locals.end(); | ||||
| 
 | ||||
| 	for(; scan <= gc_locals; scan += sizeof(cell)) | ||||
| 		copy_handle(*(cell **)scan); | ||||
| 	for(; iter < end; iter++) | ||||
| 		copy_handle((cell *)(*iter)); | ||||
| } | ||||
| 
 | ||||
| static void copy_registered_bignums() | ||||
| { | ||||
| 	cell scan = gc_bignums_region->start; | ||||
| 	std::vector<cell>::const_iterator iter = gc_bignums.begin(); | ||||
| 	std::vector<cell>::const_iterator end = gc_bignums.end(); | ||||
| 
 | ||||
| 	for(; scan <= gc_bignums; scan += sizeof(cell)) | ||||
| 	for(; iter < end; iter++) | ||||
| 	{ | ||||
| 		bignum **handle = *(bignum ***)scan; | ||||
| 		bignum **handle = (bignum **)(*iter); | ||||
| 		bignum *pointer = *handle; | ||||
| 
 | ||||
| 		if(pointer) | ||||
|  | @ -683,12 +685,12 @@ PRIMITIVE(become) | |||
| VM_ASM_API void inline_gc(cell *gc_roots_base, cell gc_roots_size) | ||||
| { | ||||
| 	for(cell i = 0; i < gc_roots_size; i++) | ||||
| 		gc_local_push((cell)&gc_roots_base[i]); | ||||
| 		gc_locals.push_back((cell)&gc_roots_base[i]); | ||||
| 
 | ||||
| 	garbage_collection(data->nursery(),false,0); | ||||
| 
 | ||||
| 	for(cell i = 0; i < gc_roots_size; i++) | ||||
| 		gc_local_pop(); | ||||
| 		gc_locals.pop_back(); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -183,15 +183,7 @@ void init_data_heap(cell gens, | |||
| 	bool secure_gc_) | ||||
| { | ||||
| 	set_data_heap(alloc_data_heap(gens,young_size,aging_size,tenured_size)); | ||||
| 
 | ||||
| 	gc_locals_region = alloc_segment(getpagesize()); | ||||
| 	gc_locals = gc_locals_region->start - sizeof(cell); | ||||
| 
 | ||||
| 	gc_bignums_region = alloc_segment(getpagesize()); | ||||
| 	gc_bignums = gc_bignums_region->start - sizeof(cell); | ||||
| 
 | ||||
| 	secure_gc = secure_gc_; | ||||
| 
 | ||||
| 	init_data_gc(); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -41,8 +41,8 @@ void throw_error(cell error, stack_frame *callstack_top) | |||
| 		gc_off = false; | ||||
| 
 | ||||
| 		/* Reset local roots */ | ||||
| 		gc_locals = gc_locals_region->start - sizeof(cell); | ||||
| 		gc_bignums = gc_bignums_region->start - sizeof(cell); | ||||
| 		gc_locals.clear(); | ||||
| 		gc_bignums.clear(); | ||||
| 
 | ||||
| 		/* If we had an underflow or overflow, stack pointers might be
 | ||||
| 		out of bounds */ | ||||
|  |  | |||
|  | @ -3,10 +3,8 @@ | |||
| namespace factor | ||||
| { | ||||
| 
 | ||||
| segment *gc_locals_region; | ||||
| cell gc_locals; | ||||
| std::vector<cell> gc_locals; | ||||
| 
 | ||||
| segment *gc_bignums_region; | ||||
| cell gc_bignums; | ||||
| std::vector<cell> gc_bignums; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -4,15 +4,12 @@ namespace factor | |||
| /* If a runtime function needs to call another function which potentially
 | ||||
| allocates memory, it must wrap any local variable references to Factor | ||||
| objects in gc_root instances */ | ||||
| extern segment *gc_locals_region; | ||||
| extern cell gc_locals; | ||||
| 
 | ||||
| DEFPUSHPOP(gc_local_,gc_locals) | ||||
| extern std::vector<cell> gc_locals; | ||||
| 
 | ||||
| template <typename T> | ||||
| struct gc_root : public tagged<T> | ||||
| { | ||||
| 	void push() { check_tagged_pointer(tagged<T>::value()); gc_local_push((cell)this); } | ||||
| 	void push() { check_tagged_pointer(tagged<T>::value()); gc_locals.push_back((cell)this); } | ||||
| 	 | ||||
| 	explicit gc_root(cell value_) : tagged<T>(value_) { push(); } | ||||
| 	explicit gc_root(T *value_) : tagged<T>(value_) { push(); } | ||||
|  | @ -22,19 +19,15 @@ struct gc_root : public tagged<T> | |||
| 
 | ||||
| 	~gc_root() { | ||||
| #ifdef FACTOR_DEBUG | ||||
| 		cell old = gc_local_pop(); | ||||
| 		assert(old == (cell)this); | ||||
| 		assert(gc_locals.back() == (cell)this); | ||||
| #else | ||||
| 		gc_local_pop(); | ||||
| 		gc_locals.pop_back(); | ||||
| #endif | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| /* A similar hack for the bignum implementation */ | ||||
| extern segment *gc_bignums_region; | ||||
| extern cell gc_bignums; | ||||
| 
 | ||||
| DEFPUSHPOP(gc_bignum_,gc_bignums) | ||||
| extern std::vector<cell> gc_bignums; | ||||
| 
 | ||||
| struct gc_bignum | ||||
| { | ||||
|  | @ -43,10 +36,15 @@ struct gc_bignum | |||
| 	gc_bignum(bignum **addr_) : addr(addr_) { | ||||
| 		if(*addr_) | ||||
| 			check_data_pointer(*addr_); | ||||
| 		gc_bignum_push((cell)addr); | ||||
| 		gc_bignums.push_back((cell)addr); | ||||
| 	} | ||||
| 
 | ||||
| 	~gc_bignum() { assert((cell)addr == gc_bignum_pop()); } | ||||
| 	~gc_bignum() { | ||||
| #ifdef FACTOR_DEBUG | ||||
| 		assert(gc_bignums.back() == (cell)addr); | ||||
| #endif | ||||
| 		gc_bignums.pop_back(); | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| #define GC_BIGNUM(x) gc_bignum x##__gc_root(&x) | ||||
|  |  | |||
|  | @ -21,6 +21,8 @@ | |||
| #include <time.h> | ||||
| 
 | ||||
| /* C++ headers */ | ||||
| #include <vector> | ||||
| 
 | ||||
| #if __GNUC__ == 4 | ||||
|         #include <tr1/unordered_map> | ||||
|         #define unordered_map std::tr1::unordered_map | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue