vm: split off free_list_allocator from heap class, rename zone to bump_allocator

db4
Slava Pestov 2009-10-20 15:15:05 -05:00
parent 5608bc1268
commit f0816d72f1
24 changed files with 147 additions and 131 deletions

View File

@ -55,7 +55,7 @@ DLL_OBJS = $(PLAF_DLL_OBJS) \
vm/jit.o \ vm/jit.o \
vm/math.o \ vm/math.o \
vm/nursery_collector.o \ vm/nursery_collector.o \
vm/old_space.o \ vm/object_start_map.o \
vm/primitives.o \ vm/primitives.o \
vm/profiler.o \ vm/profiler.o \
vm/quotations.o \ vm/quotations.o \

View File

@ -3,7 +3,8 @@ namespace factor
struct aging_policy { struct aging_policy {
factor_vm *parent; factor_vm *parent;
zone *aging, *tenured; aging_space *aging;
tenured_space *tenured;
aging_policy(factor_vm *parent_) : aging_policy(factor_vm *parent_) :
parent(parent_), parent(parent_),

View File

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

View File

@ -1,14 +1,15 @@
namespace factor namespace factor
{ {
struct zone { struct bump_allocator {
/* offset of 'here' and 'end' is hardcoded in compiler backends */ /* offset of 'here' and 'end' is hardcoded in compiler backends */
cell here; cell here;
cell start; cell start;
cell end; cell end;
cell size; cell size;
zone(cell size_, cell start_) : here(0), start(start_), end(start_ + size_), size(size_) {} bump_allocator(cell size_, cell start_) :
here(0), start(start_), end(start_ + size_), size(size_) {}
inline bool contains_p(object *pointer) inline bool contains_p(object *pointer)
{ {

View File

@ -439,7 +439,7 @@ void factor_vm::fixup_labels(array *labels, code_block *compiled)
/* Might GC */ /* Might GC */
code_block *factor_vm::allot_code_block(cell size, code_block_type type) code_block *factor_vm::allot_code_block(cell size, code_block_type type)
{ {
heap_block *block = code->heap_allot(size + sizeof(code_block)); heap_block *block = code->allocator->allot(size + sizeof(code_block));
/* If allocation failed, do a full GC and compact the code heap. /* If allocation failed, do a full GC and compact the code heap.
A full GC that occurs as a result of the data heap filling up does not A full GC that occurs as a result of the data heap filling up does not
@ -449,13 +449,13 @@ code_block *factor_vm::allot_code_block(cell size, code_block_type type)
if(block == NULL) if(block == NULL)
{ {
primitive_compact_gc(); primitive_compact_gc();
block = code->heap_allot(size + sizeof(code_block)); block = code->allocator->allot(size + sizeof(code_block));
/* Insufficient room even after code GC, give up */ /* Insufficient room even after code GC, give up */
if(block == NULL) if(block == NULL)
{ {
cell used, total_free, max_free; cell used, total_free, max_free;
code->heap_usage(&used,&total_free,&max_free); code->allocator->usage(&used,&total_free,&max_free);
print_string("Code heap stats:\n"); print_string("Code heap stats:\n");
print_string("Used: "); print_cell(used); nl(); print_string("Used: "); print_cell(used); nl();

View File

@ -3,7 +3,21 @@
namespace factor namespace factor
{ {
code_heap::code_heap(bool secure_gc, cell size) : heap<heap_block>(secure_gc,size,true) {} code_heap::code_heap(cell size)
{
if(size > (1L << (sizeof(cell) * 8 - 6))) fatal_error("Heap too large",size);
seg = new segment(align_page(size),true);
if(!seg) fatal_error("Out of memory in heap allocator",size);
allocator = new free_list_allocator<heap_block>(seg->start,size);
}
code_heap::~code_heap()
{
delete allocator;
allocator = NULL;
delete seg;
seg = NULL;
}
void code_heap::write_barrier(code_block *compiled) void code_heap::write_barrier(code_block *compiled)
{ {
@ -22,18 +36,33 @@ bool code_heap::needs_fixup_p(code_block *compiled)
return needs_fixup.count(compiled) > 0; return needs_fixup.count(compiled) > 0;
} }
bool code_heap::marked_p(heap_block *compiled)
{
return allocator->state.marked_p(compiled);
}
void code_heap::set_marked_p(code_block *compiled)
{
allocator->state.set_marked_p(compiled);
}
void code_heap::clear_mark_bits()
{
allocator->state.clear_mark_bits();
}
void code_heap::code_heap_free(code_block *compiled) void code_heap::code_heap_free(code_block *compiled)
{ {
points_to_nursery.erase(compiled); points_to_nursery.erase(compiled);
points_to_aging.erase(compiled); points_to_aging.erase(compiled);
needs_fixup.erase(compiled); needs_fixup.erase(compiled);
heap_free(compiled); allocator->free(compiled);
} }
/* Allocate a code heap during startup */ /* Allocate a code heap during startup */
void factor_vm::init_code_heap(cell size) void factor_vm::init_code_heap(cell size)
{ {
code = new code_heap(secure_gc,size); code = new code_heap(size);
} }
bool factor_vm::in_code_heap_p(cell ptr) bool factor_vm::in_code_heap_p(cell ptr)
@ -89,7 +118,7 @@ struct word_and_literal_code_heap_updater {
void factor_vm::update_code_heap_words_and_literals() void factor_vm::update_code_heap_words_and_literals()
{ {
word_and_literal_code_heap_updater updater(this); word_and_literal_code_heap_updater updater(this);
code->sweep_heap(updater); code->allocator->sweep(updater);
} }
/* After growing the heap, we have to perform a full relocation to update /* After growing the heap, we have to perform a full relocation to update
@ -109,7 +138,7 @@ void factor_vm::relocate_code_heap()
{ {
code_heap_relocator relocator(this); code_heap_relocator relocator(this);
code_heap_iterator<code_heap_relocator> iter(relocator); code_heap_iterator<code_heap_relocator> iter(relocator);
code->sweep_heap(iter); code->allocator->sweep(iter);
} }
void factor_vm::primitive_modify_code_heap() void factor_vm::primitive_modify_code_heap()
@ -169,7 +198,7 @@ void factor_vm::primitive_modify_code_heap()
void factor_vm::primitive_code_room() void factor_vm::primitive_code_room()
{ {
cell used, total_free, max_free; cell used, total_free, max_free;
code->heap_usage(&used,&total_free,&max_free); code->allocator->usage(&used,&total_free,&max_free);
dpush(tag_fixnum(code->seg->size / 1024)); dpush(tag_fixnum(code->seg->size / 1024));
dpush(tag_fixnum(used / 1024)); dpush(tag_fixnum(used / 1024));
dpush(tag_fixnum(total_free / 1024)); dpush(tag_fixnum(total_free / 1024));
@ -178,7 +207,7 @@ void factor_vm::primitive_code_room()
code_block *code_heap::forward_code_block(code_block *compiled) code_block *code_heap::forward_code_block(code_block *compiled)
{ {
return (code_block *)state->forward_block(compiled); return (code_block *)allocator->state.forward_block(compiled);
} }
struct callframe_forwarder { struct callframe_forwarder {
@ -277,7 +306,7 @@ function returns. */
void factor_vm::compact_code_heap(bool trace_contexts_p) void factor_vm::compact_code_heap(bool trace_contexts_p)
{ {
/* Figure out where blocks are going to go */ /* Figure out where blocks are going to go */
code->state->compute_forwarding(); code->allocator->state.compute_forwarding();
/* Update references to the code heap from the data heap */ /* Update references to the code heap from the data heap */
forward_object_xts(); forward_object_xts();
@ -291,7 +320,7 @@ void factor_vm::compact_code_heap(bool trace_contexts_p)
that the data heap is up to date since relocation looks up object XTs) */ that the data heap is up to date since relocation looks up object XTs) */
code_heap_relocator relocator(this); code_heap_relocator relocator(this);
code_heap_iterator<code_heap_relocator> iter(relocator); code_heap_iterator<code_heap_relocator> iter(relocator);
code->compact_heap(iter); code->allocator->compact(iter);
} }
struct stack_trace_stripper { struct stack_trace_stripper {

View File

@ -1,7 +1,13 @@
namespace factor namespace factor
{ {
struct code_heap : heap<heap_block> { struct code_heap {
/* The actual memory area */
segment *seg;
/* Memory allocator */
free_list_allocator<heap_block> *allocator;
/* Set of blocks which need full relocation. */ /* Set of blocks which need full relocation. */
std::set<code_block *> needs_fixup; std::set<code_block *> needs_fixup;
@ -11,10 +17,14 @@ struct code_heap : heap<heap_block> {
/* Code blocks which may reference objects in aging space or the nursery */ /* Code blocks which may reference objects in aging space or the nursery */
std::set<code_block *> points_to_aging; std::set<code_block *> points_to_aging;
explicit code_heap(bool secure_gc, cell size); explicit code_heap(cell size);
~code_heap();
void write_barrier(code_block *compiled); void write_barrier(code_block *compiled);
void clear_remembered_set(); void clear_remembered_set();
bool needs_fixup_p(code_block *compiled); bool needs_fixup_p(code_block *compiled);
bool marked_p(heap_block *compiled);
void set_marked_p(code_block *compiled);
void clear_mark_bits();
void code_heap_free(code_block *compiled); void code_heap_free(code_block *compiled);
code_block *forward_code_block(code_block *compiled); code_block *forward_code_block(code_block *compiled);
}; };

View File

@ -42,7 +42,7 @@ data_heap::data_heap(cell young_size_, cell aging_size_, cell tenured_size_)
aging = new aging_space(aging_size,tenured_semispace->end); aging = new aging_space(aging_size,tenured_semispace->end);
aging_semispace = new aging_space(aging_size,aging->end); aging_semispace = new aging_space(aging_size,aging->end);
nursery = new zone(young_size,aging_semispace->end); nursery = new bump_allocator(young_size,aging_semispace->end);
assert(seg->end - nursery->end <= deck_size); assert(seg->end - nursery->end <= deck_size);
} }
@ -75,10 +75,9 @@ void factor_vm::set_data_heap(data_heap *data_)
data->reset_generation(data->tenured); data->reset_generation(data->tenured);
} }
void factor_vm::init_data_heap(cell young_size, cell aging_size, cell tenured_size, bool secure_gc_) void factor_vm::init_data_heap(cell young_size, cell aging_size, cell tenured_size)
{ {
set_data_heap(new data_heap(young_size,aging_size,tenured_size)); set_data_heap(new data_heap(young_size,aging_size,tenured_size));
secure_gc = secure_gc_;
} }
/* Size of the object pointed to by a tagged pointer */ /* Size of the object pointed to by a tagged pointer */

View File

@ -10,7 +10,7 @@ struct data_heap {
segment *seg; segment *seg;
zone *nursery; bump_allocator *nursery;
aging_space *aging; aging_space *aging;
aging_space *aging_semispace; aging_space *aging_semispace;
tenured_space *tenured; tenured_space *tenured;

View File

@ -209,7 +209,7 @@ void factor_vm::dump_memory(cell from, cell to)
dump_cell(from); dump_cell(from);
} }
void factor_vm::dump_zone(const char *name, zone *z) void factor_vm::dump_zone(const char *name, bump_allocator *z)
{ {
print_string(name); print_string(": "); print_string(name); print_string(": ");
print_string("Start="); print_cell(z->start); print_string("Start="); print_cell(z->start);
@ -296,7 +296,7 @@ struct code_block_printer {
const char *status; const char *status;
if(scan->free_p()) if(scan->free_p())
status = "free"; status = "free";
else if(parent->code->state->is_marked_p(scan)) else if(parent->code->marked_p(scan))
{ {
reloc_size += parent->object_size(((code_block *)scan)->relocation); reloc_size += parent->object_size(((code_block *)scan)->relocation);
literal_size += parent->object_size(((code_block *)scan)->literals); literal_size += parent->object_size(((code_block *)scan)->literals);
@ -319,7 +319,7 @@ struct code_block_printer {
void factor_vm::dump_code_heap() void factor_vm::dump_code_heap()
{ {
code_block_printer printer(this); code_block_printer printer(this);
code->iterate_heap(printer); code->allocator->iterate(printer);
print_cell(printer.reloc_size); print_string(" bytes of relocation data\n"); print_cell(printer.reloc_size); print_string(" bytes of relocation data\n");
print_cell(printer.literal_size); print_string(" bytes of literal data\n"); print_cell(printer.literal_size); print_string(" bytes of literal data\n");
} }

View File

@ -37,7 +37,6 @@ void factor_vm::default_parameters(vm_parameters *p)
p->max_pic_size = 3; p->max_pic_size = 3;
p->secure_gc = false;
p->fep = false; p->fep = false;
p->signals = true; p->signals = true;
@ -85,7 +84,6 @@ void factor_vm::init_parameters_from_args(vm_parameters *p, int argc, vm_char **
else if(factor_arg(arg,STRING_LITERAL("-codeheap=%d"),&p->code_size)); else if(factor_arg(arg,STRING_LITERAL("-codeheap=%d"),&p->code_size));
else if(factor_arg(arg,STRING_LITERAL("-pic=%d"),&p->max_pic_size)); else if(factor_arg(arg,STRING_LITERAL("-pic=%d"),&p->max_pic_size));
else if(factor_arg(arg,STRING_LITERAL("-callbacks=%d"),&p->callback_size)); else if(factor_arg(arg,STRING_LITERAL("-callbacks=%d"),&p->callback_size));
else if(STRCMP(arg,STRING_LITERAL("-securegc")) == 0) p->secure_gc = true;
else if(STRCMP(arg,STRING_LITERAL("-fep")) == 0) p->fep = true; else if(STRCMP(arg,STRING_LITERAL("-fep")) == 0) p->fep = true;
else if(STRCMP(arg,STRING_LITERAL("-nosignals")) == 0) p->signals = false; else if(STRCMP(arg,STRING_LITERAL("-nosignals")) == 0) p->signals = false;
else if(STRNCMP(arg,STRING_LITERAL("-i="),3) == 0) p->image_path = arg + 3; else if(STRNCMP(arg,STRING_LITERAL("-i="),3) == 0) p->image_path = arg + 3;

View File

@ -3,28 +3,28 @@ namespace factor
static const cell free_list_count = 32; static const cell free_list_count = 32;
struct heap_free_list { struct free_list {
free_heap_block *small_blocks[free_list_count]; free_heap_block *small_blocks[free_list_count];
free_heap_block *large_blocks; free_heap_block *large_blocks;
}; };
template<typename Block> struct heap { template<typename Block> struct free_list_allocator {
bool secure_gc; cell start;
segment *seg; cell size;
heap_free_list free; cell end;
mark_bits<Block> *state; free_list free_blocks;
mark_bits<Block> state;
explicit heap(bool secure_gc_, cell size, bool executable_p); explicit free_list_allocator(cell start, cell size);
~heap();
inline Block *first_block() inline Block *first_block()
{ {
return (Block *)seg->start; return (Block *)start;
} }
inline Block *last_block() inline Block *last_block()
{ {
return (Block *)seg->end; return (Block *)end;
} }
Block *next_block_after(heap_block *block) Block *next_block_after(heap_block *block)
@ -38,16 +38,15 @@ template<typename Block> struct heap {
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);
Block *heap_allot(cell size); Block *allot(cell size);
void heap_free(Block *block); void free(Block *block);
void mark_block(Block *block); void usage(cell *used, cell *total_free, cell *max_free);
void heap_usage(cell *used, cell *total_free, cell *max_free); cell occupied();
cell heap_size();
template<typename Iterator> void sweep_heap(Iterator &iter); template<typename Iterator> void sweep(Iterator &iter);
template<typename Iterator> void compact_heap(Iterator &iter); template<typename Iterator> void compact(Iterator &iter);
template<typename Iterator> void iterate_heap(Iterator &iter) template<typename Iterator> void iterate(Iterator &iter)
{ {
Block *scan = first_block(); Block *scan = first_block();
Block *end = last_block(); Block *end = last_block();
@ -62,73 +61,63 @@ template<typename Block> struct heap {
} }
}; };
template<typename Block> void heap<Block>::clear_free_list() template<typename Block> void free_list_allocator<Block>::clear_free_list()
{ {
memset(&free,0,sizeof(heap_free_list)); memset(&free_blocks,0,sizeof(free_list));
} }
template<typename Block> heap<Block>::heap(bool secure_gc_, cell size, bool executable_p) : secure_gc(secure_gc_) template<typename Block>
free_list_allocator<Block>::free_list_allocator(cell start_, cell size_) :
start(start_), size(size_), end(start_ + size_), state(mark_bits<Block>(start_,size_))
{ {
if(size > (1L << (sizeof(cell) * 8 - 6))) fatal_error("Heap too large",size);
seg = new segment(align_page(size),executable_p);
if(!seg) fatal_error("Out of memory in heap allocator",size);
state = new mark_bits<Block>(seg->start,size);
clear_free_list(); clear_free_list();
} }
template<typename Block> heap<Block>::~heap() template<typename Block> void free_list_allocator<Block>::add_to_free_list(free_heap_block *block)
{
delete seg;
seg = NULL;
delete state;
state = NULL;
}
template<typename Block> void heap<Block>::add_to_free_list(free_heap_block *block)
{ {
if(block->size() < free_list_count * block_granularity) if(block->size() < free_list_count * block_granularity)
{ {
int index = block->size() / block_granularity; int index = block->size() / block_granularity;
block->next_free = free.small_blocks[index]; block->next_free = free_blocks.small_blocks[index];
free.small_blocks[index] = block; free_blocks.small_blocks[index] = block;
} }
else else
{ {
block->next_free = free.large_blocks; block->next_free = free_blocks.large_blocks;
free.large_blocks = block; free_blocks.large_blocks = block;
} }
} }
/* Called after reading the code heap from the image file, and after code heap /* Called after reading the heap from the image file, and after heap compaction.
compaction. Makes a free list consisting of one free block, at the very end. */ Makes a free list consisting of one free block, at the very end. */
template<typename Block> void heap<Block>::build_free_list(cell size) template<typename Block> void free_list_allocator<Block>::build_free_list(cell size)
{ {
clear_free_list(); clear_free_list();
free_heap_block *end = (free_heap_block *)(seg->start + size); free_heap_block *last_block = (free_heap_block *)(start + size);
end->set_free(); last_block->set_free();
end->set_size(seg->end - (cell)end); last_block->set_size(end - (cell)last_block);
add_to_free_list(end); add_to_free_list(last_block);
} }
template<typename Block> void heap<Block>::assert_free_block(free_heap_block *block) template<typename Block> void free_list_allocator<Block>::assert_free_block(free_heap_block *block)
{ {
#ifdef FACTOR_DEBUG #ifdef FACTOR_DEBUG
assert(block->free_p()); assert(block->free_p());
#endif #endif
} }
template<typename Block> free_heap_block *heap<Block>::find_free_block(cell size) template<typename Block> free_heap_block *free_list_allocator<Block>::find_free_block(cell size)
{ {
cell attempt = size; cell attempt = size;
while(attempt < free_list_count * block_granularity) while(attempt < free_list_count * block_granularity)
{ {
int index = attempt / block_granularity; int index = attempt / block_granularity;
free_heap_block *block = free.small_blocks[index]; free_heap_block *block = free_blocks.small_blocks[index];
if(block) if(block)
{ {
assert_free_block(block); assert_free_block(block);
free.small_blocks[index] = block->next_free; free_blocks.small_blocks[index] = block->next_free;
return block; return block;
} }
@ -136,7 +125,7 @@ template<typename Block> free_heap_block *heap<Block>::find_free_block(cell size
} }
free_heap_block *prev = NULL; free_heap_block *prev = NULL;
free_heap_block *block = free.large_blocks; free_heap_block *block = free_blocks.large_blocks;
while(block) while(block)
{ {
@ -146,7 +135,7 @@ template<typename Block> free_heap_block *heap<Block>::find_free_block(cell size
if(prev) if(prev)
prev->next_free = block->next_free; prev->next_free = block->next_free;
else else
free.large_blocks = block->next_free; free_blocks.large_blocks = block->next_free;
return block; return block;
} }
@ -157,7 +146,7 @@ template<typename Block> free_heap_block *heap<Block>::find_free_block(cell size
return NULL; return NULL;
} }
template<typename Block> free_heap_block *heap<Block>::split_free_block(free_heap_block *block, cell size) template<typename Block> free_heap_block *free_list_allocator<Block>::split_free_block(free_heap_block *block, cell size)
{ {
if(block->size() != size) if(block->size() != size)
{ {
@ -173,7 +162,7 @@ template<typename Block> free_heap_block *heap<Block>::split_free_block(free_hea
return block; return block;
} }
template<typename Block> Block *heap<Block>::heap_allot(cell size) template<typename Block> Block *free_list_allocator<Block>::allot(cell size)
{ {
size = align(size,block_granularity); size = align(size,block_granularity);
@ -187,20 +176,15 @@ template<typename Block> Block *heap<Block>::heap_allot(cell size)
return NULL; return NULL;
} }
template<typename Block> void heap<Block>::heap_free(Block *block) template<typename Block> void free_list_allocator<Block>::free(Block *block)
{ {
free_heap_block *free_block = (free_heap_block *)block; free_heap_block *free_block = (free_heap_block *)block;
free_block->set_free(); free_block->set_free();
add_to_free_list(free_block); add_to_free_list(free_block);
} }
template<typename Block> void heap<Block>::mark_block(Block *block)
{
state->set_marked_p(block);
}
/* Compute total sum of sizes of free blocks, and size of largest free block */ /* Compute total sum of sizes of free blocks, and size of largest free block */
template<typename Block> void heap<Block>::heap_usage(cell *used, cell *total_free, cell *max_free) template<typename Block> void free_list_allocator<Block>::usage(cell *used, cell *total_free, cell *max_free)
{ {
*used = 0; *used = 0;
*total_free = 0; *total_free = 0;
@ -227,34 +211,34 @@ template<typename Block> void heap<Block>::heap_usage(cell *used, cell *total_fr
} }
/* The size of the heap after compaction */ /* The size of the heap after compaction */
template<typename Block> cell heap<Block>::heap_size() template<typename Block> cell free_list_allocator<Block>::occupied()
{ {
Block *scan = first_block(); Block *scan = first_block();
Block *end = last_block(); Block *last = last_block();
while(scan != end) while(scan != last)
{ {
if(scan->free_p()) break; if(scan->free_p()) break;
else scan = next_block_after(scan); else scan = next_block_after(scan);
} }
if(scan != end) if(scan != last)
{ {
free_heap_block *free_block = (free_heap_block *)scan; free_heap_block *free_block = (free_heap_block *)scan;
assert(free_block->free_p()); assert(free_block->free_p());
assert((cell)scan + free_block->size() == seg->end); assert((cell)scan + free_block->size() == end);
return (cell)scan - (cell)first_block(); return (cell)scan - (cell)first_block();
} }
else else
return seg->size; return size;
} }
/* After code GC, all live code blocks are marked, so any /* After code GC, all live code blocks are marked, so any
which are not marked can be reclaimed. */ which are not marked can be reclaimed. */
template<typename Block> template<typename Block>
template<typename Iterator> template<typename Iterator>
void heap<Block>::sweep_heap(Iterator &iter) void free_list_allocator<Block>::sweep(Iterator &iter)
{ {
this->clear_free_list(); this->clear_free_list();
@ -276,7 +260,7 @@ void heap<Block>::sweep_heap(Iterator &iter)
else else
prev = scan; prev = scan;
} }
else if(this->state->is_marked_p(scan)) else if(this->state.marked_p(scan))
{ {
if(prev && prev->free_p()) if(prev && prev->free_p())
this->add_to_free_list((free_heap_block *)prev); this->add_to_free_list((free_heap_block *)prev);
@ -305,17 +289,17 @@ void heap<Block>::sweep_heap(Iterator &iter)
} }
/* The forwarding map must be computed first by calling /* The forwarding map must be computed first by calling
state->compute_forwarding(). */ state.compute_forwarding(). */
template<typename Block> template<typename Block>
template<typename Iterator> template<typename Iterator>
void heap<Block>::compact_heap(Iterator &iter) void free_list_allocator<Block>::compact(Iterator &iter)
{ {
heap_compactor<Block,Iterator> compactor(state,first_block(),iter); heap_compactor<Block,Iterator> compactor(&state,first_block(),iter);
this->iterate_heap(compactor); this->iterate(compactor);
/* Now update the free list; there will be a single free block at /* Now update the free list; there will be a single free block at
the end */ the end */
this->build_free_list((cell)compactor.address - this->seg->start); this->build_free_list((cell)compactor.address - this->start);
} }
} }

View File

@ -89,7 +89,7 @@ void full_collector::trace_literal_references(code_block *compiled)
collections */ collections */
void full_collector::mark_code_block(code_block *compiled) void full_collector::mark_code_block(code_block *compiled)
{ {
this->code->mark_block(compiled); this->code->set_marked_p(compiled);
trace_literal_references(compiled); trace_literal_references(compiled);
} }
@ -108,7 +108,7 @@ void factor_vm::collect_full_impl(bool trace_contexts_p)
{ {
full_collector collector(this); full_collector collector(this);
code->state->clear_mark_bits(); code->clear_mark_bits();
collector.trace_roots(); collector.trace_roots();
if(trace_contexts_p) if(trace_contexts_p)

View File

@ -3,7 +3,7 @@ namespace factor
struct full_policy { struct full_policy {
factor_vm *parent; factor_vm *parent;
zone *tenured; tenured_space *tenured;
full_policy(factor_vm *parent_) : parent(parent_), tenured(parent->data->tenured) {} full_policy(factor_vm *parent_) : parent(parent_), tenured(parent->data->tenured) {}

View File

@ -23,8 +23,7 @@ void factor_vm::load_data_heap(FILE *file, image_header *h, vm_parameters *p)
init_data_heap(p->young_size, init_data_heap(p->young_size,
p->aging_size, p->aging_size,
p->tenured_size, p->tenured_size);
p->secure_gc);
clear_gc_stats(); clear_gc_stats();
@ -52,7 +51,7 @@ void factor_vm::load_code_heap(FILE *file, image_header *h, vm_parameters *p)
if(h->code_size != 0) if(h->code_size != 0)
{ {
size_t bytes_read = fread(code->first_block(),1,h->code_size,file); size_t bytes_read = fread(code->allocator->first_block(),1,h->code_size,file);
if(bytes_read != h->code_size) if(bytes_read != h->code_size)
{ {
print_string("truncated image: "); print_string("truncated image: ");
@ -64,7 +63,7 @@ void factor_vm::load_code_heap(FILE *file, image_header *h, vm_parameters *p)
} }
} }
code->build_free_list(h->code_size); code->allocator->build_free_list(h->code_size);
} }
void factor_vm::data_fixup(cell *handle, cell data_relocation_base) void factor_vm::data_fixup(cell *handle, cell data_relocation_base)
@ -292,7 +291,7 @@ bool factor_vm::save_image(const vm_char *filename)
h.data_relocation_base = data->tenured->start; h.data_relocation_base = data->tenured->start;
h.data_size = data->tenured->here - data->tenured->start; h.data_size = data->tenured->here - data->tenured->start;
h.code_relocation_base = code->seg->start; h.code_relocation_base = code->seg->start;
h.code_size = code->heap_size(); h.code_size = code->allocator->occupied();
h.true_object = true_object; h.true_object = true_object;
h.bignum_zero = bignum_zero; h.bignum_zero = bignum_zero;
@ -306,7 +305,7 @@ bool factor_vm::save_image(const vm_char *filename)
if(fwrite(&h,sizeof(image_header),1,file) != 1) ok = false; if(fwrite(&h,sizeof(image_header),1,file) != 1) ok = false;
if(fwrite((void*)data->tenured->start,h.data_size,1,file) != 1) ok = false; if(fwrite((void*)data->tenured->start,h.data_size,1,file) != 1) ok = false;
if(fwrite(code->first_block(),h.code_size,1,file) != 1) ok = false; if(fwrite(code->allocator->first_block(),h.code_size,1,file) != 1) ok = false;
if(fclose(file)) ok = false; if(fclose(file)) ok = false;
if(!ok) if(!ok)

View File

@ -34,7 +34,6 @@ struct vm_parameters {
cell ds_size, rs_size; cell ds_size, rs_size;
cell young_size, aging_size, tenured_size; cell young_size, aging_size, tenured_size;
cell code_size; cell code_size;
bool secure_gc;
bool fep; bool fep;
bool console; bool console;
bool signals; bool signals;

View File

@ -95,7 +95,7 @@ template<typename Block> struct mark_bits {
} }
} }
bool is_marked_p(Block *address) bool marked_p(Block *address)
{ {
return bitmap_elt(marked,address); return bitmap_elt(marked,address);
} }
@ -155,7 +155,7 @@ template<typename Block, typename Iterator> struct heap_compactor {
void operator()(Block *block, cell size) void operator()(Block *block, cell size)
{ {
if(this->state->is_marked_p(block)) if(this->state->marked_p(block))
{ {
memmove(address,block,size); memmove(address,block,size);
iter((Block *)address,size); iter((Block *)address,size);

View File

@ -48,9 +48,11 @@ namespace factor
#include "bignumint.hpp" #include "bignumint.hpp"
#include "bignum.hpp" #include "bignum.hpp"
#include "code_block.hpp" #include "code_block.hpp"
#include "zone.hpp" #include "bump_allocator.hpp"
#include "mark_bits.hpp"
#include "free_list_allocator.hpp"
#include "write_barrier.hpp" #include "write_barrier.hpp"
#include "old_space.hpp" #include "object_start_map.hpp"
#include "aging_space.hpp" #include "aging_space.hpp"
#include "tenured_space.hpp" #include "tenured_space.hpp"
#include "data_heap.hpp" #include "data_heap.hpp"
@ -61,8 +63,6 @@ namespace factor
#include "words.hpp" #include "words.hpp"
#include "float_bits.hpp" #include "float_bits.hpp"
#include "io.hpp" #include "io.hpp"
#include "mark_bits.hpp"
#include "heap.hpp"
#include "image.hpp" #include "image.hpp"
#include "alien.hpp" #include "alien.hpp"
#include "code_heap.hpp" #include "code_heap.hpp"

View File

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

View File

@ -3,7 +3,7 @@ namespace factor
struct to_tenured_policy { struct to_tenured_policy {
factor_vm *myvm; factor_vm *myvm;
zone *tenured; tenured_space *tenured;
to_tenured_policy(factor_vm *myvm_) : myvm(myvm_), tenured(myvm->data->tenured) {} to_tenured_policy(factor_vm *myvm_) : myvm(myvm_), tenured(myvm->data->tenured) {}

View File

@ -6,7 +6,6 @@ namespace factor
factor_vm::factor_vm() : factor_vm::factor_vm() :
nursery(0,0), nursery(0,0),
profiling_p(false), profiling_p(false),
secure_gc(false),
gc_off(false), gc_off(false),
current_gc(NULL), current_gc(NULL),
fep_disabled(false), fep_disabled(false),

View File

@ -11,7 +11,7 @@ struct factor_vm
context *ctx; context *ctx;
/* New objects are allocated here */ /* New objects are allocated here */
zone nursery; bump_allocator nursery;
/* Add this to a shifted address to compute write barrier offsets */ /* Add this to a shifted address to compute write barrier offsets */
cell cards_offset; cell cards_offset;
@ -39,9 +39,6 @@ struct factor_vm
unsigned int signal_fpu_status; unsigned int signal_fpu_status;
stack_frame *signal_callstack_top; stack_frame *signal_callstack_top;
/* Zeroes out deallocated memory; set by the -securegc command line argument */
bool secure_gc;
/* A heap walk allows useful things to be done, like finding all /* A heap walk allows useful things to be done, like finding all
references to an object for debugging purposes. */ references to an object for debugging purposes. */
cell heap_scan_ptr; cell heap_scan_ptr;
@ -221,7 +218,7 @@ struct factor_vm
//data heap //data heap
void init_card_decks(); void init_card_decks();
void set_data_heap(data_heap *data_); void set_data_heap(data_heap *data_);
void init_data_heap(cell young_size, cell aging_size, cell tenured_size, bool secure_gc_); void init_data_heap(cell young_size, cell aging_size, cell tenured_size);
void primitive_size(); void primitive_size();
cell binary_payload_start(object *pointer); cell binary_payload_start(object *pointer);
void primitive_data_room(); void primitive_data_room();
@ -311,7 +308,7 @@ struct factor_vm
void print_callstack(); void print_callstack();
void dump_cell(cell x); void dump_cell(cell x);
void dump_memory(cell from, cell to); void dump_memory(cell from, cell to);
void dump_zone(const char *name, zone *z); void dump_zone(const char *name, bump_allocator *z);
void dump_generations(); void dump_generations();
void dump_objects(cell type); void dump_objects(cell type);
void find_data_references_step(cell *scan); void find_data_references_step(cell *scan);
@ -531,7 +528,7 @@ struct factor_vm
template<typename Iterator> void iterate_code_heap(Iterator &iter_) template<typename Iterator> void iterate_code_heap(Iterator &iter_)
{ {
code_heap_iterator<Iterator> iter(iter_); code_heap_iterator<Iterator> iter(iter_);
code->iterate_heap(iter); code->allocator->iterate(iter);
} }
//callbacks //callbacks