vm: simpler and more efficient code heap compaction; restructure a few things to get ready for runtime code heap compaction

db4
Slava Pestov 2009-10-16 04:33:35 -05:00
parent 349cb41a29
commit 85b746e7b5
17 changed files with 264 additions and 389 deletions

View File

@ -23,8 +23,11 @@ template<typename Iterator> void factor_vm::iterate_callstack_object(callstack *
} }
} }
template<typename Iterator> void factor_vm::iterate_callstack(cell top, cell bottom, Iterator &iterator) template<typename Iterator> void factor_vm::iterate_callstack(context *ctx, Iterator &iterator)
{ {
cell top = (cell)ctx->callstack_top;
cell bottom = (cell)ctx->callstack_bottom;
stack_frame *frame = (stack_frame *)bottom - 1; stack_frame *frame = (stack_frame *)bottom - 1;
while((cell)frame >= top) while((cell)frame >= top)

View File

@ -444,7 +444,7 @@ code_block *factor_vm::allot_code_block(cell size, cell type)
/* If allocation failed, do a code GC */ /* If allocation failed, do a code GC */
if(block == NULL) if(block == NULL)
{ {
gc(); primitive_full_gc();
block = code->heap_allot(size + sizeof(code_block),type); block = code->heap_allot(size + sizeof(code_block),type);
/* Insufficient room even after code GC, give up */ /* Insufficient room even after code GC, give up */

View File

@ -137,22 +137,24 @@ void factor_vm::primitive_code_room()
dpush(tag_fixnum(max_free / 1024)); dpush(tag_fixnum(max_free / 1024));
} }
code_block *factor_vm::forward_xt(code_block *compiled) code_block *code_heap::forward_code_block(code_block *compiled)
{ {
return (code_block *)code->forwarding[compiled]; return (code_block *)forwarding[compiled];
} }
struct xt_forwarder { struct callframe_forwarder {
factor_vm *myvm; factor_vm *myvm;
explicit xt_forwarder(factor_vm *myvm_) : myvm(myvm_) {} explicit callframe_forwarder(factor_vm *myvm_) : myvm(myvm_) {}
void operator()(stack_frame *frame) void operator()(stack_frame *frame)
{ {
cell offset = (cell)FRAME_RETURN_ADDRESS(frame,myvm) - (cell)myvm->frame_code(frame); cell offset = (cell)FRAME_RETURN_ADDRESS(frame,myvm) - (cell)frame->xt;
code_block *forwarded = myvm->forward_xt(myvm->frame_code(frame));
code_block *forwarded = myvm->code->forward_code_block(myvm->frame_code(frame));
frame->xt = forwarded->xt(); frame->xt = forwarded->xt();
FRAME_RETURN_ADDRESS(frame,myvm) = (void *)((cell)forwarded + offset);
FRAME_RETURN_ADDRESS(frame,myvm) = (void *)((cell)frame->xt + offset);
} }
}; };
@ -171,9 +173,11 @@ void factor_vm::forward_object_xts()
word *w = untag<word>(obj); word *w = untag<word>(obj);
if(w->code) if(w->code)
w->code = forward_xt(w->code); w->code = code->forward_code_block(w->code);
if(w->profiling) if(w->profiling)
w->profiling = forward_xt(w->profiling); w->profiling = code->forward_code_block(w->profiling);
update_word_xt(obj);
} }
break; break;
case QUOTATION_TYPE: case QUOTATION_TYPE:
@ -181,13 +185,16 @@ void factor_vm::forward_object_xts()
quotation *quot = untag<quotation>(obj); quotation *quot = untag<quotation>(obj);
if(quot->code) if(quot->code)
quot->code = forward_xt(quot->code); {
quot->code = code->forward_code_block(quot->code);
set_quot_xt(quot,quot->code);
}
} }
break; break;
case CALLSTACK_TYPE: case CALLSTACK_TYPE:
{ {
callstack *stack = untag<callstack>(obj); callstack *stack = untag<callstack>(obj);
xt_forwarder forwarder(this); callframe_forwarder forwarder(this);
iterate_callstack_object(stack,forwarder); iterate_callstack_object(stack,forwarder);
} }
break; break;
@ -199,59 +206,26 @@ void factor_vm::forward_object_xts()
end_scan(); end_scan();
} }
/* Set the XT fields now that the heap has been compacted */ void factor_vm::forward_context_xts()
void factor_vm::fixup_object_xts()
{ {
begin_scan(); context *ctx = stack_chain;
cell obj; while(ctx)
while((obj = next_object()) != F)
{ {
switch(tagged<object>(obj).type()) callframe_forwarder forwarder(this);
{ iterate_callstack(ctx,forwarder);
case WORD_TYPE: ctx = ctx->next;
update_word_xt(obj);
break;
case QUOTATION_TYPE:
{
quotation *quot = untag<quotation>(obj);
if(quot->code)
set_quot_xt(quot,quot->code);
break;
}
default:
break;
} }
} }
end_scan(); /* Move all free space to the end of the code heap. Live blocks must be marked
} on entry to this function. XTs in code blocks must be updated after this
function returns. */
/* Move all free space to the end of the code heap. This is not very efficient, void factor_vm::compact_code_heap(bool trace_contexts_p)
since it makes several passes over the code and data heaps, but we only ever
do this before saving a deployed image and exiting, so performance is not
critical here */
void factor_vm::compact_code_heap()
{ {
/* Free all unreachable code blocks, don't trace contexts */
garbage_collection(collect_full_op,false,0);
/* Figure out where the code heap blocks are going to end up */
cell size = code->compute_heap_forwarding();
/* Update word and quotation code pointers */
forward_object_xts();
/* Actually perform the compaction */
code->compact_heap(); code->compact_heap();
forward_object_xts();
/* Update word and quotation XTs */ if(trace_contexts_p) forward_context_xts();
fixup_object_xts();
/* Now update the free list; there will be a single free block at
the end */
code->build_free_list(size);
} }
struct stack_trace_stripper { struct stack_trace_stripper {

View File

@ -16,6 +16,7 @@ struct code_heap : heap {
void clear_remembered_set(); void clear_remembered_set();
bool needs_fixup_p(code_block *compiled); bool needs_fixup_p(code_block *compiled);
void code_heap_free(code_block *compiled); void code_heap_free(code_block *compiled);
code_block *forward_code_block(code_block *compiled);
}; };
} }

