vm: debugging mark-sweep
							parent
							
								
									814f6371d6
								
							
						
					
					
						commit
						af855b7fa9
					
				| 
						 | 
					@ -40,9 +40,10 @@ void factor_vm::collect_aging()
 | 
				
			||||||
		collector.trace_contexts();
 | 
							collector.trace_contexts();
 | 
				
			||||||
		collector.trace_code_heap_roots(&code->points_to_aging);
 | 
							collector.trace_code_heap_roots(&code->points_to_aging);
 | 
				
			||||||
		collector.cheneys_algorithm();
 | 
							collector.cheneys_algorithm();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		update_code_heap_for_minor_gc(&code->points_to_aging);
 | 
							update_code_heap_for_minor_gc(&code->points_to_aging);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nursery.here = nursery.start;
 | 
							data->reset_generation(&nursery);
 | 
				
			||||||
		code->points_to_nursery.clear();
 | 
							code->points_to_nursery.clear();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,11 +65,43 @@ data_heap *data_heap::grow(cell requested_bytes)
 | 
				
			||||||
	return new data_heap(young_size,aging_size,new_tenured_size);
 | 
						return new data_heap(young_size,aging_size,new_tenured_size);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename Generation> void data_heap::clear_cards(Generation *gen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						cell first_card = addr_to_card(gen->start - start);
 | 
				
			||||||
 | 
						cell last_card = addr_to_card(gen->end - start);
 | 
				
			||||||
 | 
						memset(&cards[first_card],0,last_card - first_card);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename Generation> void data_heap::clear_decks(Generation *gen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						cell first_deck = addr_to_deck(gen->start - start);
 | 
				
			||||||
 | 
						cell last_deck = addr_to_deck(gen->end - start);
 | 
				
			||||||
 | 
						memset(&decks[first_deck],0,last_deck - first_deck);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void data_heap::reset_generation(nursery_space *gen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gen->here = gen->start;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void data_heap::reset_generation(aging_space *gen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						gen->here = gen->start;
 | 
				
			||||||
 | 
						clear_cards(gen);
 | 
				
			||||||
 | 
						clear_decks(gen);
 | 
				
			||||||
 | 
						gen->starts.clear_object_start_offsets();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void data_heap::reset_generation(tenured_space *gen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						clear_cards(gen);
 | 
				
			||||||
 | 
						clear_decks(gen);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void factor_vm::set_data_heap(data_heap *data_)
 | 
					void factor_vm::set_data_heap(data_heap *data_)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	data = data_;
 | 
						data = data_;
 | 
				
			||||||
	nursery = *data->nursery;
 | 
						nursery = *data->nursery;
 | 
				
			||||||
	nursery.here = nursery.start;
 | 
					 | 
				
			||||||
	init_card_decks();
 | 
						init_card_decks();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,31 +26,9 @@ struct data_heap {
 | 
				
			||||||
	data_heap *grow(cell requested_size);
 | 
						data_heap *grow(cell requested_size);
 | 
				
			||||||
	template<typename Generation> void clear_cards(Generation *gen);
 | 
						template<typename Generation> void clear_cards(Generation *gen);
 | 
				
			||||||
	template<typename Generation> void clear_decks(Generation *gen);
 | 
						template<typename Generation> void clear_decks(Generation *gen);
 | 
				
			||||||
	template<typename Generation> void reset_generation(Generation *gen);
 | 
						void reset_generation(nursery_space *gen);
 | 
				
			||||||
 | 
						void reset_generation(aging_space *gen);
 | 
				
			||||||
 | 
						void reset_generation(tenured_space *gen);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename Generation> void data_heap::clear_cards(Generation *gen)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	cell first_card = addr_to_card(gen->start - start);
 | 
					 | 
				
			||||||
	cell last_card = addr_to_card(gen->end - start);
 | 
					 | 
				
			||||||
	memset(&cards[first_card],0,last_card - first_card);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename Generation> void data_heap::clear_decks(Generation *gen)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	cell first_deck = addr_to_deck(gen->start - start);
 | 
					 | 
				
			||||||
	cell last_deck = addr_to_deck(gen->end - start);
 | 
					 | 
				
			||||||
	memset(&decks[first_deck],0,last_deck - first_deck);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* After garbage collection, any generations which are now empty need to have
 | 
					 | 
				
			||||||
their allocation pointers and cards reset. */
 | 
					 | 
				
			||||||
template<typename Generation> void data_heap::reset_generation(Generation *gen)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	gen->here = gen->start;
 | 
					 | 
				
			||||||
	clear_cards(gen);
 | 
					 | 
				
			||||||
	clear_decks(gen);
 | 
					 | 
				
			||||||
	gen->starts.clear_object_start_offsets();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -88,10 +88,12 @@ Makes a free list consisting of one free block, at the very end. */
 | 
				
			||||||
template<typename Block> void free_list_allocator<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 *last_block = (free_heap_block *)(start + size);
 | 
						if(size != this->size)
 | 
				
			||||||
	last_block->set_free();
 | 
						{
 | 
				
			||||||
	last_block->set_size(end - (cell)last_block);
 | 
							free_heap_block *last_block = (free_heap_block *)(start + size);
 | 
				
			||||||
	add_to_free_list(last_block);
 | 
							last_block->make_free(end - (cell)last_block);
 | 
				
			||||||
 | 
							add_to_free_list(last_block);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename Block> void free_list_allocator<Block>::assert_free_block(free_heap_block *block)
 | 
					template<typename Block> void free_list_allocator<Block>::assert_free_block(free_heap_block *block)
 | 
				
			||||||
| 
						 | 
					@ -147,10 +149,9 @@ template<typename Block> free_heap_block *free_list_allocator<Block>::split_free
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* split the block in two */
 | 
							/* split the block in two */
 | 
				
			||||||
		free_heap_block *split = (free_heap_block *)((cell)block + size);
 | 
							free_heap_block *split = (free_heap_block *)((cell)block + size);
 | 
				
			||||||
		split->set_free();
 | 
							split->make_free(block->size() - size);
 | 
				
			||||||
		split->set_size(block->size() - size);
 | 
					 | 
				
			||||||
		split->next_free = block->next_free;
 | 
							split->next_free = block->next_free;
 | 
				
			||||||
		block->set_size(size);
 | 
							block->make_free(size);
 | 
				
			||||||
		add_to_free_list(split);
 | 
							add_to_free_list(split);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -174,7 +175,7 @@ template<typename Block> Block *free_list_allocator<Block>::allot(cell size)
 | 
				
			||||||
template<typename Block> void free_list_allocator<Block>::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->make_free(block->size());
 | 
				
			||||||
	add_to_free_list(free_block);
 | 
						add_to_free_list(free_block);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -267,7 +268,8 @@ void free_list_allocator<Block>::sweep()
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				((free_heap_block *)scan)->set_free();
 | 
									free_heap_block *free_block = (free_heap_block *)scan;
 | 
				
			||||||
 | 
									free_block->make_free(size);
 | 
				
			||||||
				prev = scan;
 | 
									prev = scan;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -319,7 +321,8 @@ void free_list_allocator<Block>::sweep(Iterator &iter)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				scan->set_free();
 | 
									free_heap_block *free_block = (free_heap_block *)scan;
 | 
				
			||||||
 | 
									free_block->make_free(size);
 | 
				
			||||||
				prev = scan;
 | 
									prev = scan;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,12 +108,24 @@ void full_collector::mark_reachable_objects()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct object_start_map_updater {
 | 
				
			||||||
 | 
						object_start_map *starts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						object_start_map_updater(object_start_map *starts_) : starts(starts_) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void operator()(object *obj, cell size)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							starts->record_object_start_offset(obj);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void factor_vm::collect_full_impl(bool trace_contexts_p)
 | 
					void factor_vm::collect_full_impl(bool trace_contexts_p)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	full_collector collector(this);
 | 
						full_collector collector(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	code->clear_mark_bits();
 | 
						code->clear_mark_bits();
 | 
				
			||||||
	data->tenured->clear_mark_bits();
 | 
						data->tenured->clear_mark_bits();
 | 
				
			||||||
 | 
						data->tenured->clear_mark_stack();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	collector.trace_roots();
 | 
						collector.trace_roots();
 | 
				
			||||||
        if(trace_contexts_p)
 | 
					        if(trace_contexts_p)
 | 
				
			||||||
| 
						 | 
					@ -125,9 +137,14 @@ void factor_vm::collect_full_impl(bool trace_contexts_p)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	collector.mark_reachable_objects();
 | 
						collector.mark_reachable_objects();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data->tenured->sweep();
 | 
						data->tenured->starts.clear_object_start_offsets();
 | 
				
			||||||
 | 
						object_start_map_updater updater(&data->tenured->starts);
 | 
				
			||||||
 | 
						data->tenured->sweep(updater);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data->reset_generation(data->tenured);
 | 
				
			||||||
	data->reset_generation(data->aging);
 | 
						data->reset_generation(data->aging);
 | 
				
			||||||
	nursery.here = nursery.start;
 | 
						data->reset_generation(&nursery);
 | 
				
			||||||
 | 
						code->clear_remembered_set();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void factor_vm::collect_growing_heap(cell requested_bytes,
 | 
					void factor_vm::collect_growing_heap(cell requested_bytes,
 | 
				
			||||||
| 
						 | 
					@ -144,8 +161,6 @@ void factor_vm::collect_growing_heap(cell requested_bytes,
 | 
				
			||||||
		compact_code_heap(trace_contexts_p);
 | 
							compact_code_heap(trace_contexts_p);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		relocate_code_heap();
 | 
							relocate_code_heap();
 | 
				
			||||||
 | 
					 | 
				
			||||||
	code->clear_remembered_set();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void factor_vm::collect_full(bool trace_contexts_p, bool compact_code_heap_p)
 | 
					void factor_vm::collect_full(bool trace_contexts_p, bool compact_code_heap_p)
 | 
				
			||||||
| 
						 | 
					@ -156,8 +171,6 @@ void factor_vm::collect_full(bool trace_contexts_p, bool compact_code_heap_p)
 | 
				
			||||||
		compact_code_heap(trace_contexts_p);
 | 
							compact_code_heap(trace_contexts_p);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		update_code_heap_words_and_literals();
 | 
							update_code_heap_words_and_literals();
 | 
				
			||||||
 | 
					 | 
				
			||||||
	code->clear_remembered_set();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,8 +58,6 @@ static const cell data_alignment = 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TYPE_COUNT 15
 | 
					#define TYPE_COUNT 15
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Not real types, but code_block's type can be set to this */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum code_block_type
 | 
					enum code_block_type
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	code_block_unoptimized,
 | 
						code_block_unoptimized,
 | 
				
			||||||
| 
						 | 
					@ -229,30 +227,29 @@ struct heap_block
 | 
				
			||||||
		return header & 1 == 1;
 | 
							return header & 1 == 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void set_free()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		header |= 1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void clear_free()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		header &= ~1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cell size()
 | 
						cell size()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return header >> 3;
 | 
							cell bytes = header >> 3;
 | 
				
			||||||
 | 
					#ifdef FACTOR_DEBUG
 | 
				
			||||||
 | 
							assert(bytes > 0);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
							return bytes;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void set_size(cell size)
 | 
						void set_size(cell size)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		header = (header & 0x7) | (size << 3);
 | 
							header = ((header & 0x7) | (size << 3));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct free_heap_block : public heap_block
 | 
					struct free_heap_block : public heap_block
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	free_heap_block *next_free;
 | 
						free_heap_block *next_free;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void make_free(cell size)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							header = (size << 3) | 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct code_block : public heap_block
 | 
					struct code_block : public heap_block
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,11 +55,6 @@ template<typename Block> struct mark_bits {
 | 
				
			||||||
		cell line_number = block_line(address);
 | 
							cell line_number = block_line(address);
 | 
				
			||||||
		cell word_index = (line_number >> 6);
 | 
							cell word_index = (line_number >> 6);
 | 
				
			||||||
		cell word_shift = (line_number & 63);
 | 
							cell word_shift = (line_number & 63);
 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef FACTOR_DEBUG
 | 
					 | 
				
			||||||
		assert(word_index < bits_size);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return std::make_pair(word_index,word_shift);
 | 
							return std::make_pair(word_index,word_shift);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,7 @@ void factor_vm::collect_nursery()
 | 
				
			||||||
	collector.cheneys_algorithm();
 | 
						collector.cheneys_algorithm();
 | 
				
			||||||
	update_code_heap_for_minor_gc(&code->points_to_nursery);
 | 
						update_code_heap_for_minor_gc(&code->points_to_nursery);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nursery.here = nursery.start;
 | 
						data->reset_generation(&nursery);
 | 
				
			||||||
	code->points_to_nursery.clear();
 | 
						code->points_to_nursery.clear();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,6 +51,11 @@ struct tenured_space : free_list_allocator<object> {
 | 
				
			||||||
		state.clear_mark_bits();
 | 
							state.clear_mark_bits();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void clear_mark_stack()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							mark_stack.clear();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool marked_p(object *obj)
 | 
						bool marked_p(object *obj)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return this->state.marked_p(obj);
 | 
							return this->state.marked_p(obj);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,19 +26,20 @@ void factor_vm::collect_to_tenured()
 | 
				
			||||||
	/* Copy live objects from aging space to tenured space. */
 | 
						/* Copy live objects from aging space to tenured space. */
 | 
				
			||||||
	to_tenured_collector collector(this);
 | 
						to_tenured_collector collector(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data->tenured->clear_mark_stack();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	collector.trace_roots();
 | 
						collector.trace_roots();
 | 
				
			||||||
	collector.trace_contexts();
 | 
						collector.trace_contexts();
 | 
				
			||||||
	collector.trace_cards(data->tenured,
 | 
						collector.trace_cards(data->tenured,
 | 
				
			||||||
		card_points_to_aging,
 | 
							card_points_to_aging,
 | 
				
			||||||
		dummy_unmarker());
 | 
							simple_unmarker(card_mark_mask));
 | 
				
			||||||
	collector.trace_code_heap_roots(&code->points_to_aging);
 | 
						collector.trace_code_heap_roots(&code->points_to_aging);
 | 
				
			||||||
	collector.tenure_reachable_objects();
 | 
						collector.tenure_reachable_objects();
 | 
				
			||||||
	update_code_heap_for_minor_gc(&code->points_to_aging);
 | 
						update_code_heap_for_minor_gc(&code->points_to_aging);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nursery.here = nursery.start;
 | 
						data->reset_generation(&nursery);
 | 
				
			||||||
	data->reset_generation(data->aging);
 | 
						data->reset_generation(data->aging);
 | 
				
			||||||
	code->points_to_nursery.clear();
 | 
						code->clear_remembered_set();
 | 
				
			||||||
	code->points_to_aging.clear();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue