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;
+ }
};
}
{
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> {
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();
}
clear_cards(gen);
clear_decks(gen);
- gen->clear_object_start_offsets();
+ gen->starts.clear_object_start_offsets();
}
}
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);
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;
}
else
*used += size;
- scan = layout.next_block_after(scan);
+ scan = next_block_after(scan);
}
}
while(scan != end)
{
if(scan->free_p()) break;
- else scan = layout.next_block_after(scan);
+ else scan = next_block_after(scan);
}
if(scan != end)
}
}
- scan = layout.next_block_after(scan);
+ scan = next_block_after(scan);
}
if(prev && prev->free_p())
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);
}
}
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 */
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;
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;
}
/* 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;
-}
-
}
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);
};
}
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;
+ }
};
}
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;
+ }
};
}