View File

@ -132,17 +132,17 @@ template<typename TargetGeneration, typename Policy> struct collector {
void trace_contexts() void trace_contexts()
{ {
context *stacks = myvm->stack_chain; context *ctx = myvm->stack_chain;
while(stacks) while(ctx)
{ {
trace_stack_elements(stacks->datastack_region,(cell *)stacks->datastack); trace_stack_elements(ctx->datastack_region,(cell *)ctx->datastack);
trace_stack_elements(stacks->retainstack_region,(cell *)stacks->retainstack); trace_stack_elements(ctx->retainstack_region,(cell *)ctx->retainstack);
trace_handle(&stacks->catchstack_save); trace_handle(&ctx->catchstack_save);
trace_handle(&stacks->current_callback_save); trace_handle(&ctx->current_callback_save);
stacks = stacks->next; ctx = ctx->next;
} }
} }
}; };

View File

@ -104,9 +104,9 @@ void factor_vm::unnest_stacks()
userenv[CURRENT_CALLBACK_ENV] = stack_chain->current_callback_save; userenv[CURRENT_CALLBACK_ENV] = stack_chain->current_callback_save;
userenv[CATCHSTACK_ENV] = stack_chain->catchstack_save; userenv[CATCHSTACK_ENV] = stack_chain->catchstack_save;
context *old_stacks = stack_chain; context *old_ctx = stack_chain;
stack_chain = old_stacks->next; stack_chain = old_ctx->next;
dealloc_context(old_stacks); dealloc_context(old_ctx);
} }
void unnest_stacks(factor_vm *myvm) void unnest_stacks(factor_vm *myvm)

View File

