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->young_size = sizeof(cell) / 4;
p->aging_size = sizeof(cell) / 2;
p->tenured_size = 4 * sizeof(cell);
p->tenured_size = 16 * sizeof(cell);
#endif
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);
free_heap_block *find_free_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);
void free(Block *block);
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;
}
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)
{
size = align(size,block_granularity);

View File

@ -115,7 +115,7 @@ void factor_vm::primitive_full_gc()
gc(collect_full_op,
0, /* requested size */
true, /* trace contexts? */
false /* compact code heap? */);
true /* compact code heap? */);
}
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,
after a GC if needed */
if(nursery.size > size)
if(size < nursery.size)
{
/* If there is insufficient room, collect the nursery */
if(nursery.here + size > nursery.end)
@ -239,23 +239,21 @@ object *factor_vm::allot_object(header header, cell size)
obj = nursery.allot(size);
}
/* If the object is bigger than the nursery, allocate it in
tenured space */
else
{
/* If tenured space does not have enough room, collect */
//XXX
//if(data->tenured->here + size > data->tenured->end)
primitive_full_gc();
/* If it still won't fit, grow the heap */
//XXX
//if(data->tenured->here + size > data->tenured->end)
/* If tenured space does not have enough room, collect and compact */
if(!data->tenured->can_allot_p(size))
{
gc(collect_growing_heap_op,
size, /* requested size */
true, /* trace contexts? */
false /* compact code heap? */);
primitive_compact_gc();
/* If it still won't fit, grow the heap */
if(!data->tenured->can_allot_p(size))
{
gc(collect_growing_heap_op,
size, /* requested size */
true, /* trace contexts? */
false /* compact code heap? */);
}
}
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)
{
cell good_size = h->data_size + (1 << 20);
if(good_size > p->tenured_size)
p->tenured_size = good_size;
p->tenured_size = std::max((h->data_size * 3) / 2,p->tenured_size);
init_data_heap(p->young_size,
p->aging_size,