diff --git a/vm/callstack.cpp b/vm/callstack.cpp index b766be0399..fcf517fde5 100755 --- a/vm/callstack.cpp +++ b/vm/callstack.cpp @@ -94,10 +94,9 @@ stack_frame *factor_vm::frame_successor(stack_frame *frame) cell factor_vm::frame_offset(stack_frame *frame) { - char *entry_point = (char *)frame_code(frame)->entry_point(); char *return_address = (char *)FRAME_RETURN_ADDRESS(frame,this); FACTOR_ASSERT(return_address != 0); - return return_address - entry_point; + return frame_code(frame)->offset(return_address); } void factor_vm::set_frame_offset(stack_frame *frame, cell offset) diff --git a/vm/callstack.hpp b/vm/callstack.hpp index 7d167e9fe8..ccddba117a 100755 --- a/vm/callstack.hpp +++ b/vm/callstack.hpp @@ -8,8 +8,9 @@ inline static cell callstack_object_size(cell size) /* This is a little tricky. The iterator may allocate memory, so we keep the callstack in a GC root and use relative offsets */ -template -void factor_vm::iterate_callstack_object_reversed(callstack *stack_, Iterator &iterator) +template +void factor_vm::iterate_callstack_object_reversed(callstack *stack_, + Iterator &iterator, Fixup &fixup) { data_root stack(stack_,this); fixnum frame_length = factor::untag_fixnum(stack->length); @@ -20,18 +21,21 @@ void factor_vm::iterate_callstack_object_reversed(callstack *stack_, Iterator &i void *frame_top = stack->frame_top_at(frame_offset); void *addr = frame_return_address(frame_top); - code_block *owner = code->code_block_for_address(addr); - cell frame_size = owner->stack_frame_size_for_address(addr); + 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*)((char*)frame_top + frame_size) - 1; - FACTOR_ASSERT(owner->entry_point() == frame->entry_point); + 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(owner, addr); + iterator(frame_top, owner, fixed_addr); frame_offset += frame_size; } } @@ -73,8 +77,8 @@ void factor_vm::iterate_callstack_reversed(context *ctx, Iterator &iterator) FACTOR_ASSERT(frame_size == frame->size); #endif + iterator(frame_top, owner, addr); frame_top += frame_size; - iterator(owner, addr); } } diff --git a/vm/code_blocks.hpp b/vm/code_blocks.hpp index ed74c50de5..d7e2858684 100644 --- a/vm/code_blocks.hpp +++ b/vm/code_blocks.hpp @@ -127,6 +127,11 @@ struct code_block return (char*)addr - (char*)entry_point(); } + void *address_for_offset(cell offset) const + { + return (void*)((char*)entry_point() + offset); + } + cell scan(factor_vm *vm, void *addr) const; }; diff --git a/vm/compaction.cpp b/vm/compaction.cpp index 465ac573b7..2b96e68002 100644 --- a/vm/compaction.cpp +++ b/vm/compaction.cpp @@ -224,6 +224,8 @@ void factor_vm::collect_compact_impl(bool trace_contexts_p) code_block_compaction_updater code_block_updater(this,fixup,data_forwarder,code_forwarder); code->allocator->compact(code_block_updater,fixup,&code_finger); + code->update_all_blocks_set(code_forwarding_map); + data_forwarder.visit_roots(); if(trace_contexts_p) { diff --git a/vm/debug.cpp b/vm/debug.cpp index 204dcf365f..10b99fccf5 100755 --- a/vm/debug.cpp +++ b/vm/debug.cpp @@ -220,9 +220,10 @@ struct stack_frame_printer { factor_vm *parent; explicit stack_frame_printer(factor_vm *parent_) : parent(parent_) {} - void operator()(code_block *owner, void *addr) + void operator()(void *frame_top, code_block *owner, void *addr) { std::cout << std::endl; + std::cout << "frame: " << frame_top << std::endl; std::cout << "executing: "; parent->print_obj(owner->owner); std::cout << std::endl; diff --git a/vm/image.cpp b/vm/image.cpp index bd66b9fee1..806db02ca4 100755 --- a/vm/image.cpp +++ b/vm/image.cpp @@ -53,6 +53,7 @@ void factor_vm::load_code_heap(FILE *file, image_header *h, vm_parameters *p) } code->allocator->initial_free_list(h->code_size); + code->initialize_all_blocks_set(); } struct startup_fixup { @@ -284,8 +285,6 @@ void factor_vm::load_image(vm_parameters *p) fixup_data(data_offset,code_offset); fixup_code(data_offset,code_offset); - code->initialize_all_blocks_set(); - /* Store image path name */ special_objects[OBJ_IMAGE] = allot_alien(false_object,(cell)p->image_path); } diff --git a/vm/mark_bits.hpp b/vm/mark_bits.hpp index 0cce3fd134..e721342975 100644 --- a/vm/mark_bits.hpp +++ b/vm/mark_bits.hpp @@ -126,7 +126,8 @@ template struct mark_bits { Block *forward_block(const Block *original) { #ifdef FACTOR_DEBUG - FACTOR_ASSERT(marked_p(original)); + // XXX this condition seems to be harmless--ask slava + //FACTOR_ASSERT(marked_p(original)); #endif std::pair position = bitmap_deref(original); diff --git a/vm/slot_visitor.hpp b/vm/slot_visitor.hpp index 5e8cbe10d0..131fcd6ea5 100755 --- a/vm/slot_visitor.hpp +++ b/vm/slot_visitor.hpp @@ -300,32 +300,27 @@ struct call_frame_slot_visitor { parent(parent_), visitor(visitor_) {} /* - next -> [entry_point] - [size] - [return address] -- x86 only, backend adds 1 to each spill location - [spill area] - ... - frame -> [entry_point] - [size] + frame top -> [return address] + [spill area] + ... + [entry_point] + [size] */ - void operator()(stack_frame *frame) + void operator()(void *frame_top, code_block *owner, void *addr) { - cell return_address = parent->frame_offset(frame); - if(return_address == (cell)-1) - return; + cell return_address = owner->offset(addr); - code_block *compiled = visitor->fixup.translate_code(parent->frame_code(frame)); - gc_info *info = compiled->block_gc_info(); + gc_info *info = owner->block_gc_info(); - FACTOR_ASSERT(return_address < compiled->size()); + FACTOR_ASSERT(return_address < owner->size()); cell callsite = info->return_address_index(return_address); if(callsite == (cell)-1) return; #ifdef DEBUG_GC_MAPS - std::cout << "call frame code block " << compiled << " with offset " << return_address << std::endl; + std::cout << "call frame code block " << owner << " with offset " << return_address << std::endl; #endif - cell *stack_pointer = (cell *)(parent->frame_successor(frame) + 1); + cell *stack_pointer = (cell *)frame_top; u8 *bitmap = info->gc_info_bitmap(); /* Subtract old value of base pointer from every derived pointer. */ @@ -371,14 +366,14 @@ template void slot_visitor::visit_callstack_object(callstack *stack) { call_frame_slot_visitor call_frame_visitor(parent,this); - parent->iterate_callstack_object(stack,call_frame_visitor); + parent->iterate_callstack_object_reversed(stack,call_frame_visitor,fixup); } template void slot_visitor::visit_callstack(context *ctx) { call_frame_slot_visitor call_frame_visitor(parent,this); - parent->iterate_callstack(ctx,call_frame_visitor); + parent->iterate_callstack_reversed(ctx,call_frame_visitor); } template diff --git a/vm/vm.hpp b/vm/vm.hpp index 968d2d8dd4..c7e762e1af 100755 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -621,8 +621,13 @@ struct factor_vm bool embedded_image_p(); // callstack - template void iterate_callstack_object(callstack *stack_, Iterator &iterator); - template void iterate_callstack_object_reversed(callstack *stack_, Iterator &iterator); + template + void iterate_callstack_object(callstack *stack_, Iterator &iterator); + + template + void iterate_callstack_object_reversed(callstack *stack_, + Iterator &iterator, Fixup &fixup); + void check_frame(stack_frame *frame); callstack *allot_callstack(cell size); stack_frame *second_from_top_stack_frame(context *ctx);