@ -189,10 +189,8 @@ struct stack_frame_printer {
void factor_vm::print_callstack() void factor_vm::print_callstack()
{ {
print_string("==== CALL STACK:\n"); print_string("==== CALL STACK:\n");
cell bottom = (cell)stack_chain->callstack_bottom;
cell top = (cell)stack_chain->callstack_top;
stack_frame_printer printer(this); stack_frame_printer printer(this);
iterate_callstack(top,bottom,printer); iterate_callstack(stack_chain,printer);
} }
void factor_vm::dump_cell(cell x) void factor_vm::dump_cell(cell x)
@ -234,7 +232,7 @@ void factor_vm::dump_generations()
void factor_vm::dump_objects(cell type) void factor_vm::dump_objects(cell type)
{ {
gc(); primitive_full_gc();
begin_scan(); begin_scan();
cell obj; cell obj;

View File

@ -26,17 +26,13 @@ struct stack_frame_marker {
/* Mark code blocks executing in currently active stack frames. */ /* Mark code blocks executing in currently active stack frames. */
void full_collector::mark_active_blocks() void full_collector::mark_active_blocks()
{ {
context *stacks = this->myvm->stack_chain; context *ctx = this->myvm->stack_chain;
while(stacks) while(ctx)
{ {
cell top = (cell)stacks->callstack_top;
cell bottom = (cell)stacks->callstack_bottom;
stack_frame_marker marker(this); stack_frame_marker marker(this);
myvm->iterate_callstack(top,bottom,marker); myvm->iterate_callstack(ctx,marker);
ctx = ctx->next;
stacks = stacks->next;
} }
} }
@ -140,7 +136,12 @@ void factor_vm::collect_full_impl(bool trace_contexts_p)
nursery.here = nursery.start; nursery.here = nursery.start;
} }
void factor_vm::collect_growing_heap(cell requested_bytes, bool trace_contexts_p) /* In both cases, compact code heap before updating code blocks so that
XTs are correct after */
void factor_vm::collect_growing_heap(cell requested_bytes,
bool trace_contexts_p,
bool compact_code_heap_p)
{ {
/* Grow the data heap and copy all live objects to the new heap. */ /* Grow the data heap and copy all live objects to the new heap. */
data_heap *old = data; data_heap *old = data;
@ -148,18 +149,22 @@ void factor_vm::collect_growing_heap(cell requested_bytes, bool trace_contexts_p
collect_full_impl(trace_contexts_p); collect_full_impl(trace_contexts_p);
delete old; delete old;
if(compact_code_heap_p) compact_code_heap(trace_contexts_p);
after_growing_heap_updater updater(this); after_growing_heap_updater updater(this);
code->free_unmarked(updater); code->free_unmarked(updater);
code->clear_remembered_set(); code->clear_remembered_set();
} }
void factor_vm::collect_full(bool trace_contexts_p) void factor_vm::collect_full(bool trace_contexts_p, bool compact_code_heap_p)
{ {
/* Copy all live objects to the tenured semispace. */ /* Copy all live objects to the tenured semispace. */
std::swap(data->tenured,data->tenured_semispace); std::swap(data->tenured,data->tenured_semispace);
reset_generation(data->tenured); reset_generation(data->tenured);
collect_full_impl(trace_contexts_p); collect_full_impl(trace_contexts_p);
if(compact_code_heap_p) compact_code_heap(trace_contexts_p);
after_full_updater updater(this); after_full_updater updater(this);
code->free_unmarked(updater); code->free_unmarked(updater);
code->clear_remembered_set(); code->clear_remembered_set();

View File

@ -25,10 +25,10 @@ void factor_vm::record_gc_stats(generation_statistics *stats)
stats->max_gc_time = gc_elapsed; stats->max_gc_time = gc_elapsed;
} }
/* Collect gen and all younger generations. void factor_vm::gc(gc_op op,
If growing_data_heap_ is true, we must grow the data heap to such a size that cell requested_bytes,
an allocation of requested_bytes won't fail */ bool trace_contexts_p,
void factor_vm::garbage_collection(gc_op op, bool trace_contexts_p, cell requested_bytes) bool compact_code_heap_p)
{ {
assert(!gc_off); assert(!gc_off);
assert(!current_gc); assert(!current_gc);
@ -80,11 +80,11 @@ void factor_vm::garbage_collection(gc_op op, bool trace_contexts_p, cell request
record_gc_stats(&gc_stats.aging_stats); record_gc_stats(&gc_stats.aging_stats);
break; break;
case collect_full_op: case collect_full_op:
collect_full(trace_contexts_p); collect_full(trace_contexts_p,compact_code_heap_p);
record_gc_stats(&gc_stats.full_stats); record_gc_stats(&gc_stats.full_stats);
break; break;
case collect_growing_heap_op: case collect_growing_heap_op:
collect_growing_heap(requested_bytes,trace_contexts_p); collect_growing_heap(requested_bytes,trace_contexts_p,compact_code_heap_p);
record_gc_stats(&gc_stats.full_stats); record_gc_stats(&gc_stats.full_stats);
break; break;
default: default:
@ -96,14 +96,28 @@ void factor_vm::garbage_collection(gc_op op, bool trace_contexts_p, cell request
current_gc = NULL; current_gc = NULL;
} }
void factor_vm::gc() void factor_vm::primitive_full_gc()
{ {
garbage_collection(collect_full_op,true,0); gc(collect_full_op,
0, /* requested size */
true, /* trace contexts? */
false /* compact code heap? */);
} }
void factor_vm::primitive_gc() void factor_vm::primitive_minor_gc()
{ {
gc(); gc(collect_nursery_op,
0, /* requested size */
true, /* trace contexts? */
false /* compact code heap? */);
}
void factor_vm::primitive_compact_gc()
{
gc(collect_full_op,
0, /* requested size */
true, /* trace contexts? */
true /* compact code heap? */);
} }
void factor_vm::add_gc_stats(generation_statistics *stats, growable_array *result) void factor_vm::add_gc_stats(generation_statistics *stats, growable_array *result)
@ -171,7 +185,7 @@ void factor_vm::primitive_become()
old_obj->h.forward_to(new_obj.untagged()); old_obj->h.forward_to(new_obj.untagged());
} }
gc(); primitive_full_gc();
/* If a word's definition quotation was in old_objects and the /* If a word's definition quotation was in old_objects and the
quotation in new_objects is not compiled, we might leak memory quotation in new_objects is not compiled, we might leak memory
@ -185,7 +199,7 @@ void factor_vm::inline_gc(cell *gc_roots_base, cell gc_roots_size)
for(cell i = 0; i < gc_roots_size; i++) for(cell i = 0; i < gc_roots_size; i++)
gc_locals.push_back((cell)&gc_roots_base[i]); gc_locals.push_back((cell)&gc_roots_base[i]);
garbage_collection(collect_nursery_op,true,0); primitive_minor_gc();
for(cell i = 0; i < gc_roots_size; i++) for(cell i = 0; i < gc_roots_size; i++)
gc_locals.pop_back(); gc_locals.pop_back();
@ -204,16 +218,18 @@ object *factor_vm::allot_object(header header, cell size)
{ {
#ifdef GC_DEBUG #ifdef GC_DEBUG
if(!gc_off) if(!gc_off)
gc(); primitive_full_gc();
#endif #endif
object *obj; object *obj;
/* If the object is smaller than the nursery, allocate it in the nursery,
after a GC if needed */
if(nursery.size > size) if(nursery.size > 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)
garbage_collection(collect_nursery_op,true,0); primitive_minor_gc();
obj = nursery.allot(size); obj = nursery.allot(size);
} }
@ -223,11 +239,16 @@ object *factor_vm::allot_object(header header, cell size)
{ {
/* If tenured space does not have enough room, collect */ /* If tenured space does not have enough room, collect */
if(data->tenured->here + size > data->tenured->end) if(data->tenured->here + size > data->tenured->end)
gc(); primitive_full_gc();
/* If it still won't fit, grow the heap */ /* If it still won't fit, grow the heap */
if(data->tenured->here + size > data->tenured->end) if(data->tenured->here + size > data->tenured->end)
garbage_collection(collect_growing_heap_op,true,size); {
gc(collect_growing_heap_op,
size, /* requested size */
true, /* trace contexts? */
false /* compact code heap? */);
}
obj = data->tenured->allot(size); obj = data->tenured->allot(size);

View File

@ -226,37 +226,32 @@ cell heap::heap_size()
return seg->size; return seg->size;
} }
/* Compute where each block is going to go, after compaction */
cell heap::compute_heap_forwarding()
{
heap_block *scan = first_block();
char *address = (char *)first_block();
while(scan)
{
if(scan->type() != FREE_BLOCK_TYPE)
{
forwarding[scan] = address;
address += scan->size();
}
scan = next_block(scan);
}
return (cell)address - seg->start;
}
void heap::compact_heap() void heap::compact_heap()
{ {
heap_block *scan = first_block(); forwarding.clear();
heap_block *scan = first_block();
char *address = (char *)scan;
/* Slide blocks up while building the forwarding hashtable. */
while(scan) while(scan)
{ {
heap_block *next = next_block(scan); heap_block *next = next_block(scan);
if(scan->type() != FREE_BLOCK_TYPE) if(scan->type() != FREE_BLOCK_TYPE && scan->marked_p())
memmove(forwarding[scan],scan,scan->size()); {
cell size = scan->size();
memmove(address,scan,size);
forwarding[scan] = address;
address += size;
}
scan = next; scan = next;
} }
/* Now update the free list; there will be a single free block at
the end */
build_free_list((cell)address - seg->start);
} }
heap_block *heap::free_allocated(heap_block *prev, heap_block *scan) heap_block *heap::free_allocated(heap_block *prev, heap_block *scan)

