vm: split off free_list_allocator from heap class, rename zone to bump_allocator
							parent
							
								
									5608bc1268
								
							
						
					
					
						commit
						f0816d72f1
					
				
							
								
								
									
										2
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										2
									
								
								Makefile
								
								
								
								
							|  | @ -55,7 +55,7 @@ DLL_OBJS = $(PLAF_DLL_OBJS) \ | ||||||
| 	vm/jit.o \
 | 	vm/jit.o \
 | ||||||
| 	vm/math.o \
 | 	vm/math.o \
 | ||||||
| 	vm/nursery_collector.o \
 | 	vm/nursery_collector.o \
 | ||||||
| 	vm/old_space.o \
 | 	vm/object_start_map.o \
 | ||||||
| 	vm/primitives.o \
 | 	vm/primitives.o \
 | ||||||
| 	vm/profiler.o \
 | 	vm/profiler.o \
 | ||||||
| 	vm/quotations.o \
 | 	vm/quotations.o \
 | ||||||
|  |  | ||||||
|  | @ -3,7 +3,8 @@ namespace factor | ||||||
| 
 | 
 | ||||||
| struct aging_policy { | struct aging_policy { | ||||||
| 	factor_vm *parent; | 	factor_vm *parent; | ||||||
| 	zone *aging, *tenured; | 	aging_space *aging; | ||||||
|  | 	tenured_space *tenured; | ||||||
| 
 | 
 | ||||||
| 	aging_policy(factor_vm *parent_) : | 	aging_policy(factor_vm *parent_) : | ||||||
| 		parent(parent_), | 		parent(parent_), | ||||||
|  |  | ||||||
|  | @ -1,17 +1,17 @@ | ||||||
| namespace factor | namespace factor | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| struct aging_space : zone { | struct aging_space : bump_allocator { | ||||||
| 	object_start_map starts; | 	object_start_map starts; | ||||||
| 
 | 
 | ||||||
| 	aging_space(cell size, cell start) : | 	aging_space(cell size, cell start) : | ||||||
| 		zone(size,start), starts(size,start) {} | 		bump_allocator(size,start), starts(size,start) {} | ||||||
| 
 | 
 | ||||||
| 	object *allot(cell size) | 	object *allot(cell size) | ||||||
| 	{ | 	{ | ||||||
| 		if(here + size > end) return NULL; | 		if(here + size > end) return NULL; | ||||||
| 
 | 
 | ||||||
| 		object *obj = zone::allot(size); | 		object *obj = bump_allocator::allot(size); | ||||||
| 		starts.record_object_start_offset(obj); | 		starts.record_object_start_offset(obj); | ||||||
| 		return obj; | 		return obj; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -1,14 +1,15 @@ | ||||||
| namespace factor | namespace factor | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| struct zone { | struct bump_allocator { | ||||||
| 	/* offset of 'here' and 'end' is hardcoded in compiler backends */ | 	/* offset of 'here' and 'end' is hardcoded in compiler backends */ | ||||||
| 	cell here; | 	cell here; | ||||||
| 	cell start; | 	cell start; | ||||||
| 	cell end; | 	cell end; | ||||||
| 	cell size; | 	cell size; | ||||||
| 
 | 
 | ||||||
| 	zone(cell size_, cell start_) : here(0), start(start_), end(start_ + size_), size(size_) {} | 	bump_allocator(cell size_, cell start_) : | ||||||
|  | 		here(0), start(start_), end(start_ + size_), size(size_) {} | ||||||
| 
 | 
 | ||||||
| 	inline bool contains_p(object *pointer) | 	inline bool contains_p(object *pointer) | ||||||
| 	{ | 	{ | ||||||
|  | @ -439,7 +439,7 @@ void factor_vm::fixup_labels(array *labels, code_block *compiled) | ||||||
| /* Might GC */ | /* Might GC */ | ||||||
| code_block *factor_vm::allot_code_block(cell size, code_block_type type) | code_block *factor_vm::allot_code_block(cell size, code_block_type type) | ||||||
| { | { | ||||||
| 	heap_block *block = code->heap_allot(size + sizeof(code_block)); | 	heap_block *block = code->allocator->allot(size + sizeof(code_block)); | ||||||
| 
 | 
 | ||||||
| 	/* If allocation failed, do a full GC and compact the code heap.
 | 	/* If allocation failed, do a full GC and compact the code heap.
 | ||||||
| 	A full GC that occurs as a result of the data heap filling up does not | 	A full GC that occurs as a result of the data heap filling up does not | ||||||
|  | @ -449,13 +449,13 @@ code_block *factor_vm::allot_code_block(cell size, code_block_type type) | ||||||
| 	if(block == NULL) | 	if(block == NULL) | ||||||
| 	{ | 	{ | ||||||
| 		primitive_compact_gc(); | 		primitive_compact_gc(); | ||||||
| 		block = code->heap_allot(size + sizeof(code_block)); | 		block = code->allocator->allot(size + sizeof(code_block)); | ||||||
| 
 | 
 | ||||||
| 		/* Insufficient room even after code GC, give up */ | 		/* Insufficient room even after code GC, give up */ | ||||||
| 		if(block == NULL) | 		if(block == NULL) | ||||||
| 		{ | 		{ | ||||||
| 			cell used, total_free, max_free; | 			cell used, total_free, max_free; | ||||||
| 			code->heap_usage(&used,&total_free,&max_free); | 			code->allocator->usage(&used,&total_free,&max_free); | ||||||
| 
 | 
 | ||||||
| 			print_string("Code heap stats:\n"); | 			print_string("Code heap stats:\n"); | ||||||
| 			print_string("Used: "); print_cell(used); nl(); | 			print_string("Used: "); print_cell(used); nl(); | ||||||
|  |  | ||||||
|  | @ -3,7 +3,21 @@ | ||||||
| namespace factor | namespace factor | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| code_heap::code_heap(bool secure_gc, cell size) : heap<heap_block>(secure_gc,size,true) {} | code_heap::code_heap(cell size) | ||||||
|  | { | ||||||
|  | 	if(size > (1L << (sizeof(cell) * 8 - 6))) fatal_error("Heap too large",size); | ||||||
|  | 	seg = new segment(align_page(size),true); | ||||||
|  | 	if(!seg) fatal_error("Out of memory in heap allocator",size); | ||||||
|  | 	allocator = new free_list_allocator<heap_block>(seg->start,size); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | code_heap::~code_heap() | ||||||
|  | { | ||||||
|  | 	delete allocator; | ||||||
|  | 	allocator = NULL; | ||||||
|  | 	delete seg; | ||||||
|  | 	seg = NULL; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| void code_heap::write_barrier(code_block *compiled) | void code_heap::write_barrier(code_block *compiled) | ||||||
| { | { | ||||||
|  | @ -22,18 +36,33 @@ bool code_heap::needs_fixup_p(code_block *compiled) | ||||||
| 	return needs_fixup.count(compiled) > 0; | 	return needs_fixup.count(compiled) > 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool code_heap::marked_p(heap_block *compiled) | ||||||
|  | { | ||||||
|  | 	return allocator->state.marked_p(compiled); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void code_heap::set_marked_p(code_block *compiled) | ||||||
|  | { | ||||||
|  | 	allocator->state.set_marked_p(compiled); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void code_heap::clear_mark_bits() | ||||||
|  | { | ||||||
|  | 	allocator->state.clear_mark_bits(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void code_heap::code_heap_free(code_block *compiled) | void code_heap::code_heap_free(code_block *compiled) | ||||||
| { | { | ||||||
| 	points_to_nursery.erase(compiled); | 	points_to_nursery.erase(compiled); | ||||||
| 	points_to_aging.erase(compiled); | 	points_to_aging.erase(compiled); | ||||||
| 	needs_fixup.erase(compiled); | 	needs_fixup.erase(compiled); | ||||||
| 	heap_free(compiled); | 	allocator->free(compiled); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Allocate a code heap during startup */ | /* Allocate a code heap during startup */ | ||||||
| void factor_vm::init_code_heap(cell size) | void factor_vm::init_code_heap(cell size) | ||||||
| { | { | ||||||
| 	code = new code_heap(secure_gc,size); | 	code = new code_heap(size); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool factor_vm::in_code_heap_p(cell ptr) | bool factor_vm::in_code_heap_p(cell ptr) | ||||||
|  | @ -89,7 +118,7 @@ struct word_and_literal_code_heap_updater { | ||||||
| void factor_vm::update_code_heap_words_and_literals() | void factor_vm::update_code_heap_words_and_literals() | ||||||
| { | { | ||||||
| 	word_and_literal_code_heap_updater updater(this); | 	word_and_literal_code_heap_updater updater(this); | ||||||
| 	code->sweep_heap(updater); | 	code->allocator->sweep(updater); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* After growing the heap, we have to perform a full relocation to update
 | /* After growing the heap, we have to perform a full relocation to update
 | ||||||
|  | @ -109,7 +138,7 @@ void factor_vm::relocate_code_heap() | ||||||
| { | { | ||||||
| 	code_heap_relocator relocator(this); | 	code_heap_relocator relocator(this); | ||||||
| 	code_heap_iterator<code_heap_relocator> iter(relocator); | 	code_heap_iterator<code_heap_relocator> iter(relocator); | ||||||
| 	code->sweep_heap(iter); | 	code->allocator->sweep(iter); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void factor_vm::primitive_modify_code_heap() | void factor_vm::primitive_modify_code_heap() | ||||||
|  | @ -169,7 +198,7 @@ void factor_vm::primitive_modify_code_heap() | ||||||
| void factor_vm::primitive_code_room() | void factor_vm::primitive_code_room() | ||||||
| { | { | ||||||
| 	cell used, total_free, max_free; | 	cell used, total_free, max_free; | ||||||
| 	code->heap_usage(&used,&total_free,&max_free); | 	code->allocator->usage(&used,&total_free,&max_free); | ||||||
| 	dpush(tag_fixnum(code->seg->size / 1024)); | 	dpush(tag_fixnum(code->seg->size / 1024)); | ||||||
| 	dpush(tag_fixnum(used / 1024)); | 	dpush(tag_fixnum(used / 1024)); | ||||||
| 	dpush(tag_fixnum(total_free / 1024)); | 	dpush(tag_fixnum(total_free / 1024)); | ||||||
|  | @ -178,7 +207,7 @@ void factor_vm::primitive_code_room() | ||||||
| 
 | 
 | ||||||
| code_block *code_heap::forward_code_block(code_block *compiled) | code_block *code_heap::forward_code_block(code_block *compiled) | ||||||
| { | { | ||||||
| 	return (code_block *)state->forward_block(compiled); | 	return (code_block *)allocator->state.forward_block(compiled); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct callframe_forwarder { | struct callframe_forwarder { | ||||||
|  | @ -277,7 +306,7 @@ function returns. */ | ||||||
| void factor_vm::compact_code_heap(bool trace_contexts_p) | void factor_vm::compact_code_heap(bool trace_contexts_p) | ||||||
| { | { | ||||||
| 	/* Figure out where blocks are going to go */ | 	/* Figure out where blocks are going to go */ | ||||||
| 	code->state->compute_forwarding(); | 	code->allocator->state.compute_forwarding(); | ||||||
| 
 | 
 | ||||||
| 	/* Update references to the code heap from the data heap */ | 	/* Update references to the code heap from the data heap */ | ||||||
| 	forward_object_xts(); | 	forward_object_xts(); | ||||||
|  | @ -291,7 +320,7 @@ void factor_vm::compact_code_heap(bool trace_contexts_p) | ||||||
| 	that the data heap is up to date since relocation looks up object XTs) */ | 	that the data heap is up to date since relocation looks up object XTs) */ | ||||||
| 	code_heap_relocator relocator(this); | 	code_heap_relocator relocator(this); | ||||||
| 	code_heap_iterator<code_heap_relocator> iter(relocator); | 	code_heap_iterator<code_heap_relocator> iter(relocator); | ||||||
| 	code->compact_heap(iter); | 	code->allocator->compact(iter); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct stack_trace_stripper { | struct stack_trace_stripper { | ||||||
|  |  | ||||||
|  | @ -1,7 +1,13 @@ | ||||||
| namespace factor | namespace factor | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| struct code_heap : heap<heap_block> { | struct code_heap { | ||||||
|  | 	/* The actual memory area */ | ||||||
|  | 	segment *seg; | ||||||
|  | 
 | ||||||
|  | 	/* Memory allocator */ | ||||||
|  | 	free_list_allocator<heap_block> *allocator; | ||||||
|  | 
 | ||||||
| 	/* Set of blocks which need full relocation. */ | 	/* Set of blocks which need full relocation. */ | ||||||
| 	std::set<code_block *> needs_fixup; | 	std::set<code_block *> needs_fixup; | ||||||
| 
 | 
 | ||||||
|  | @ -11,10 +17,14 @@ struct code_heap : heap<heap_block> { | ||||||
| 	/* Code blocks which may reference objects in aging space or the nursery */ | 	/* Code blocks which may reference objects in aging space or the nursery */ | ||||||
| 	std::set<code_block *> points_to_aging; | 	std::set<code_block *> points_to_aging; | ||||||
| 
 | 
 | ||||||
| 	explicit code_heap(bool secure_gc, cell size); | 	explicit code_heap(cell size); | ||||||
|  | 	~code_heap(); | ||||||
| 	void write_barrier(code_block *compiled); | 	void write_barrier(code_block *compiled); | ||||||
| 	void clear_remembered_set(); | 	void clear_remembered_set(); | ||||||
| 	bool needs_fixup_p(code_block *compiled); | 	bool needs_fixup_p(code_block *compiled); | ||||||
|  | 	bool marked_p(heap_block *compiled); | ||||||
|  | 	void set_marked_p(code_block *compiled); | ||||||
|  | 	void clear_mark_bits(); | ||||||
| 	void code_heap_free(code_block *compiled); | 	void code_heap_free(code_block *compiled); | ||||||
| 	code_block *forward_code_block(code_block *compiled); | 	code_block *forward_code_block(code_block *compiled); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -42,7 +42,7 @@ data_heap::data_heap(cell young_size_, cell aging_size_, cell tenured_size_) | ||||||
| 	aging = new aging_space(aging_size,tenured_semispace->end); | 	aging = new aging_space(aging_size,tenured_semispace->end); | ||||||
| 	aging_semispace = new aging_space(aging_size,aging->end); | 	aging_semispace = new aging_space(aging_size,aging->end); | ||||||
| 
 | 
 | ||||||
| 	nursery = new zone(young_size,aging_semispace->end); | 	nursery = new bump_allocator(young_size,aging_semispace->end); | ||||||
| 
 | 
 | ||||||
| 	assert(seg->end - nursery->end <= deck_size); | 	assert(seg->end - nursery->end <= deck_size); | ||||||
| } | } | ||||||
|  | @ -75,10 +75,9 @@ void factor_vm::set_data_heap(data_heap *data_) | ||||||
| 	data->reset_generation(data->tenured); | 	data->reset_generation(data->tenured); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void factor_vm::init_data_heap(cell young_size, cell aging_size, cell tenured_size, bool secure_gc_) | void factor_vm::init_data_heap(cell young_size, cell aging_size, cell tenured_size) | ||||||
| { | { | ||||||
| 	set_data_heap(new data_heap(young_size,aging_size,tenured_size)); | 	set_data_heap(new data_heap(young_size,aging_size,tenured_size)); | ||||||
| 	secure_gc = secure_gc_; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Size of the object pointed to by a tagged pointer */ | /* Size of the object pointed to by a tagged pointer */ | ||||||
|  |  | ||||||
|  | @ -10,7 +10,7 @@ struct data_heap { | ||||||
| 
 | 
 | ||||||
| 	segment *seg; | 	segment *seg; | ||||||
| 
 | 
 | ||||||
| 	zone *nursery; | 	bump_allocator *nursery; | ||||||
| 	aging_space *aging; | 	aging_space *aging; | ||||||
| 	aging_space *aging_semispace; | 	aging_space *aging_semispace; | ||||||
| 	tenured_space *tenured; | 	tenured_space *tenured; | ||||||
|  |  | ||||||
|  | @ -209,7 +209,7 @@ void factor_vm::dump_memory(cell from, cell to) | ||||||
| 		dump_cell(from); | 		dump_cell(from); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void factor_vm::dump_zone(const char *name, zone *z) | void factor_vm::dump_zone(const char *name, bump_allocator *z) | ||||||
| { | { | ||||||
| 	print_string(name); print_string(": "); | 	print_string(name); print_string(": "); | ||||||
| 	print_string("Start="); print_cell(z->start); | 	print_string("Start="); print_cell(z->start); | ||||||
|  | @ -296,7 +296,7 @@ struct code_block_printer { | ||||||
| 		const char *status; | 		const char *status; | ||||||
| 		if(scan->free_p()) | 		if(scan->free_p()) | ||||||
| 			status = "free"; | 			status = "free"; | ||||||
| 		else if(parent->code->state->is_marked_p(scan)) | 		else if(parent->code->marked_p(scan)) | ||||||
| 		{ | 		{ | ||||||
| 			reloc_size += parent->object_size(((code_block *)scan)->relocation); | 			reloc_size += parent->object_size(((code_block *)scan)->relocation); | ||||||
| 			literal_size += parent->object_size(((code_block *)scan)->literals); | 			literal_size += parent->object_size(((code_block *)scan)->literals); | ||||||
|  | @ -319,7 +319,7 @@ struct code_block_printer { | ||||||
| void factor_vm::dump_code_heap() | void factor_vm::dump_code_heap() | ||||||
| { | { | ||||||
| 	code_block_printer printer(this); | 	code_block_printer printer(this); | ||||||
| 	code->iterate_heap(printer); | 	code->allocator->iterate(printer); | ||||||
| 	print_cell(printer.reloc_size); print_string(" bytes of relocation data\n"); | 	print_cell(printer.reloc_size); print_string(" bytes of relocation data\n"); | ||||||
| 	print_cell(printer.literal_size); print_string(" bytes of literal data\n"); | 	print_cell(printer.literal_size); print_string(" bytes of literal data\n"); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -37,7 +37,6 @@ void factor_vm::default_parameters(vm_parameters *p) | ||||||
| 
 | 
 | ||||||
| 	p->max_pic_size = 3; | 	p->max_pic_size = 3; | ||||||
| 
 | 
 | ||||||
| 	p->secure_gc = false; |  | ||||||
| 	p->fep = false; | 	p->fep = false; | ||||||
| 	p->signals = true; | 	p->signals = true; | ||||||
| 
 | 
 | ||||||
|  | @ -85,7 +84,6 @@ void factor_vm::init_parameters_from_args(vm_parameters *p, int argc, vm_char ** | ||||||
| 		else if(factor_arg(arg,STRING_LITERAL("-codeheap=%d"),&p->code_size)); | 		else if(factor_arg(arg,STRING_LITERAL("-codeheap=%d"),&p->code_size)); | ||||||
| 		else if(factor_arg(arg,STRING_LITERAL("-pic=%d"),&p->max_pic_size)); | 		else if(factor_arg(arg,STRING_LITERAL("-pic=%d"),&p->max_pic_size)); | ||||||
| 		else if(factor_arg(arg,STRING_LITERAL("-callbacks=%d"),&p->callback_size)); | 		else if(factor_arg(arg,STRING_LITERAL("-callbacks=%d"),&p->callback_size)); | ||||||
| 		else if(STRCMP(arg,STRING_LITERAL("-securegc")) == 0) p->secure_gc = true; |  | ||||||
| 		else if(STRCMP(arg,STRING_LITERAL("-fep")) == 0) p->fep = true; | 		else if(STRCMP(arg,STRING_LITERAL("-fep")) == 0) p->fep = true; | ||||||
| 		else if(STRCMP(arg,STRING_LITERAL("-nosignals")) == 0) p->signals = false; | 		else if(STRCMP(arg,STRING_LITERAL("-nosignals")) == 0) p->signals = false; | ||||||
| 		else if(STRNCMP(arg,STRING_LITERAL("-i="),3) == 0) p->image_path = arg + 3; | 		else if(STRNCMP(arg,STRING_LITERAL("-i="),3) == 0) p->image_path = arg + 3; | ||||||
|  |  | ||||||
|  | @ -3,28 +3,28 @@ namespace factor | ||||||
| 
 | 
 | ||||||
| static const cell free_list_count = 32; | static const cell free_list_count = 32; | ||||||
| 
 | 
 | ||||||
| struct heap_free_list { | struct free_list { | ||||||
| 	free_heap_block *small_blocks[free_list_count]; | 	free_heap_block *small_blocks[free_list_count]; | ||||||
| 	free_heap_block *large_blocks; | 	free_heap_block *large_blocks; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<typename Block> struct heap { | template<typename Block> struct free_list_allocator { | ||||||
| 	bool secure_gc; | 	cell start; | ||||||
| 	segment *seg; | 	cell size; | ||||||
| 	heap_free_list free; | 	cell end; | ||||||
| 	mark_bits<Block> *state; | 	free_list free_blocks; | ||||||
|  | 	mark_bits<Block> state; | ||||||
| 
 | 
 | ||||||
| 	explicit heap(bool secure_gc_, cell size, bool executable_p); | 	explicit free_list_allocator(cell start, cell size); | ||||||
| 	~heap(); |  | ||||||
| 
 | 
 | ||||||
| 	inline Block *first_block() | 	inline Block *first_block() | ||||||
| 	{ | 	{ | ||||||
| 		return (Block *)seg->start; | 		return (Block *)start; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	inline Block *last_block() | 	inline Block *last_block() | ||||||
| 	{ | 	{ | ||||||
| 		return (Block *)seg->end; | 		return (Block *)end; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	Block *next_block_after(heap_block *block) | 	Block *next_block_after(heap_block *block) | ||||||
|  | @ -38,16 +38,15 @@ template<typename Block> struct heap { | ||||||
| 	void assert_free_block(free_heap_block *block); | 	void assert_free_block(free_heap_block *block); | ||||||
| 	free_heap_block *find_free_block(cell size); | 	free_heap_block *find_free_block(cell size); | ||||||
| 	free_heap_block *split_free_block(free_heap_block *block, cell size); | 	free_heap_block *split_free_block(free_heap_block *block, cell size); | ||||||
| 	Block *heap_allot(cell size); | 	Block *allot(cell size); | ||||||
| 	void heap_free(Block *block); | 	void free(Block *block); | ||||||
| 	void mark_block(Block *block); | 	void usage(cell *used, cell *total_free, cell *max_free); | ||||||
| 	void heap_usage(cell *used, cell *total_free, cell *max_free); | 	cell occupied(); | ||||||
| 	cell heap_size(); |  | ||||||
| 
 | 
 | ||||||
| 	template<typename Iterator> void sweep_heap(Iterator &iter); | 	template<typename Iterator> void sweep(Iterator &iter); | ||||||
| 	template<typename Iterator> void compact_heap(Iterator &iter); | 	template<typename Iterator> void compact(Iterator &iter); | ||||||
| 
 | 
 | ||||||
| 	template<typename Iterator> void iterate_heap(Iterator &iter) | 	template<typename Iterator> void iterate(Iterator &iter) | ||||||
| 	{ | 	{ | ||||||
| 		Block *scan = first_block(); | 		Block *scan = first_block(); | ||||||
| 		Block *end = last_block(); | 		Block *end = last_block(); | ||||||
|  | @ -62,73 +61,63 @@ template<typename Block> struct heap { | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<typename Block> void heap<Block>::clear_free_list() | template<typename Block> void free_list_allocator<Block>::clear_free_list() | ||||||
| { | { | ||||||
| 	memset(&free,0,sizeof(heap_free_list)); | 	memset(&free_blocks,0,sizeof(free_list)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<typename Block> heap<Block>::heap(bool secure_gc_, cell size, bool executable_p) : secure_gc(secure_gc_) | template<typename Block> | ||||||
|  | free_list_allocator<Block>::free_list_allocator(cell start_, cell size_) : | ||||||
|  | 	start(start_), size(size_), end(start_ + size_), state(mark_bits<Block>(start_,size_)) | ||||||
| { | { | ||||||
| 	if(size > (1L << (sizeof(cell) * 8 - 6))) fatal_error("Heap too large",size); |  | ||||||
| 	seg = new segment(align_page(size),executable_p); |  | ||||||
| 	if(!seg) fatal_error("Out of memory in heap allocator",size); |  | ||||||
| 	state = new mark_bits<Block>(seg->start,size); |  | ||||||
| 	clear_free_list(); | 	clear_free_list(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<typename Block> heap<Block>::~heap() | template<typename Block> void free_list_allocator<Block>::add_to_free_list(free_heap_block *block) | ||||||
| { |  | ||||||
| 	delete seg; |  | ||||||
| 	seg = NULL; |  | ||||||
| 	delete state; |  | ||||||
| 	state = NULL; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| template<typename Block> void heap<Block>::add_to_free_list(free_heap_block *block) |  | ||||||
| { | { | ||||||
| 	if(block->size() < free_list_count * block_granularity) | 	if(block->size() < free_list_count * block_granularity) | ||||||
| 	{ | 	{ | ||||||
| 		int index = block->size() / block_granularity; | 		int index = block->size() / block_granularity; | ||||||
| 		block->next_free = free.small_blocks[index]; | 		block->next_free = free_blocks.small_blocks[index]; | ||||||
| 		free.small_blocks[index] = block; | 		free_blocks.small_blocks[index] = block; | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		block->next_free = free.large_blocks; | 		block->next_free = free_blocks.large_blocks; | ||||||
| 		free.large_blocks = block; | 		free_blocks.large_blocks = block; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Called after reading the code heap from the image file, and after code heap
 | /* Called after reading the heap from the image file, and after heap compaction.
 | ||||||
| compaction. Makes a free list consisting of one free block, at the very end. */ | Makes a free list consisting of one free block, at the very end. */ | ||||||
| template<typename Block> void heap<Block>::build_free_list(cell size) | template<typename Block> void free_list_allocator<Block>::build_free_list(cell size) | ||||||
| { | { | ||||||
| 	clear_free_list(); | 	clear_free_list(); | ||||||
| 	free_heap_block *end = (free_heap_block *)(seg->start + size); | 	free_heap_block *last_block = (free_heap_block *)(start + size); | ||||||
| 	end->set_free(); | 	last_block->set_free(); | ||||||
| 	end->set_size(seg->end - (cell)end); | 	last_block->set_size(end - (cell)last_block); | ||||||
| 	add_to_free_list(end); | 	add_to_free_list(last_block); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<typename Block> void heap<Block>::assert_free_block(free_heap_block *block) | template<typename Block> void free_list_allocator<Block>::assert_free_block(free_heap_block *block) | ||||||
| { | { | ||||||
| #ifdef FACTOR_DEBUG | #ifdef FACTOR_DEBUG | ||||||
| 	assert(block->free_p()); | 	assert(block->free_p()); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<typename Block> free_heap_block *heap<Block>::find_free_block(cell size) | template<typename Block> free_heap_block *free_list_allocator<Block>::find_free_block(cell size) | ||||||
| { | { | ||||||
| 	cell attempt = size; | 	cell attempt = size; | ||||||
| 
 | 
 | ||||||
| 	while(attempt < free_list_count * block_granularity) | 	while(attempt < free_list_count * block_granularity) | ||||||
| 	{ | 	{ | ||||||
| 		int index = attempt / block_granularity; | 		int index = attempt / block_granularity; | ||||||
| 		free_heap_block *block = free.small_blocks[index]; | 		free_heap_block *block = free_blocks.small_blocks[index]; | ||||||
| 		if(block) | 		if(block) | ||||||
| 		{ | 		{ | ||||||
| 			assert_free_block(block); | 			assert_free_block(block); | ||||||
| 			free.small_blocks[index] = block->next_free; | 			free_blocks.small_blocks[index] = block->next_free; | ||||||
| 			return block; | 			return block; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -136,7 +125,7 @@ template<typename Block> free_heap_block *heap<Block>::find_free_block(cell size | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	free_heap_block *prev = NULL; | 	free_heap_block *prev = NULL; | ||||||
| 	free_heap_block *block = free.large_blocks; | 	free_heap_block *block = free_blocks.large_blocks; | ||||||
| 
 | 
 | ||||||
| 	while(block) | 	while(block) | ||||||
| 	{ | 	{ | ||||||
|  | @ -146,7 +135,7 @@ template<typename Block> free_heap_block *heap<Block>::find_free_block(cell size | ||||||
| 			if(prev) | 			if(prev) | ||||||
| 				prev->next_free = block->next_free; | 				prev->next_free = block->next_free; | ||||||
| 			else | 			else | ||||||
| 				free.large_blocks = block->next_free; | 				free_blocks.large_blocks = block->next_free; | ||||||
| 			return block; | 			return block; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -157,7 +146,7 @@ template<typename Block> free_heap_block *heap<Block>::find_free_block(cell size | ||||||
| 	return NULL; | 	return NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<typename Block> free_heap_block *heap<Block>::split_free_block(free_heap_block *block, cell size) | template<typename Block> free_heap_block *free_list_allocator<Block>::split_free_block(free_heap_block *block, cell size) | ||||||
| { | { | ||||||
| 	if(block->size() != size) | 	if(block->size() != size) | ||||||
| 	{ | 	{ | ||||||
|  | @ -173,7 +162,7 @@ template<typename Block> free_heap_block *heap<Block>::split_free_block(free_hea | ||||||
| 	return block; | 	return block; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<typename Block> Block *heap<Block>::heap_allot(cell size) | template<typename Block> Block *free_list_allocator<Block>::allot(cell size) | ||||||
| { | { | ||||||
| 	size = align(size,block_granularity); | 	size = align(size,block_granularity); | ||||||
| 
 | 
 | ||||||
|  | @ -187,20 +176,15 @@ template<typename Block> Block *heap<Block>::heap_allot(cell size) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<typename Block> void heap<Block>::heap_free(Block *block) | template<typename Block> void free_list_allocator<Block>::free(Block *block) | ||||||
| { | { | ||||||
| 	free_heap_block *free_block = (free_heap_block *)block; | 	free_heap_block *free_block = (free_heap_block *)block; | ||||||
| 	free_block->set_free(); | 	free_block->set_free(); | ||||||
| 	add_to_free_list(free_block); | 	add_to_free_list(free_block); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<typename Block> void heap<Block>::mark_block(Block *block) |  | ||||||
| { |  | ||||||
| 	state->set_marked_p(block); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* Compute total sum of sizes of free blocks, and size of largest free block */ | /* Compute total sum of sizes of free blocks, and size of largest free block */ | ||||||
| template<typename Block> void heap<Block>::heap_usage(cell *used, cell *total_free, cell *max_free) | template<typename Block> void free_list_allocator<Block>::usage(cell *used, cell *total_free, cell *max_free) | ||||||
| { | { | ||||||
| 	*used = 0; | 	*used = 0; | ||||||
| 	*total_free = 0; | 	*total_free = 0; | ||||||
|  | @ -227,34 +211,34 @@ template<typename Block> void heap<Block>::heap_usage(cell *used, cell *total_fr | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* The size of the heap after compaction */ | /* The size of the heap after compaction */ | ||||||
| template<typename Block> cell heap<Block>::heap_size() | template<typename Block> cell free_list_allocator<Block>::occupied() | ||||||
| { | { | ||||||
| 	Block *scan = first_block(); | 	Block *scan = first_block(); | ||||||
| 	Block *end = last_block(); | 	Block *last = last_block(); | ||||||
| 
 | 
 | ||||||
| 	while(scan != end) | 	while(scan != last) | ||||||
| 	{ | 	{ | ||||||
| 		if(scan->free_p()) break; | 		if(scan->free_p()) break; | ||||||
| 		else scan = next_block_after(scan); | 		else scan = next_block_after(scan); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if(scan != end) | 	if(scan != last) | ||||||
| 	{ | 	{ | ||||||
| 		free_heap_block *free_block = (free_heap_block *)scan; | 		free_heap_block *free_block = (free_heap_block *)scan; | ||||||
| 		assert(free_block->free_p()); | 		assert(free_block->free_p()); | ||||||
| 		assert((cell)scan + free_block->size() == seg->end); | 		assert((cell)scan + free_block->size() == end); | ||||||
| 
 | 
 | ||||||
| 		return (cell)scan - (cell)first_block(); | 		return (cell)scan - (cell)first_block(); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 		return seg->size; | 		return size; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* After code GC, all live code blocks are marked, so any
 | /* After code GC, all live code blocks are marked, so any
 | ||||||
| which are not marked can be reclaimed. */ | which are not marked can be reclaimed. */ | ||||||
| template<typename Block> | template<typename Block> | ||||||
| template<typename Iterator> | template<typename Iterator> | ||||||
| void heap<Block>::sweep_heap(Iterator &iter) | void free_list_allocator<Block>::sweep(Iterator &iter) | ||||||
| { | { | ||||||
| 	this->clear_free_list(); | 	this->clear_free_list(); | ||||||
| 
 | 
 | ||||||
|  | @ -276,7 +260,7 @@ void heap<Block>::sweep_heap(Iterator &iter) | ||||||
| 			else | 			else | ||||||
| 				prev = scan; | 				prev = scan; | ||||||
| 		} | 		} | ||||||
| 		else if(this->state->is_marked_p(scan)) | 		else if(this->state.marked_p(scan)) | ||||||
| 		{ | 		{ | ||||||
| 			if(prev && prev->free_p()) | 			if(prev && prev->free_p()) | ||||||
| 				this->add_to_free_list((free_heap_block *)prev); | 				this->add_to_free_list((free_heap_block *)prev); | ||||||
|  | @ -305,17 +289,17 @@ void heap<Block>::sweep_heap(Iterator &iter) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* The forwarding map must be computed first by calling
 | /* The forwarding map must be computed first by calling
 | ||||||
| state->compute_forwarding(). */ | state.compute_forwarding(). */ | ||||||
| template<typename Block> | template<typename Block> | ||||||
| template<typename Iterator> | template<typename Iterator> | ||||||
| void heap<Block>::compact_heap(Iterator &iter) | void free_list_allocator<Block>::compact(Iterator &iter) | ||||||
| { | { | ||||||
| 	heap_compactor<Block,Iterator> compactor(state,first_block(),iter); | 	heap_compactor<Block,Iterator> compactor(&state,first_block(),iter); | ||||||
| 	this->iterate_heap(compactor); | 	this->iterate(compactor); | ||||||
| 
 | 
 | ||||||
| 	/* Now update the free list; there will be a single free block at
 | 	/* Now update the free list; there will be a single free block at
 | ||||||
| 	the end */ | 	the end */ | ||||||
| 	this->build_free_list((cell)compactor.address - this->seg->start); | 	this->build_free_list((cell)compactor.address - this->start); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | @ -89,7 +89,7 @@ void full_collector::trace_literal_references(code_block *compiled) | ||||||
| collections */ | collections */ | ||||||
| void full_collector::mark_code_block(code_block *compiled) | void full_collector::mark_code_block(code_block *compiled) | ||||||
| { | { | ||||||
| 	this->code->mark_block(compiled); | 	this->code->set_marked_p(compiled); | ||||||
| 	trace_literal_references(compiled); | 	trace_literal_references(compiled); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -108,7 +108,7 @@ void factor_vm::collect_full_impl(bool trace_contexts_p) | ||||||
| { | { | ||||||
| 	full_collector collector(this); | 	full_collector collector(this); | ||||||
| 
 | 
 | ||||||
| 	code->state->clear_mark_bits(); | 	code->clear_mark_bits(); | ||||||
| 
 | 
 | ||||||
| 	collector.trace_roots(); | 	collector.trace_roots(); | ||||||
|         if(trace_contexts_p) |         if(trace_contexts_p) | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ namespace factor | ||||||
| 
 | 
 | ||||||
| struct full_policy { | struct full_policy { | ||||||
| 	factor_vm *parent; | 	factor_vm *parent; | ||||||
| 	zone *tenured; | 	tenured_space *tenured; | ||||||
| 
 | 
 | ||||||
| 	full_policy(factor_vm *parent_) : parent(parent_), tenured(parent->data->tenured) {} | 	full_policy(factor_vm *parent_) : parent(parent_), tenured(parent->data->tenured) {} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										11
									
								
								vm/image.cpp
								
								
								
								
							
							
						
						
									
										11
									
								
								vm/image.cpp
								
								
								
								
							|  | @ -23,8 +23,7 @@ void factor_vm::load_data_heap(FILE *file, image_header *h, vm_parameters *p) | ||||||
| 
 | 
 | ||||||
| 	init_data_heap(p->young_size, | 	init_data_heap(p->young_size, | ||||||
| 		p->aging_size, | 		p->aging_size, | ||||||
| 		p->tenured_size, | 		p->tenured_size); | ||||||
| 		p->secure_gc); |  | ||||||
| 
 | 
 | ||||||
| 	clear_gc_stats(); | 	clear_gc_stats(); | ||||||
| 
 | 
 | ||||||
|  | @ -52,7 +51,7 @@ void factor_vm::load_code_heap(FILE *file, image_header *h, vm_parameters *p) | ||||||
| 
 | 
 | ||||||
| 	if(h->code_size != 0) | 	if(h->code_size != 0) | ||||||
| 	{ | 	{ | ||||||
| 		size_t bytes_read = fread(code->first_block(),1,h->code_size,file); | 		size_t bytes_read = fread(code->allocator->first_block(),1,h->code_size,file); | ||||||
| 		if(bytes_read != h->code_size) | 		if(bytes_read != h->code_size) | ||||||
| 		{ | 		{ | ||||||
| 			print_string("truncated image: "); | 			print_string("truncated image: "); | ||||||
|  | @ -64,7 +63,7 @@ void factor_vm::load_code_heap(FILE *file, image_header *h, vm_parameters *p) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	code->build_free_list(h->code_size); | 	code->allocator->build_free_list(h->code_size); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void factor_vm::data_fixup(cell *handle, cell data_relocation_base) | void factor_vm::data_fixup(cell *handle, cell data_relocation_base) | ||||||
|  | @ -292,7 +291,7 @@ bool factor_vm::save_image(const vm_char *filename) | ||||||
| 	h.data_relocation_base = data->tenured->start; | 	h.data_relocation_base = data->tenured->start; | ||||||
| 	h.data_size = data->tenured->here - data->tenured->start; | 	h.data_size = data->tenured->here - data->tenured->start; | ||||||
| 	h.code_relocation_base = code->seg->start; | 	h.code_relocation_base = code->seg->start; | ||||||
| 	h.code_size = code->heap_size(); | 	h.code_size = code->allocator->occupied(); | ||||||
| 
 | 
 | ||||||
| 	h.true_object = true_object; | 	h.true_object = true_object; | ||||||
| 	h.bignum_zero = bignum_zero; | 	h.bignum_zero = bignum_zero; | ||||||
|  | @ -306,7 +305,7 @@ bool factor_vm::save_image(const vm_char *filename) | ||||||
| 
 | 
 | ||||||
| 	if(fwrite(&h,sizeof(image_header),1,file) != 1) ok = false; | 	if(fwrite(&h,sizeof(image_header),1,file) != 1) ok = false; | ||||||
| 	if(fwrite((void*)data->tenured->start,h.data_size,1,file) != 1) ok = false; | 	if(fwrite((void*)data->tenured->start,h.data_size,1,file) != 1) ok = false; | ||||||
| 	if(fwrite(code->first_block(),h.code_size,1,file) != 1) ok = false; | 	if(fwrite(code->allocator->first_block(),h.code_size,1,file) != 1) ok = false; | ||||||
| 	if(fclose(file)) ok = false; | 	if(fclose(file)) ok = false; | ||||||
| 
 | 
 | ||||||
| 	if(!ok) | 	if(!ok) | ||||||
|  |  | ||||||
|  | @ -34,7 +34,6 @@ struct vm_parameters { | ||||||
| 	cell ds_size, rs_size; | 	cell ds_size, rs_size; | ||||||
| 	cell young_size, aging_size, tenured_size; | 	cell young_size, aging_size, tenured_size; | ||||||
| 	cell code_size; | 	cell code_size; | ||||||
| 	bool secure_gc; |  | ||||||
| 	bool fep; | 	bool fep; | ||||||
| 	bool console; | 	bool console; | ||||||
| 	bool signals; | 	bool signals; | ||||||
|  |  | ||||||
|  | @ -95,7 +95,7 @@ template<typename Block> struct mark_bits { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	bool is_marked_p(Block *address) | 	bool marked_p(Block *address) | ||||||
| 	{ | 	{ | ||||||
| 		return bitmap_elt(marked,address); | 		return bitmap_elt(marked,address); | ||||||
| 	} | 	} | ||||||
|  | @ -155,7 +155,7 @@ template<typename Block, typename Iterator> struct heap_compactor { | ||||||
| 
 | 
 | ||||||
| 	void operator()(Block *block, cell size) | 	void operator()(Block *block, cell size) | ||||||
| 	{ | 	{ | ||||||
| 		if(this->state->is_marked_p(block)) | 		if(this->state->marked_p(block)) | ||||||
| 		{ | 		{ | ||||||
| 			memmove(address,block,size); | 			memmove(address,block,size); | ||||||
| 			iter((Block *)address,size); | 			iter((Block *)address,size); | ||||||
|  |  | ||||||
|  | @ -48,9 +48,11 @@ namespace factor | ||||||
| #include "bignumint.hpp" | #include "bignumint.hpp" | ||||||
| #include "bignum.hpp" | #include "bignum.hpp" | ||||||
| #include "code_block.hpp" | #include "code_block.hpp" | ||||||
| #include "zone.hpp" | #include "bump_allocator.hpp" | ||||||
|  | #include "mark_bits.hpp" | ||||||
|  | #include "free_list_allocator.hpp" | ||||||
| #include "write_barrier.hpp" | #include "write_barrier.hpp" | ||||||
| #include "old_space.hpp" | #include "object_start_map.hpp" | ||||||
| #include "aging_space.hpp" | #include "aging_space.hpp" | ||||||
| #include "tenured_space.hpp" | #include "tenured_space.hpp" | ||||||
| #include "data_heap.hpp" | #include "data_heap.hpp" | ||||||
|  | @ -61,8 +63,6 @@ namespace factor | ||||||
| #include "words.hpp" | #include "words.hpp" | ||||||
| #include "float_bits.hpp" | #include "float_bits.hpp" | ||||||
| #include "io.hpp" | #include "io.hpp" | ||||||
| #include "mark_bits.hpp" |  | ||||||
| #include "heap.hpp" |  | ||||||
| #include "image.hpp" | #include "image.hpp" | ||||||
| #include "alien.hpp" | #include "alien.hpp" | ||||||
| #include "code_heap.hpp" | #include "code_heap.hpp" | ||||||
|  |  | ||||||
|  | @ -1,17 +1,17 @@ | ||||||
| namespace factor | namespace factor | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| struct tenured_space : zone { | struct tenured_space : bump_allocator { | ||||||
| 	object_start_map starts; | 	object_start_map starts; | ||||||
| 
 | 
 | ||||||
| 	tenured_space(cell size, cell start) : | 	tenured_space(cell size, cell start) : | ||||||
| 		zone(size,start), starts(size,start) {} | 		bump_allocator(size,start), starts(size,start) {} | ||||||
| 
 | 
 | ||||||
| 	object *allot(cell size) | 	object *allot(cell size) | ||||||
| 	{ | 	{ | ||||||
| 		if(here + size > end) return NULL; | 		if(here + size > end) return NULL; | ||||||
| 
 | 
 | ||||||
| 		object *obj = zone::allot(size); | 		object *obj = bump_allocator::allot(size); | ||||||
| 		starts.record_object_start_offset(obj); | 		starts.record_object_start_offset(obj); | ||||||
| 		return obj; | 		return obj; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ namespace factor | ||||||
| 
 | 
 | ||||||
| struct to_tenured_policy { | struct to_tenured_policy { | ||||||
| 	factor_vm *myvm; | 	factor_vm *myvm; | ||||||
| 	zone *tenured; | 	tenured_space *tenured; | ||||||
| 
 | 
 | ||||||
| 	to_tenured_policy(factor_vm *myvm_) : myvm(myvm_), tenured(myvm->data->tenured) {} | 	to_tenured_policy(factor_vm *myvm_) : myvm(myvm_), tenured(myvm->data->tenured) {} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -6,7 +6,6 @@ namespace factor | ||||||
| factor_vm::factor_vm() : | factor_vm::factor_vm() : | ||||||
| 	nursery(0,0), | 	nursery(0,0), | ||||||
| 	profiling_p(false), | 	profiling_p(false), | ||||||
| 	secure_gc(false), |  | ||||||
| 	gc_off(false), | 	gc_off(false), | ||||||
| 	current_gc(NULL), | 	current_gc(NULL), | ||||||
| 	fep_disabled(false), | 	fep_disabled(false), | ||||||
|  |  | ||||||
							
								
								
									
										11
									
								
								vm/vm.hpp
								
								
								
								
							
							
						
						
									
										11
									
								
								vm/vm.hpp
								
								
								
								
							|  | @ -11,7 +11,7 @@ struct factor_vm | ||||||
| 	context *ctx; | 	context *ctx; | ||||||
| 	 | 	 | ||||||
| 	/* New objects are allocated here */ | 	/* New objects are allocated here */ | ||||||
| 	zone nursery; | 	bump_allocator nursery; | ||||||
| 
 | 
 | ||||||
| 	/* Add this to a shifted address to compute write barrier offsets */ | 	/* Add this to a shifted address to compute write barrier offsets */ | ||||||
| 	cell cards_offset; | 	cell cards_offset; | ||||||
|  | @ -39,9 +39,6 @@ struct factor_vm | ||||||
| 	unsigned int signal_fpu_status; | 	unsigned int signal_fpu_status; | ||||||
| 	stack_frame *signal_callstack_top; | 	stack_frame *signal_callstack_top; | ||||||
| 
 | 
 | ||||||
| 	/* Zeroes out deallocated memory; set by the -securegc command line argument */ |  | ||||||
| 	bool secure_gc; |  | ||||||
| 
 |  | ||||||
| 	/* A heap walk allows useful things to be done, like finding all
 | 	/* A heap walk allows useful things to be done, like finding all
 | ||||||
| 	   references to an object for debugging purposes. */ | 	   references to an object for debugging purposes. */ | ||||||
| 	cell heap_scan_ptr; | 	cell heap_scan_ptr; | ||||||
|  | @ -221,7 +218,7 @@ struct factor_vm | ||||||
| 	//data heap
 | 	//data heap
 | ||||||
| 	void init_card_decks(); | 	void init_card_decks(); | ||||||
| 	void set_data_heap(data_heap *data_); | 	void set_data_heap(data_heap *data_); | ||||||
| 	void init_data_heap(cell young_size, cell aging_size, cell tenured_size, bool secure_gc_); | 	void init_data_heap(cell young_size, cell aging_size, cell tenured_size); | ||||||
| 	void primitive_size(); | 	void primitive_size(); | ||||||
| 	cell binary_payload_start(object *pointer); | 	cell binary_payload_start(object *pointer); | ||||||
| 	void primitive_data_room(); | 	void primitive_data_room(); | ||||||
|  | @ -311,7 +308,7 @@ struct factor_vm | ||||||
| 	void print_callstack(); | 	void print_callstack(); | ||||||
| 	void dump_cell(cell x); | 	void dump_cell(cell x); | ||||||
| 	void dump_memory(cell from, cell to); | 	void dump_memory(cell from, cell to); | ||||||
| 	void dump_zone(const char *name, zone *z); | 	void dump_zone(const char *name, bump_allocator *z); | ||||||
| 	void dump_generations(); | 	void dump_generations(); | ||||||
| 	void dump_objects(cell type); | 	void dump_objects(cell type); | ||||||
| 	void find_data_references_step(cell *scan); | 	void find_data_references_step(cell *scan); | ||||||
|  | @ -531,7 +528,7 @@ struct factor_vm | ||||||
| 	template<typename Iterator> void iterate_code_heap(Iterator &iter_) | 	template<typename Iterator> void iterate_code_heap(Iterator &iter_) | ||||||
| 	{ | 	{ | ||||||
| 		code_heap_iterator<Iterator> iter(iter_); | 		code_heap_iterator<Iterator> iter(iter_); | ||||||
| 		code->iterate_heap(iter); | 		code->allocator->iterate(iter); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	//callbacks
 | 	//callbacks
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue