vm: object start recording in cards is now independent of allocation strategy

db4
Slava Pestov 2009-10-20 13:47:04 -05:00
parent d22d5466fc
commit e482940dca
12 changed files with 91 additions and 49 deletions

View File

@ -1,8 +1,20 @@
namespace factor
{
struct aging_space : old_space {
aging_space(cell size, cell start) : old_space(size,start) {}
struct aging_space : zone {
object_start_map starts;
aging_space(cell size, cell start) :
zone(size,start), starts(size,start) {}
object *allot(cell size)
{
if(here + size > end) return NULL;
object *obj = zone::allot(size);
starts.record_object_start_offset(obj);
return obj;
}
};
}

View File

@ -6,11 +6,6 @@ struct code_heap_layout {
{
return block->size();
}
heap_block *next_block_after(heap_block *block)
{
return (heap_block *)((cell)block + block_size(block));
}
};
struct code_heap : heap<heap_block,code_heap_layout> {

View File

@ -95,7 +95,7 @@ struct copying_collector : collector<TargetGeneration,Policy> {
if(end < card_start_address(card_index))
{
start = gen->find_object_containing_card(card_index - gen_start_card);
start = gen->starts.find_object_containing_card(card_index - gen_start_card);
binary_start = start + this->parent->binary_payload_start((object *)start);
end = start + ((object *)start)->size();
}

View File

@ -52,7 +52,7 @@ template<typename Generation> void data_heap::reset_generation(Generation *gen)
clear_cards(gen);
clear_decks(gen);
gen->clear_object_start_offsets();
gen->starts.clear_object_start_offsets();
}
}

View File

@ -28,6 +28,11 @@ template<typename Block, typename HeapLayout> struct heap {
return (Block *)seg->end;
}
Block *next_block_after(heap_block *block)
{
return (Block *)((cell)block + layout.block_size(block));
}
void clear_free_list();
void add_to_free_list(free_heap_block *block);
void build_free_list(cell size);
@ -50,7 +55,7 @@ template<typename Block, typename HeapLayout> struct heap {
while(scan != end)
{
Block *next = layout.next_block_after(scan);
Block *next = next_block_after(scan);
if(!scan->free_p()) iter(scan,layout.block_size(scan));
scan = next;
}
@ -229,7 +234,7 @@ void heap<Block,HeapLayout>::heap_usage(cell *used, cell *total_free, cell *max_
else
*used += size;
scan = layout.next_block_after(scan);
scan = next_block_after(scan);
}
}
@ -243,7 +248,7 @@ cell heap<Block,HeapLayout>::heap_size()
while(scan != end)
{
if(scan->free_p()) break;
else scan = layout.next_block_after(scan);
else scan = next_block_after(scan);
}
if(scan != end)
@ -308,7 +313,7 @@ void heap<Block,HeapLayout>::sweep_heap(Iterator &iter)
}
}
scan = layout.next_block_after(scan);
scan = next_block_after(scan);
}
if(prev && prev->free_p())

View File

@ -203,7 +203,7 @@ void factor_vm::relocate_data(cell data_relocation_base, cell code_relocation_ba
while(obj)
{
relocate_object((object *)obj,data_relocation_base,code_relocation_base);
data->tenured->record_object_start_offset((object *)obj);
data->tenured->starts.record_object_start_offset((object *)obj);
obj = data->tenured->next_object_after(obj);
}
}

View File