View File

@ -49,7 +49,6 @@ struct heap {
void clear_mark_bits(); void clear_mark_bits();
void heap_usage(cell *used, cell *total_free, cell *max_free); void heap_usage(cell *used, cell *total_free, cell *max_free);
cell heap_size(); cell heap_size();
cell compute_heap_forwarding();
void compact_heap(); void compact_heap();
heap_block *free_allocated(heap_block *prev, heap_block *scan); heap_block *free_allocated(heap_block *prev, heap_block *scan);

View File

@ -114,7 +114,7 @@ bool factor_vm::save_image(const vm_char *filename)
void factor_vm::primitive_save_image() void factor_vm::primitive_save_image()
{ {
/* do a full GC to push everything into tenured space */ /* do a full GC to push everything into tenured space */
gc(); primitive_full_gc();
gc_root<byte_array> path(dpop(),this); gc_root<byte_array> path(dpop(),this);
path.untag_check(this); path.untag_check(this);
@ -135,8 +135,10 @@ void factor_vm::primitive_save_image_and_exit()
if(!save_env_p(i)) userenv[i] = F; if(!save_env_p(i)) userenv[i] = F;
} }
/* do a full GC + code heap compaction */ gc(collect_full_op,
compact_code_heap(); 0, /* requested size */
false, /* discard objects only reachable from stacks */
true /* compact the code heap */);
/* Save the image */ /* Save the image */
if(save_image((vm_char *)(path.untagged() + 1))) if(save_image((vm_char *)(path.untagged() + 1)))

View File

@ -3,6 +3,131 @@
namespace factor namespace factor
{ {
PRIMITIVE_FORWARD(bignum_to_fixnum)
PRIMITIVE_FORWARD(float_to_fixnum)
PRIMITIVE_FORWARD(fixnum_to_bignum)
PRIMITIVE_FORWARD(float_to_bignum)
PRIMITIVE_FORWARD(fixnum_to_float)
PRIMITIVE_FORWARD(bignum_to_float)
PRIMITIVE_FORWARD(str_to_float)
PRIMITIVE_FORWARD(float_to_str)
PRIMITIVE_FORWARD(float_bits)
PRIMITIVE_FORWARD(double_bits)
PRIMITIVE_FORWARD(bits_float)
PRIMITIVE_FORWARD(bits_double)
PRIMITIVE_FORWARD(fixnum_divint)
PRIMITIVE_FORWARD(fixnum_divmod)
PRIMITIVE_FORWARD(fixnum_shift)
PRIMITIVE_FORWARD(bignum_eq)
PRIMITIVE_FORWARD(bignum_add)
PRIMITIVE_FORWARD(bignum_subtract)
PRIMITIVE_FORWARD(bignum_multiply)
PRIMITIVE_FORWARD(bignum_divint)
PRIMITIVE_FORWARD(bignum_mod)
PRIMITIVE_FORWARD(bignum_divmod)
PRIMITIVE_FORWARD(bignum_and)
PRIMITIVE_FORWARD(bignum_or)
PRIMITIVE_FORWARD(bignum_xor)
PRIMITIVE_FORWARD(bignum_not)
PRIMITIVE_FORWARD(bignum_shift)
PRIMITIVE_FORWARD(bignum_less)
PRIMITIVE_FORWARD(bignum_lesseq)
PRIMITIVE_FORWARD(bignum_greater)
PRIMITIVE_FORWARD(bignum_greatereq)
PRIMITIVE_FORWARD(bignum_bitp)
PRIMITIVE_FORWARD(bignum_log2)
PRIMITIVE_FORWARD(byte_array_to_bignum)
PRIMITIVE_FORWARD(float_eq)
PRIMITIVE_FORWARD(float_add)
PRIMITIVE_FORWARD(float_subtract)
PRIMITIVE_FORWARD(float_multiply)
PRIMITIVE_FORWARD(float_divfloat)
PRIMITIVE_FORWARD(float_mod)
PRIMITIVE_FORWARD(float_less)
PRIMITIVE_FORWARD(float_lesseq)
PRIMITIVE_FORWARD(float_greater)
PRIMITIVE_FORWARD(float_greatereq)
PRIMITIVE_FORWARD(word)
PRIMITIVE_FORWARD(word_xt)
PRIMITIVE_FORWARD(getenv)
PRIMITIVE_FORWARD(setenv)
PRIMITIVE_FORWARD(existsp)
PRIMITIVE_FORWARD(full_gc)
PRIMITIVE_FORWARD(gc_stats)
PRIMITIVE_FORWARD(save_image)
PRIMITIVE_FORWARD(save_image_and_exit)
PRIMITIVE_FORWARD(datastack)
PRIMITIVE_FORWARD(retainstack)
PRIMITIVE_FORWARD(callstack)
PRIMITIVE_FORWARD(set_datastack)
PRIMITIVE_FORWARD(set_retainstack)
PRIMITIVE_FORWARD(set_callstack)
PRIMITIVE_FORWARD(exit)
PRIMITIVE_FORWARD(data_room)
PRIMITIVE_FORWARD(code_room)
PRIMITIVE_FORWARD(micros)
PRIMITIVE_FORWARD(modify_code_heap)
PRIMITIVE_FORWARD(dlopen)
PRIMITIVE_FORWARD(dlsym)
PRIMITIVE_FORWARD(dlclose)
PRIMITIVE_FORWARD(byte_array)
PRIMITIVE_FORWARD(uninitialized_byte_array)
PRIMITIVE_FORWARD(displaced_alien)
PRIMITIVE_FORWARD(alien_address)
PRIMITIVE_FORWARD(set_slot)
PRIMITIVE_FORWARD(string_nth)
PRIMITIVE_FORWARD(set_string_nth_fast)
PRIMITIVE_FORWARD(set_string_nth_slow)
PRIMITIVE_FORWARD(resize_array)
PRIMITIVE_FORWARD(resize_string)
PRIMITIVE_FORWARD(array)
PRIMITIVE_FORWARD(begin_scan)
PRIMITIVE_FORWARD(next_object)
PRIMITIVE_FORWARD(end_scan)
PRIMITIVE_FORWARD(size)
PRIMITIVE_FORWARD(die)
PRIMITIVE_FORWARD(fopen)
PRIMITIVE_FORWARD(fgetc)
PRIMITIVE_FORWARD(fread)
PRIMITIVE_FORWARD(fputc)
PRIMITIVE_FORWARD(fwrite)
PRIMITIVE_FORWARD(fflush)
PRIMITIVE_FORWARD(ftell)
PRIMITIVE_FORWARD(fseek)
PRIMITIVE_FORWARD(fclose)
PRIMITIVE_FORWARD(wrapper)
PRIMITIVE_FORWARD(clone)
PRIMITIVE_FORWARD(string)
PRIMITIVE_FORWARD(array_to_quotation)
PRIMITIVE_FORWARD(quotation_xt)
PRIMITIVE_FORWARD(tuple)
PRIMITIVE_FORWARD(profiling)
PRIMITIVE_FORWARD(become)
PRIMITIVE_FORWARD(sleep)
PRIMITIVE_FORWARD(tuple_boa)
PRIMITIVE_FORWARD(callstack_to_array)
PRIMITIVE_FORWARD(innermost_stack_frame_executing)
PRIMITIVE_FORWARD(innermost_stack_frame_scan)
PRIMITIVE_FORWARD(set_innermost_stack_frame_quot)
PRIMITIVE_FORWARD(call_clear)
PRIMITIVE_FORWARD(resize_byte_array)
PRIMITIVE_FORWARD(dll_validp)
PRIMITIVE_FORWARD(unimplemented)
PRIMITIVE_FORWARD(clear_gc_stats)
PRIMITIVE_FORWARD(jit_compile)
PRIMITIVE_FORWARD(load_locals)
PRIMITIVE_FORWARD(check_datastack)
PRIMITIVE_FORWARD(mega_cache_miss)
PRIMITIVE_FORWARD(lookup_method)
PRIMITIVE_FORWARD(reset_dispatch_stats)
PRIMITIVE_FORWARD(dispatch_stats)
PRIMITIVE_FORWARD(reset_inline_cache_stats)
PRIMITIVE_FORWARD(inline_cache_stats)
PRIMITIVE_FORWARD(optimized_p)
PRIMITIVE_FORWARD(quot_compiled_p)
PRIMITIVE_FORWARD(vm_ptr)
PRIMITIVE_FORWARD(strip_stack_traces)
const primitive_type primitives[] = { const primitive_type primitives[] = {
primitive_bignum_to_fixnum, primitive_bignum_to_fixnum,
primitive_float_to_fixnum, primitive_float_to_fixnum,
@ -62,7 +187,7 @@ const primitive_type primitives[] = {
primitive_getenv, primitive_getenv,
primitive_setenv, primitive_setenv,
primitive_existsp, primitive_existsp,
primitive_gc, primitive_full_gc,
primitive_gc_stats, primitive_gc_stats,
primitive_save_image, primitive_save_image,
primitive_save_image_and_exit, primitive_save_image_and_exit,
@ -167,129 +292,4 @@ const primitive_type primitives[] = {
primitive_strip_stack_traces, primitive_strip_stack_traces,
}; };
PRIMITIVE_FORWARD(bignum_to_fixnum)
PRIMITIVE_FORWARD(float_to_fixnum)
PRIMITIVE_FORWARD(fixnum_to_bignum)
PRIMITIVE_FORWARD(float_to_bignum)
PRIMITIVE_FORWARD(fixnum_to_float)
PRIMITIVE_FORWARD(bignum_to_float)
PRIMITIVE_FORWARD(str_to_float)
PRIMITIVE_FORWARD(float_to_str)
PRIMITIVE_FORWARD(float_bits)
PRIMITIVE_FORWARD(double_bits)
PRIMITIVE_FORWARD(bits_float)
PRIMITIVE_FORWARD(bits_double)
PRIMITIVE_FORWARD(fixnum_divint)
PRIMITIVE_FORWARD(fixnum_divmod)
PRIMITIVE_FORWARD(fixnum_shift)
PRIMITIVE_FORWARD(bignum_eq)
PRIMITIVE_FORWARD(bignum_add)
PRIMITIVE_FORWARD(bignum_subtract)
PRIMITIVE_FORWARD(bignum_multiply)
PRIMITIVE_FORWARD(bignum_divint)
PRIMITIVE_FORWARD(bignum_mod)
PRIMITIVE_FORWARD(bignum_divmod)
PRIMITIVE_FORWARD(bignum_and)
PRIMITIVE_FORWARD(bignum_or)
PRIMITIVE_FORWARD(bignum_xor)
PRIMITIVE_FORWARD(bignum_not)
PRIMITIVE_FORWARD(bignum_shift)
PRIMITIVE_FORWARD(bignum_less)
PRIMITIVE_FORWARD(bignum_lesseq)
PRIMITIVE_FORWARD(bignum_greater)
PRIMITIVE_FORWARD(bignum_greatereq)
PRIMITIVE_FORWARD(bignum_bitp)
PRIMITIVE_FORWARD(bignum_log2)
PRIMITIVE_FORWARD(byte_array_to_bignum)
PRIMITIVE_FORWARD(float_eq)
PRIMITIVE_FORWARD(float_add)
PRIMITIVE_FORWARD(float_subtract)
PRIMITIVE_FORWARD(float_multiply)
PRIMITIVE_FORWARD(float_divfloat)
PRIMITIVE_FORWARD(float_mod)
PRIMITIVE_FORWARD(float_less)
PRIMITIVE_FORWARD(float_lesseq)
PRIMITIVE_FORWARD(float_greater)
PRIMITIVE_FORWARD(float_greatereq)
PRIMITIVE_FORWARD(word)
PRIMITIVE_FORWARD(word_xt)
PRIMITIVE_FORWARD(getenv)
PRIMITIVE_FORWARD(setenv)
PRIMITIVE_FORWARD(existsp)
PRIMITIVE_FORWARD(gc)
PRIMITIVE_FORWARD(gc_stats)
PRIMITIVE_FORWARD(save_image)
PRIMITIVE_FORWARD(save_image_and_exit)
PRIMITIVE_FORWARD(datastack)
PRIMITIVE_FORWARD(retainstack)
PRIMITIVE_FORWARD(callstack)
PRIMITIVE_FORWARD(set_datastack)
PRIMITIVE_FORWARD(set_retainstack)
PRIMITIVE_FORWARD(set_callstack)
PRIMITIVE_FORWARD(exit)
PRIMITIVE_FORWARD(data_room)
PRIMITIVE_FORWARD(code_room)
PRIMITIVE_FORWARD(micros)
PRIMITIVE_FORWARD(modify_code_heap)
PRIMITIVE_FORWARD(dlopen)
PRIMITIVE_FORWARD(dlsym)
PRIMITIVE_FORWARD(dlclose)
PRIMITIVE_FORWARD(byte_array)
PRIMITIVE_FORWARD(uninitialized_byte_array)
PRIMITIVE_FORWARD(displaced_alien)
PRIMITIVE_FORWARD(alien_address)
PRIMITIVE_FORWARD(set_slot)
PRIMITIVE_FORWARD(string_nth)
PRIMITIVE_FORWARD(set_string_nth_fast)
PRIMITIVE_FORWARD(set_string_nth_slow)
PRIMITIVE_FORWARD(resize_array)
PRIMITIVE_FORWARD(resize_string)
PRIMITIVE_FORWARD(array)
PRIMITIVE_FORWARD(begin_scan)
PRIMITIVE_FORWARD(next_object)
PRIMITIVE_FORWARD(end_scan)
PRIMITIVE_FORWARD(size)
PRIMITIVE_FORWARD(die)
PRIMITIVE_FORWARD(fopen)
PRIMITIVE_FORWARD(fgetc)
PRIMITIVE_FORWARD(fread)
PRIMITIVE_FORWARD(fputc)
PRIMITIVE_FORWARD(fwrite)
PRIMITIVE_FORWARD(fflush)
PRIMITIVE_FORWARD(ftell)
PRIMITIVE_FORWARD(fseek)
PRIMITIVE_FORWARD(fclose)
PRIMITIVE_FORWARD(wrapper)
PRIMITIVE_FORWARD(clone)
PRIMITIVE_FORWARD(string)
PRIMITIVE_FORWARD(array_to_quotation)
PRIMITIVE_FORWARD(quotation_xt)
PRIMITIVE_FORWARD(tuple)
PRIMITIVE_FORWARD(profiling)
PRIMITIVE_FORWARD(become)
PRIMITIVE_FORWARD(sleep)
PRIMITIVE_FORWARD(tuple_boa)
PRIMITIVE_FORWARD(callstack_to_array)
PRIMITIVE_FORWARD(innermost_stack_frame_executing)
PRIMITIVE_FORWARD(innermost_stack_frame_scan)
PRIMITIVE_FORWARD(set_innermost_stack_frame_quot)
PRIMITIVE_FORWARD(call_clear)
PRIMITIVE_FORWARD(resize_byte_array)
PRIMITIVE_FORWARD(dll_validp)
PRIMITIVE_FORWARD(unimplemented)
PRIMITIVE_FORWARD(clear_gc_stats)
PRIMITIVE_FORWARD(jit_compile)
PRIMITIVE_FORWARD(load_locals)
PRIMITIVE_FORWARD(check_datastack)
PRIMITIVE_FORWARD(mega_cache_miss)
PRIMITIVE_FORWARD(lookup_method)
PRIMITIVE_FORWARD(reset_dispatch_stats)
PRIMITIVE_FORWARD(dispatch_stats)
PRIMITIVE_FORWARD(reset_inline_cache_stats)
PRIMITIVE_FORWARD(inline_cache_stats)
PRIMITIVE_FORWARD(optimized_p)
PRIMITIVE_FORWARD(quot_compiled_p)
PRIMITIVE_FORWARD(vm_ptr)
PRIMITIVE_FORWARD(strip_stack_traces)
} }

View File

@ -18,79 +18,14 @@ namespace factor
#endif #endif
extern const primitive_type primitives[]; extern const primitive_type primitives[];
PRIMITIVE(bignum_to_fixnum); /* These are defined in assembly */
PRIMITIVE(float_to_fixnum);
PRIMITIVE(fixnum_to_bignum);
PRIMITIVE(float_to_bignum);
PRIMITIVE(fixnum_to_float);
PRIMITIVE(bignum_to_float);
PRIMITIVE(str_to_float);
PRIMITIVE(float_to_str);
PRIMITIVE(float_bits);
PRIMITIVE(double_bits);
PRIMITIVE(bits_float);
PRIMITIVE(bits_double);
PRIMITIVE(fixnum_add); PRIMITIVE(fixnum_add);
PRIMITIVE(fixnum_subtract); PRIMITIVE(fixnum_subtract);
PRIMITIVE(fixnum_multiply); PRIMITIVE(fixnum_multiply);
PRIMITIVE(fixnum_divint); PRIMITIVE(inline_cache_miss);
PRIMITIVE(fixnum_divmod); PRIMITIVE(inline_cache_miss_tail);
PRIMITIVE(fixnum_shift);
PRIMITIVE(bignum_eq); /* These are generated with macros in alien.c */
PRIMITIVE(bignum_add);
PRIMITIVE(bignum_subtract);
PRIMITIVE(bignum_multiply);
PRIMITIVE(bignum_divint);
PRIMITIVE(bignum_mod);
PRIMITIVE(bignum_divmod);
PRIMITIVE(bignum_and);
PRIMITIVE(bignum_or);
PRIMITIVE(bignum_xor);
PRIMITIVE(bignum_not);
PRIMITIVE(bignum_shift);
PRIMITIVE(bignum_less);
PRIMITIVE(bignum_lesseq);
PRIMITIVE(bignum_greater);
PRIMITIVE(bignum_greatereq);
PRIMITIVE(bignum_bitp);
PRIMITIVE(bignum_log2);
PRIMITIVE(byte_array_to_bignum);
PRIMITIVE(float_eq);
PRIMITIVE(float_add);
PRIMITIVE(float_subtract);
PRIMITIVE(float_multiply);
PRIMITIVE(float_divfloat);
PRIMITIVE(float_mod);
PRIMITIVE(float_less);
PRIMITIVE(float_lesseq);
PRIMITIVE(float_greater);
PRIMITIVE(float_greatereq);
PRIMITIVE(word);
PRIMITIVE(word_xt);
PRIMITIVE(getenv);
PRIMITIVE(setenv);
PRIMITIVE(existsp);
PRIMITIVE(gc);
PRIMITIVE(gc_stats);
PRIMITIVE(save_image);
PRIMITIVE(save_image_and_exit);
PRIMITIVE(datastack);
PRIMITIVE(retainstack);
PRIMITIVE(callstack);
PRIMITIVE(set_datastack);
PRIMITIVE(set_retainstack);
PRIMITIVE(set_callstack);
PRIMITIVE(exit);
PRIMITIVE(data_room);
PRIMITIVE(code_room);
PRIMITIVE(micros);
PRIMITIVE(modify_code_heap);
PRIMITIVE(dlopen);
PRIMITIVE(dlsym);
PRIMITIVE(dlclose);
PRIMITIVE(byte_array);
PRIMITIVE(uninitialized_byte_array);
PRIMITIVE(displaced_alien);
PRIMITIVE(alien_signed_cell); PRIMITIVE(alien_signed_cell);
PRIMITIVE(set_alien_signed_cell); PRIMITIVE(set_alien_signed_cell);
PRIMITIVE(alien_unsigned_cell); PRIMITIVE(alien_unsigned_cell);
@ -117,61 +52,5 @@ PRIMITIVE(alien_double);
PRIMITIVE(set_alien_double); PRIMITIVE(set_alien_double);
PRIMITIVE(alien_cell); PRIMITIVE(alien_cell);
PRIMITIVE(set_alien_cell); PRIMITIVE(set_alien_cell);
PRIMITIVE(alien_address);
PRIMITIVE(set_slot);
PRIMITIVE(string_nth);
PRIMITIVE(set_string_nth_fast);
PRIMITIVE(set_string_nth_slow);
PRIMITIVE(resize_array);
PRIMITIVE(resize_string);
PRIMITIVE(array);
PRIMITIVE(begin_scan);
PRIMITIVE(next_object);
PRIMITIVE(end_scan);
PRIMITIVE(size);
PRIMITIVE(die);
PRIMITIVE(fopen);
PRIMITIVE(fgetc);
PRIMITIVE(fread);
PRIMITIVE(fputc);
PRIMITIVE(fwrite);
PRIMITIVE(fflush);
PRIMITIVE(ftell);
PRIMITIVE(fseek);
PRIMITIVE(fclose);
PRIMITIVE(wrapper);
PRIMITIVE(clone);
PRIMITIVE(string);
PRIMITIVE(array_to_quotation);
PRIMITIVE(quotation_xt);
PRIMITIVE(tuple);
PRIMITIVE(profiling);
PRIMITIVE(become);
PRIMITIVE(sleep);
PRIMITIVE(tuple_boa);
PRIMITIVE(callstack_to_array);
PRIMITIVE(innermost_stack_frame_executing);
PRIMITIVE(innermost_stack_frame_scan);
PRIMITIVE(set_innermost_stack_frame_quot);
PRIMITIVE(call_clear);
PRIMITIVE(resize_byte_array);
PRIMITIVE(dll_validp);
PRIMITIVE(unimplemented);
PRIMITIVE(clear_gc_stats);
PRIMITIVE(jit_compile);
PRIMITIVE(load_locals);
PRIMITIVE(check_datastack);
PRIMITIVE(inline_cache_miss);
PRIMITIVE(inline_cache_miss_tail);
PRIMITIVE(mega_cache_miss);
PRIMITIVE(lookup_method);
PRIMITIVE(reset_dispatch_stats);
PRIMITIVE(dispatch_stats);
PRIMITIVE(reset_inline_cache_stats);
PRIMITIVE(inline_cache_stats);
PRIMITIVE(optimized_p);
PRIMITIVE(quot_compiled_p);
PRIMITIVE(vm_ptr);
PRIMITIVE(strip_stack_traces);
} }

View File

@ -29,7 +29,7 @@ void factor_vm::set_profiling(bool profiling)
/* Push everything to tenured space so that we can heap scan /* Push everything to tenured space so that we can heap scan
and allocate profiling blocks if necessary */ and allocate profiling blocks if necessary */
gc(); primitive_full_gc();
gc_root<array> words(find_all_words(),this); gc_root<array> words(find_all_words(),this);

View File

@ -283,9 +283,7 @@ void quotation_jit::iterate_quotation()
void factor_vm::set_quot_xt(quotation *quot, code_block *code) void factor_vm::set_quot_xt(quotation *quot, code_block *code)
{ {
if(code->type() != QUOTATION_TYPE) assert(code->type() == QUOTATION_TYPE);
critical_error("Bad param to set_quot_xt",(cell)code);
quot->code = code; quot->code = code;
quot->xt = code->xt(); quot->xt = code->xt();
} }

View File

@ -239,12 +239,13 @@ struct factor_vm
void collect_aging(); void collect_aging();
void collect_to_tenured(); void collect_to_tenured();
void collect_full_impl(bool trace_contexts_p); void collect_full_impl(bool trace_contexts_p);
void collect_growing_heap(cell requested_bytes, bool trace_contexts_p); void collect_growing_heap(cell requested_bytes, bool trace_contexts_p, bool compact_code_heap_p);
void collect_full(bool trace_contexts_p); void collect_full(bool trace_contexts_p, bool compact_code_heap_p);
void record_gc_stats(generation_statistics *stats); void record_gc_stats(generation_statistics *stats);
void garbage_collection(gc_op op, bool trace_contexts_p, cell requested_bytes); void gc(gc_op op, cell requested_bytes, bool trace_contexts_p, bool compact_code_heap_p);
void gc(); void primitive_full_gc();
void primitive_gc(); void primitive_minor_gc();
void primitive_compact_gc();
void primitive_gc_stats(); void primitive_gc_stats();
void clear_gc_stats(); void clear_gc_stats();
void primitive_become(); void primitive_become();
@ -499,10 +500,9 @@ struct factor_vm
void update_code_heap_words(); void update_code_heap_words();
void primitive_modify_code_heap(); void primitive_modify_code_heap();
void primitive_code_room(); void primitive_code_room();
code_block *forward_xt(code_block *compiled);
void forward_object_xts(); void forward_object_xts();
void fixup_object_xts(); void forward_context_xts();
void compact_code_heap(); void compact_code_heap(bool trace_contexts_p);
void primitive_strip_stack_traces(); void primitive_strip_stack_traces();
/* Apply a function to every code block */ /* Apply a function to every code block */
@ -557,7 +557,7 @@ struct factor_vm
void primitive_innermost_stack_frame_scan(); void primitive_innermost_stack_frame_scan();
void primitive_set_innermost_stack_frame_quot(); void primitive_set_innermost_stack_frame_quot();
void save_callstack_bottom(stack_frame *callstack_bottom); void save_callstack_bottom(stack_frame *callstack_bottom);
template<typename Iterator> void iterate_callstack(cell top, cell bottom, Iterator &iterator); template<typename Iterator> void iterate_callstack(context *ctx, Iterator &iterator);
/* Every object has a regular representation in the runtime, which makes GC /* Every object has a regular representation in the runtime, which makes GC
much simpler. Every slot of the object until binary_payload_start is a pointer much simpler. Every slot of the object until binary_payload_start is a pointer