diff --git a/vm/callstack.hpp b/vm/callstack.hpp index ccddba117a..bd16117b40 100755 --- a/vm/callstack.hpp +++ b/vm/callstack.hpp @@ -40,7 +40,8 @@ void factor_vm::iterate_callstack_object_reversed(callstack *stack_, } } -template void factor_vm::iterate_callstack_object(callstack *stack_, Iterator &iterator) +template void factor_vm::iterate_callstack_object(callstack *stack_, + Iterator &iterator) { data_root stack(stack_,this); fixnum frame_offset = factor::untag_fixnum(stack->length) - sizeof(stack_frame); @@ -53,6 +54,39 @@ template void factor_vm::iterate_callstack_object(callstack * } } +template +void factor_vm::iterate_callstack_reversed(context *ctx, Iterator &iterator, Fixup &fixup) +{ + if (ctx->callstack_top == ctx->callstack_bottom) + return; + + char *frame_top = (char*)ctx->callstack_top; + + while (frame_top < (char*)ctx->callstack_bottom) + { + void *addr = frame_return_address((void*)frame_top); + FACTOR_ASSERT(addr != 0); + + void *fixed_addr = (void*)fixup.translate_code((code_block*)addr); + + code_block *owner = code->code_block_for_address((cell)fixed_addr); + cell frame_size = owner->stack_frame_size_for_address((cell)fixed_addr); + +#ifdef FACTOR_DEBUG + // check our derived owner and frame size against the ones stored in the frame + // by the function prolog + stack_frame *frame = (stack_frame*)(frame_top + frame_size) - 1; + void *fixed_entry_point = + (void*)fixup.translate_code((code_block*)frame->entry_point); + FACTOR_ASSERT(owner->entry_point() == fixed_entry_point); + FACTOR_ASSERT(frame_size == frame->size); +#endif + + iterator(frame_top, owner, fixed_addr); + frame_top += frame_size; + } +} + template void factor_vm::iterate_callstack_reversed(context *ctx, Iterator &iterator) { diff --git a/vm/code_block_visitor.hpp b/vm/code_block_visitor.hpp index 2421ace669..96881ed37f 100644 --- a/vm/code_block_visitor.hpp +++ b/vm/code_block_visitor.hpp @@ -42,12 +42,13 @@ struct call_frame_code_block_visitor { explicit call_frame_code_block_visitor(factor_vm *parent_, Fixup fixup_) : parent(parent_), fixup(fixup_) {} - void operator()(stack_frame *frame) + void operator()(void *frame_top, code_block *owner, void *addr) { - cell offset = parent->frame_offset(frame); - code_block *compiled = fixup.fixup_code(parent->frame_code(frame)); - frame->entry_point = compiled->entry_point(); - parent->set_frame_offset(frame,offset); + set_frame_return_address(frame_top, addr); + // XXX remove this when prolog data is removed + cell frame_size = owner->stack_frame_size_for_address((cell)addr); + stack_frame *frame = (stack_frame*)((char*)frame_top + frame_size) - 1; + frame->entry_point = owner->entry_point(); } }; @@ -74,7 +75,7 @@ void code_block_visitor::visit_object_code_block(object *obj) { callstack *stack = (callstack *)obj; call_frame_code_block_visitor call_frame_visitor(parent,fixup); - parent->iterate_callstack_object(stack,call_frame_visitor); + parent->iterate_callstack_object_reversed(stack,call_frame_visitor,fixup); break; } } @@ -110,7 +111,7 @@ template void code_block_visitor::visit_context_code_blocks() { call_frame_code_block_visitor call_frame_visitor(parent,fixup); - parent->iterate_active_callstacks(call_frame_visitor); + parent->iterate_active_callstacks_reversed(call_frame_visitor,fixup); } template diff --git a/vm/cpu-x86.hpp b/vm/cpu-x86.hpp index 542d3a8c08..45731976b9 100755 --- a/vm/cpu-x86.hpp +++ b/vm/cpu-x86.hpp @@ -8,9 +8,9 @@ inline static void* frame_return_address(void *frame_top) return *(void**)frame_top; } -inline static void set_frame_return_address(void *frame_top, cell return_address) +inline static void set_frame_return_address(void *frame_top, void *return_address) { - *(cell*)frame_top = return_address; + *(void**)frame_top = return_address; } #define CALLSTACK_BOTTOM(ctx) (stack_frame *)(ctx->callstack_seg->end - sizeof(cell) * 5) diff --git a/vm/debug.cpp b/vm/debug.cpp index 10b99fccf5..026ac7fd5e 100755 --- a/vm/debug.cpp +++ b/vm/debug.cpp @@ -614,6 +614,8 @@ void factor_vm::factorbug() } else if(strcmp(cmd,"code") == 0) dump_code_heap(); + else if(strcmp(cmd,"compact-gc") == 0) + primitive_compact_gc(); else if(strcmp(cmd,"gc") == 0) primitive_full_gc(); else if(strcmp(cmd,"compact-gc") == 0) diff --git a/vm/mark_bits.hpp b/vm/mark_bits.hpp index e721342975..b546f69d6a 100644 --- a/vm/mark_bits.hpp +++ b/vm/mark_bits.hpp @@ -130,12 +130,13 @@ template struct mark_bits { //FACTOR_ASSERT(marked_p(original)); #endif std::pair position = bitmap_deref(original); + cell offset = (cell)original & (data_alignment - 1); cell approx_popcount = forwarding[position.first]; cell mask = ((cell)1 << position.second) - 1; cell new_line_number = approx_popcount + popcount(marked[position.first] & mask); - Block *new_block = line_block(new_line_number); + Block *new_block = (Block*)((char*)line_block(new_line_number) + offset); #ifdef FACTOR_DEBUG FACTOR_ASSERT(new_block <= original); #endif diff --git a/vm/slot_visitor.hpp b/vm/slot_visitor.hpp index 131fcd6ea5..85f5b4fe11 100755 --- a/vm/slot_visitor.hpp +++ b/vm/slot_visitor.hpp @@ -373,7 +373,7 @@ template void slot_visitor::visit_callstack(context *ctx) { call_frame_slot_visitor call_frame_visitor(parent,this); - parent->iterate_callstack_reversed(ctx,call_frame_visitor); + parent->iterate_callstack_reversed(ctx,call_frame_visitor,fixup); } template diff --git a/vm/vm.hpp b/vm/vm.hpp index c7e762e1af..6770fa20b8 100755 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -178,7 +178,8 @@ struct factor_vm void primitive_check_datastack(); void primitive_load_locals(); - template void iterate_active_callstacks(Iterator &iter) + template + void iterate_active_callstacks(Iterator &iter) { std::set::const_iterator begin = active_contexts.begin(); std::set::const_iterator end = active_contexts.end(); @@ -188,6 +189,17 @@ struct factor_vm } } + template + void iterate_active_callstacks_reversed(Iterator &iter, Fixup &fixup) + { + std::set::const_iterator begin = active_contexts.begin(); + std::set::const_iterator end = active_contexts.end(); + while(begin != end) + { + iterate_callstack_reversed(*begin++,iter,fixup); + } + } + // run void primitive_exit(); void primitive_nano_count(); @@ -648,8 +660,15 @@ struct factor_vm void primitive_innermost_stack_frame_scan(); void primitive_set_innermost_stack_frame_quot(); void primitive_callstack_bounds(); - template void iterate_callstack_reversed(context *ctx, Iterator &iterator); - template void iterate_callstack(context *ctx, Iterator &iterator); + + template + void iterate_callstack_reversed(context *ctx, Iterator &iterator); + + template + void iterate_callstack_reversed(context *ctx, Iterator &iterator, Fixup &fixup); + + template + void iterate_callstack(context *ctx, Iterator &iterator); // cpu-* void dispatch_signal_handler(cell *sp, cell *pc, cell newpc);