vm: erase code blocks from all_blocks during sweep

Fixes #437
db4
Joe Groff 2011-12-13 12:28:09 -08:00
parent 083b856604
commit bd7e6b33f8
4 changed files with 50 additions and 2 deletions

View File

@ -72,6 +72,31 @@ void code_heap::flush_icache()
factor::flush_icache(seg->start,seg->size);
}
struct clear_free_blocks_from_all_blocks_iterator
{
code_heap *code;
clear_free_blocks_from_all_blocks_iterator(code_heap *code) : code(code) {}
void operator()(code_block *free_block, cell size) {
std::set<code_block*>::iterator erase_from =
code->all_blocks.lower_bound(free_block);
std::set<code_block*>::iterator erase_to =
code->all_blocks.lower_bound((code_block*)((char*)free_block + size));
code->all_blocks.erase(erase_from, erase_to);
}
};
void code_heap::sweep()
{
clear_free_blocks_from_all_blocks_iterator clearer(this);
allocator->sweep(clearer);
#ifdef FACTOR_DEBUG
verify_all_blocks_set();
#endif
}
struct all_blocks_set_verifier {
std::set<code_block*> *leftovers;
@ -104,6 +129,11 @@ code_block *code_heap::code_block_for_address(cell address)
&& address - (cell)found_block->entry_point() < found_block->size()))
{
std::cerr << "invalid block found in all_blocks set!" << std::endl;
std::cerr << "address " << (void*)address
<< " block " << (void*)found_block
<< " entry point " << (void*)found_block->entry_point()
<< " size " << found_block->size()
<< " free? " << found_block->free_p();
verify_all_blocks_set();
FACTOR_ASSERT(false);
}

View File

@ -48,6 +48,8 @@ struct code_heap {
void verify_all_blocks_set();
void initialize_all_blocks_set();
void sweep();
code_block *code_block_for_address(cell address);
bool safepoint_p(cell addr)

View File

@ -23,6 +23,7 @@ template<typename Block> struct free_list_allocator {
cell largest_free_block();
cell free_block_count();
void sweep();
template<typename Iterator> void sweep(Iterator &iter);
template<typename Iterator, typename Fixup> void compact(Iterator &iter, Fixup fixup, const Block **finger);
template<typename Iterator, typename Fixup> void iterate(Iterator &iter, Fixup fixup);
template<typename Iterator> void iterate(Iterator &iter);
@ -124,7 +125,8 @@ template<typename Block> cell free_list_allocator<Block>::free_block_count()
}
template<typename Block>
void free_list_allocator<Block>::sweep()
template<typename Iterator>
void free_list_allocator<Block>::sweep(Iterator &iter)
{
free_blocks.clear_free_list();
@ -145,12 +147,26 @@ void free_list_allocator<Block>::sweep()
free_heap_block *free_block = (free_heap_block *)start;
free_block->make_free(size);
free_blocks.add_to_free_list(free_block);
iter(start, size);
start = (Block *)((char *)start + size);
}
}
}
template<typename Block>
struct null_sweep_iterator
{
void operator()(Block *free_block, cell size) {}
};
template<typename Block>
void free_list_allocator<Block>::sweep()
{
null_sweep_iterator<Block> none;
sweep(none);
}
template<typename Block, typename Iterator> struct heap_compactor {
mark_bits<Block> *state;
char *address;

View File

@ -101,7 +101,7 @@ void factor_vm::collect_sweep_impl()
update_code_roots_for_sweep();
if(event) event->started_code_sweep();
code->allocator->sweep();
code->sweep();
if(event) event->ended_code_sweep();
}