vm: new GC policy: mark sweep after N megabytes promoted, mark compact if tenured space cannot fit nursery+aging in one contiguous block. N = 32 on 32-bit and 64 on 64-bit
							parent
							
								
									a1aac42786
								
							
						
					
					
						commit
						5536003cf8
					
				| 
						 | 
				
			
			@ -203,8 +203,8 @@ code_heap_room factor_vm::code_room()
 | 
			
		|||
	room.size             = code->allocator->size;
 | 
			
		||||
	room.occupied_space   = code->allocator->occupied_space();
 | 
			
		||||
	room.total_free       = code->allocator->free_space();
 | 
			
		||||
	room.contiguous_free  = code->allocator->free_blocks.largest_free_block();
 | 
			
		||||
	room.free_block_count = code->allocator->free_blocks.free_block_count;
 | 
			
		||||
	room.contiguous_free  = code->allocator->largest_free_block();
 | 
			
		||||
	room.free_block_count = code->allocator->free_block_count();
 | 
			
		||||
 | 
			
		||||
	return room;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,7 +9,10 @@ void factor_vm::init_card_decks()
 | 
			
		|||
	decks_offset = (cell)data->decks - addr_to_deck(data->start);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
data_heap::data_heap(cell young_size_, cell aging_size_, cell tenured_size_)
 | 
			
		||||
