vm: vm: fix large object allocation logic and change default heap image size for 2009

db4
Slava Pestov 2009-10-25 13:27:40 -05:00
parent cf247c23a2
commit 7d8c85443e
4 changed files with 38 additions and 21 deletions

View File

@ -32,7 +32,7 @@ void factor_vm::default_parameters(vm_parameters *p)
p->code_size = 8 * sizeof(cell); p->code_size = 8 * sizeof(cell);
p->young_size = sizeof(cell) / 4; p->young_size = sizeof(cell) / 4;
p->aging_size = sizeof(cell) / 2; p->aging_size = sizeof(cell) / 2;
p->tenured_size = 4 * sizeof(cell); p->tenured_size = 16 * sizeof(cell);
#endif #endif
p->max_pic_size = 3; p->max_pic_size = 3;

View File

@ -47,6 +47,7 @@ template<typename Block> struct free_list_allocator {
void assert_free_block(free_heap_block *block); void assert_free_block(free_heap_block *block);
free_heap_block *find_free_block(cell size); free_heap_block *find_free_block(cell size);
free_heap_block *split_free_block(free_heap_block *block, cell size); free_heap_block *split_free_block(free_heap_block *block, cell size);
bool can_allot_p(cell size);
Block *allot(cell size); Block *allot(cell size);
void free(Block *block); void free(Block *block);
void usage(cell *used, cell *total_free, cell *max_free); void usage(cell *used, cell *total_free, cell *max_free);
@ -180,6 +181,27 @@ template<typename Block> free_heap_block *free_list_allocator<Block>::split_free
return block; return block;
} }
template<typename Block> bool free_list_allocator<Block>::can_allot_p(cell size)
{
cell attempt = size;
while(attempt < free_list_count * block_granularity)
{
int index = attempt / block_granularity;
if(free_blocks.small_blocks[index]) return true;
attempt *= 2;
}
free_heap_block *block = free_blocks.large_blocks;
while(block)
{
if(block->size() >= size) return true;
block = block->next_free;
}
return false;
}
template<typename Block> Block *free_list_allocator<Block>::allot(cell size) template<typename Block> Block *free_list_allocator<Block>::allot(cell size)
{ {
size = align(size,block_granularity); size = align(size,block_granularity);

View File

@ -115,7 +115,7 @@ void factor_vm::primitive_full_gc()
gc(collect_full_op, gc(collect_full_op,
0, /* requested size */ 0, /* requested size */
true, /* trace contexts? */ true, /* trace contexts? */
false /* compact code heap? */); true /* compact code heap? */);
} }
void factor_vm::primitive_compact_gc() void factor_vm::primitive_compact_gc()
@ -231,7 +231,7 @@ object *factor_vm::allot_object(header header, cell size)
/* If the object is smaller than the nursery, allocate it in the nursery, /* If the object is smaller than the nursery, allocate it in the nursery,
after a GC if needed */ after a GC if needed */
if(nursery.size > size) if(size < nursery.size)
{ {
/* If there is insufficient room, collect the nursery */ /* If there is insufficient room, collect the nursery */
if(nursery.here + size > nursery.end) if(nursery.here + size > nursery.end)
@ -239,24 +239,22 @@ object *factor_vm::allot_object(header header, cell size)
obj = nursery.allot(size); obj = nursery.allot(size);
} }
/* If the object is bigger than the nursery, allocate it in
tenured space */
else else
{ {
/* If tenured space does not have enough room, collect */ /* If tenured space does not have enough room, collect and compact */
//XXX if(!data->tenured->can_allot_p(size))
//if(data->tenured->here + size > data->tenured->end) {
primitive_full_gc(); primitive_compact_gc();
/* If it still won't fit, grow the heap */ /* If it still won't fit, grow the heap */
//XXX if(!data->tenured->can_allot_p(size))
//if(data->tenured->here + size > data->tenured->end)
{ {
gc(collect_growing_heap_op, gc(collect_growing_heap_op,
size, /* requested size */ size, /* requested size */
true, /* trace contexts? */ true, /* trace contexts? */
false /* compact code heap? */); false /* compact code heap? */);
} }
}
obj = data->tenured->allot(size); obj = data->tenured->allot(size);

View File

@ -16,10 +16,7 @@ void factor_vm::init_objects(image_header *h)
void factor_vm::load_data_heap(FILE *file, image_header *h, vm_parameters *p) void factor_vm::load_data_heap(FILE *file, image_header *h, vm_parameters *p)
{ {
cell good_size = h->data_size + (1 << 20); p->tenured_size = std::max((h->data_size * 3) / 2,p->tenured_size);
if(good_size > p->tenured_size)
p->tenured_size = good_size;
init_data_heap(p->young_size, init_data_heap(p->young_size,
p->aging_size, p->aging_size,