@ -148,8 +148,17 @@ struct header {
struct object {
NO_TYPE_CHECK;
header h;
cell *slots() { return (cell *)this; }
cell size();
cell *slots() { return (cell *)this; }
/* Only valid for objects in tenured space; must fast to free_heap_block
to do anything with it if its free */
bool free_p()
{
return h.value & 1 == 1;
}
};
/* Assembly code makes assumptions about the layout of this struct */

View File

@ -70,10 +70,15 @@ template<typename Block, typename HeapLayout> struct mark_bits {
return (bits[pair.first] & ((u64)1 << pair.second)) != 0;
}
Block *next_block_after(Block *block)
{
return (Block *)((cell)block + layout.block_size(block));
}
void set_bitmap_range(u64 *bits, Block *address)
{
std::pair<cell,cell> start = bitmap_deref(address);
std::pair<cell,cell> end = bitmap_deref(layout.next_block_after(address));
std::pair<cell,cell> end = bitmap_deref(next_block_after(address));
u64 start_mask = ((u64)1 << start.second) - 1;
u64 end_mask = ((u64)1 << end.second) - 1;

View File

@ -3,23 +3,24 @@
namespace factor
{
old_space::old_space(cell size_, cell start_) : zone(size_,start_)
object_start_map::object_start_map(cell size_, cell start_) :
size(size_), start(start_)
{
object_start_offsets = new card[addr_to_card(size_)];
object_start_offsets_end = object_start_offsets + addr_to_card(size_);
}
old_space::~old_space()
object_start_map::~object_start_map()
{
delete[] object_start_offsets;
}
cell old_space::first_object_in_card(cell card_index)
cell object_start_map::first_object_in_card(cell card_index)
{
return object_start_offsets[card_index];
}
cell old_space::find_object_containing_card(cell card_index)
cell object_start_map::find_object_containing_card(cell card_index)
{
if(card_index == 0)
return start;
@ -41,34 +42,16 @@ cell old_space::find_object_containing_card(cell card_index)
}
/* we need to remember the first object allocated in the card */
void old_space::record_object_start_offset(object *obj)
void object_start_map::record_object_start_offset(object *obj)
{
cell idx = addr_to_card((cell)obj - start);
if(object_start_offsets[idx] == card_starts_inside_object)
object_start_offsets[idx] = ((cell)obj & addr_card_mask);
card obj_start = ((cell)obj & addr_card_mask);
object_start_offsets[idx] = std::min(object_start_offsets[idx],obj_start);
}
object *old_space::allot(cell size)
{
if(here + size > end) return NULL;
object *obj = zone::allot(size);
record_object_start_offset(obj);
return obj;
}
void old_space::clear_object_start_offsets()
void object_start_map::clear_object_start_offsets()
{
memset(object_start_offsets,card_starts_inside_object,addr_to_card(size));
}
cell old_space::next_object_after(cell scan)
{
cell size = ((object *)scan)->size();
if(scan + size < here)
return scan + size;
else
return 0;
}
}

View File

@ -3,19 +3,18 @@ namespace factor
static const cell card_starts_inside_object = 0xff;
struct old_space : zone {
struct object_start_map {
cell size, start;
card *object_start_offsets;
card *object_start_offsets_end;
old_space(cell size_, cell start_);
~old_space();
object_start_map(cell size_, cell start_);
~object_start_map();
cell first_object_in_card(cell card_index);
cell find_object_containing_card(cell card_index);
void record_object_start_offset(object *obj);
object *allot(cell size);
void clear_object_start_offsets();
cell next_object_after(cell scan);
};
}

View File

@ -1,8 +1,33 @@
namespace factor
{
struct tenured_space : old_space {
tenured_space(cell size, cell start) : old_space(size,start) {}
struct tenured_space_layout {
cell block_size(object *block)
{
if(block->free_p())
{
free_heap_block *free_block = (free_heap_block *)block;
return free_block->size();
}
else
return block->size();
}
};
struct tenured_space : zone {
object_start_map starts;
tenured_space(cell size, cell start) :
zone(size,start), starts(size,start) {}
object *allot(cell size)
{
if(here + size > end) return NULL;
object *obj = zone::allot(size);
starts.record_object_start_offset(obj);
return obj;
}
};
}

View File

@ -21,6 +21,15 @@ struct zone {
here = h + align(size,data_alignment);
return (object *)h;
}
cell next_object_after(cell scan)
{
cell size = ((object *)scan)->size();
if(scan + size < here)
return scan + size;
else
return 0;
}
};
}