data_heap::data_heap(cell young_size_,
 | 
			
		||||
	cell aging_size_,
 | 
			
		||||
	cell tenured_size_,
 | 
			
		||||
	cell promotion_threshold_)
 | 
			
		||||
{
 | 
			
		||||
	young_size_ = align(young_size_,deck_size);
 | 
			
		||||
	aging_size_ = align(aging_size_,deck_size);
 | 
			
		||||
| 
						 | 
				
			
			@ -18,15 +21,12 @@ data_heap::data_heap(cell young_size_, cell aging_size_, cell tenured_size_)
 | 
			
		|||
	young_size = young_size_;
 | 
			
		||||
	aging_size = aging_size_;
 | 
			
		||||
	tenured_size = tenured_size_;
 | 
			
		||||
	promotion_threshold = promotion_threshold_;
 | 
			
		||||
 | 
			
		||||
	cell total_size = young_size + 2 * aging_size + tenured_size;
 | 
			
		||||
 | 
			
		||||
	total_size += deck_size;
 | 
			
		||||
 | 
			
		||||
	cell total_size = young_size + 2 * aging_size + tenured_size + deck_size;
 | 
			
		||||
	seg = new segment(total_size,false);
 | 
			
		||||
 | 
			
		||||
	cell cards_size = addr_to_card(total_size);
 | 
			
		||||
 | 
			
		||||
	cards = new card[cards_size];
 | 
			
		||||
	cards_end = cards + cards_size;
 | 
			
		||||
	memset(cards,0,cards_size);
 | 
			
		||||
| 
						 | 
				
			
			@ -62,7 +62,10 @@ data_heap::~data_heap()
 | 
			
		|||
data_heap *data_heap::grow(cell requested_bytes)
 | 
			
		||||
{
 | 
			
		||||
	cell new_tenured_size = (tenured_size * 2) + requested_bytes;
 | 
			
		||||
	return new data_heap(young_size,aging_size,new_tenured_size);
 | 
			
		||||
	return new data_heap(young_size,
 | 
			
		||||
		aging_size,
 | 
			
		||||
		new_tenured_size,
 | 
			
		||||
		promotion_threshold * 1.25);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Generation> void data_heap::clear_cards(Generation *gen)
 | 
			
		||||
| 
						 | 
				
			
			@ -105,9 +108,9 @@ void factor_vm::set_data_heap(data_heap *data_)
 | 
			
		|||
	init_card_decks();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void factor_vm::init_data_heap(cell young_size, cell aging_size, cell tenured_size)
 | 
			
		||||
void factor_vm::init_data_heap(cell young_size, cell aging_size, cell tenured_size, cell promotion_threshold)
 | 
			
		||||
{
 | 
			
		||||
	set_data_heap(new data_heap(young_size,aging_size,tenured_size));
 | 
			
		||||
	set_data_heap(new data_heap(young_size,aging_size,tenured_size,promotion_threshold));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Size of the object pointed to by a tagged pointer */
 | 
			
		||||
| 
						 | 
				
			
			@ -214,8 +217,8 @@ data_heap_room factor_vm::data_room()
 | 
			
		|||
	room.tenured_size             = data->tenured->size;
 | 
			
		||||
	room.tenured_occupied         = data->tenured->occupied_space();
 | 
			
		||||
	room.tenured_total_free       = data->tenured->free_space();
 | 
			
		||||
	room.tenured_contiguous_free  = data->tenured->free_blocks.largest_free_block();
 | 
			
		||||
	room.tenured_free_block_count = data->tenured->free_blocks.free_block_count;
 | 
			
		||||
	room.tenured_contiguous_free  = data->tenured->largest_free_block();
 | 
			
		||||
	room.tenured_free_block_count = data->tenured->free_block_count();
 | 
			
		||||
	room.cards                    = data->cards_end - data->cards;
 | 
			
		||||
	room.decks                    = data->decks_end - data->decks;
 | 
			
		||||
	room.mark_stack               = data->tenured->mark_stack.capacity();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,8 @@ struct data_heap {
 | 
			
		|||
	cell aging_size;
 | 
			
		||||
	cell tenured_size;
 | 
			
		||||
 | 
			
		||||
	cell promotion_threshold;
 | 
			
		||||
 | 
			
		||||
	segment *seg;
 | 
			
		||||
 | 
			
		||||
	nursery_space *nursery;
 | 
			
		||||
| 
						 | 
				
			
			@ -21,7 +23,7 @@ struct data_heap {
 | 
			
		|||
	card_deck *decks;
 | 
			
		||||
	card_deck *decks_end;
 | 
			
		||||
	
 | 
			
		||||
	explicit data_heap(cell young_size, cell aging_size, cell tenured_size);
 | 
			
		||||
	explicit data_heap(cell young_size, cell aging_size, cell tenured_size, cell promotion_threshold);
 | 
			
		||||
	~data_heap();
 | 
			
		||||
	data_heap *grow(cell requested_size);
 | 
			
		||||
	template<typename Generation> void clear_cards(Generation *gen);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,25 +15,14 @@ void factor_vm::default_parameters(vm_parameters *p)
 | 
			
		|||
{
 | 
			
		||||
	p->image_path = NULL;
 | 
			
		||||
 | 
			
		||||
	/* We make a wild guess here that if we're running on ARM, we don't
 | 
			
		||||
	have a lot of memory. */
 | 
			
		||||
#ifdef FACTOR_ARM
 | 
			
		||||
	p->ds_size = 8 * sizeof(cell);
 | 
			
		||||
	p->rs_size = 8 * sizeof(cell);
 | 
			
		||||
 | 
			
		||||
	p->code_size = 4;
 | 
			
		||||
	p->young_size = 1;
 | 
			
		||||
	p->aging_size = 1;
 | 
			
		||||
	p->tenured_size = 6;
 | 
			
		||||
#else
 | 
			
		||||
	p->ds_size = 32 * sizeof(cell);
 | 
			
		||||
	p->rs_size = 32 * sizeof(cell);
 | 
			
		||||
 | 
			
		||||
	p->code_size = 8 * sizeof(cell);
 | 
			
		||||
	p->young_size = sizeof(cell) / 4;
 | 
			
		||||
	p->aging_size = sizeof(cell) / 2;
 | 
			
		||||
	p->tenured_size = 16 * sizeof(cell);
 | 
			
		||||
#endif
 | 
			
		||||
	p->tenured_size = 24 * sizeof(cell);
 | 
			
		||||
	p->promotion_threshold = 8 * sizeof(cell);
 | 
			
		||||
 | 
			
		||||
	p->max_pic_size = 3;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -81,6 +70,7 @@ void factor_vm::init_parameters_from_args(vm_parameters *p, int argc, vm_char **
 | 
			
		|||
		else if(factor_arg(arg,STRING_LITERAL("-young=%d"),&p->young_size));
 | 
			
		||||
		else if(factor_arg(arg,STRING_LITERAL("-aging=%d"),&p->aging_size));
 | 
			
		||||
		else if(factor_arg(arg,STRING_LITERAL("-tenured=%d"),&p->tenured_size));
 | 
			
		||||
		else if(factor_arg(arg,STRING_LITERAL("-promote=%d"),&p->promotion_threshold));
 | 
			
		||||
		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("-callbacks=%d"),&p->callback_size));
 | 
			
		||||
| 
						 | 
				
			
			@ -114,6 +104,7 @@ void factor_vm::init_factor(vm_parameters *p)
 | 
			
		|||
	p->young_size <<= 20;
 | 
			
		||||
	p->aging_size <<= 20;
 | 
			
		||||
	p->tenured_size <<= 20;
 | 
			
		||||
	p->promotion_threshold <<= 20;
 | 
			
		||||
	p->code_size <<= 20;
 | 
			
		||||
 | 
			
		||||
	/* Disable GC during init as a sanity check */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,6 +46,10 @@ free_heap_block *free_list::find_free_block(cell size)
 | 
			
		|||
		{
 | 
			
		||||
			free_heap_block *block = blocks.back();
 | 
			
		||||
			blocks.pop_back();
 | 
			
		||||
 | 
			
		||||
			free_block_count--;
 | 
			
		||||
			free_space -= block->size();
 | 
			
		||||
 | 
			
		||||
			return block;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ template<typename Block> struct free_list_allocator {
 | 
			
		|||
	cell size;
 | 
			
		||||
	cell start;
 | 
			
		||||
	cell end;
 | 
			
		||||
	cell high_water_mark;
 | 
			
		||||
	free_list free_blocks;
 | 
			
		||||
	mark_bits<Block> state;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -20,6 +21,8 @@ template<typename Block> struct free_list_allocator {
 | 
			
		|||
	void free(Block *block);
 | 
			
		||||
	cell occupied_space();
 | 
			
		||||
	cell free_space();
 | 
			
		||||
	cell largest_free_block();
 | 
			
		||||
	cell free_block_count();
 | 
			
		||||
	void sweep();
 | 
			
		||||
	template<typename Iterator> void sweep(Iterator &iter);
 | 
			
		||||
	template<typename Iterator, typename Sizer> void compact(Iterator &iter, Sizer &sizer);
 | 
			
		||||
| 
						 | 
				
			
			@ -29,7 +32,10 @@ template<typename Block> struct free_list_allocator {
 | 
			
		|||
 | 
			
		||||
template<typename Block>
 | 
			
		||||
free_list_allocator<Block>::free_list_allocator(cell size_, cell start_) :
 | 
			
		||||
	size(size_), start(start_), end(start_ + size_), state(mark_bits<Block>(size_,start_))
 | 
			
		||||
	size(size_),
 | 
			
		||||
	start(start_),
 | 
			
		||||
	end(start_ + size_),
 | 
			
		||||
	state(mark_bits<Block>(size_,start_))
 | 
			
		||||
{
 | 
			
		||||
	initial_free_list(0);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -37,6 +43,7 @@ free_list_allocator<Block>::free_list_allocator(cell size_, cell start_) :
 | 
			
		|||
template<typename Block> void free_list_allocator<Block>::initial_free_list(cell occupied)
 | 
			
		||||
{
 | 
			
		||||
	free_blocks.initial_free_list(start,end,occupied);
 | 
			
		||||
	high_water_mark = free_blocks.free_space;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Block> bool free_list_allocator<Block>::contains_p(Block *block)
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +116,16 @@ template<typename Block> cell free_list_allocator<Block>::occupied_space()
 | 
			
		|||
	return size - free_blocks.free_space;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Block> cell free_list_allocator<Block>::largest_free_block()
 | 
			
		||||
{
 | 
			
		||||
	return free_blocks.largest_free_block();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Block> cell free_list_allocator<Block>::free_block_count()
 | 
			
		||||
{
 | 
			
		||||
	return free_blocks.free_block_count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Block>
 | 
			
		||||
void free_list_allocator<Block>::sweep()
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -158,6 +175,8 @@ void free_list_allocator<Block>::sweep()
 | 
			
		|||
 | 
			
		||||
	if(prev && prev->free_p())
 | 
			
		||||
		free_blocks.add_to_free_list((free_heap_block *)prev);
 | 
			
		||||
 | 
			
		||||
	high_water_mark = free_blocks.free_space;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Block>
 | 
			
		||||
| 
						 | 
				
			
			@ -211,6 +230,8 @@ void free_list_allocator<Block>::sweep(Iterator &iter)
 | 
			
		|||
 | 
			
		||||
	if(prev && prev->free_p())
 | 
			
		||||
		free_blocks.add_to_free_list((free_heap_block *)prev);
 | 
			
		||||
 | 
			
		||||
	high_water_mark = free_blocks.free_space;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Block, typename Iterator> struct heap_compactor {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										15
									
								
								vm/gc.cpp
								
								
								
								
							
							
						
						
									
										15
									
								
								vm/gc.cpp
								
								
								
								
							| 
						 | 
				
			
			@ -152,6 +152,19 @@ void factor_vm::gc(gc_op op, cell requested_bytes, bool trace_contexts_p)
 | 
			
		|||
		start_gc_again();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(current_gc->op == collect_aging_op
 | 
			
		||||
		|| current_gc->op == collect_to_tenured_op
 | 
			
		||||
		|| current_gc->op == collect_full_op)
 | 
			
		||||
	{
 | 
			
		||||
		if(data->tenured->largest_free_block() <= data->nursery->size + data->aging->size)
 | 
			
		||||
			current_gc->op = collect_compact_op;
 | 
			
		||||
	
 | 
			
		||||
		if(data->tenured->high_water_mark - data->tenured->free_space() >= data->promotion_threshold)
 | 
			
		||||
			current_gc->op = collect_full_op;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	current_gc->event->op = current_gc->op;
 | 
			
		||||
 | 
			
		||||
	switch(current_gc->op)
 | 
			
		||||
	{
 | 
			
		||||
	case collect_nursery_op:
 | 
			
		||||
| 
						 | 
				
			
			@ -316,7 +329,7 @@ void factor_vm::primitive_disable_gc_events()
 | 
			
		|||
{
 | 
			
		||||
	if(gc_events)
 | 
			
		||||
	{
 | 
			
		||||
		byte_array *data = byte_array_from_values(&gc_events->first(),gc_events->size());
 | 
			
		||||
		byte_array *data = byte_array_from_values(&gc_events->front(),gc_events->size());
 | 
			
		||||
		dpush(tag<byte_array>(data));
 | 
			
		||||
 | 
			
		||||
		delete gc_events;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,8 @@ void factor_vm::load_data_heap(FILE *file, image_header *h, vm_parameters *p)
 | 
			
		|||
 | 
			
		||||
	init_data_heap(p->young_size,
 | 
			
		||||
		p->aging_size,
 | 
			
		||||
		p->tenured_size);
 | 
			
		||||
		p->tenured_size,
 | 
			
		||||
		p->promotion_threshold);
 | 
			
		||||
 | 
			
		||||
	fixnum bytes_read = fread((void*)data->tenured->start,1,h->data_size,file);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,6 +33,7 @@ struct vm_parameters {
 | 
			
		|||
	const vm_char *executable_path;
 | 
			
		||||
	cell ds_size, rs_size;
 | 
			
		||||
	cell young_size, aging_size, tenured_size;
 | 
			
		||||
	cell promotion_threshold;
 | 
			
		||||
	cell code_size;
 | 
			
		||||
	bool fep;
 | 
			
		||||
	bool console;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -218,7 +218,7 @@ struct factor_vm
 | 
			
		|||
	//data heap
 | 
			
		||||
	void init_card_decks();
 | 
			
		||||
	void set_data_heap(data_heap *data_);
 | 
			
		||||
	void init_data_heap(cell young_size, cell aging_size, cell tenured_size);
 | 
			
		||||
	void init_data_heap(cell young_size, cell aging_size, cell tenured_size, cell promotion_threshold);
 | 
			
		||||
	void primitive_size();
 | 
			
		||||
	data_heap_room data_room();
 | 
			
		||||
	void primitive_data_room();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue