diff --git a/vm/gc_info.hpp b/vm/gc_info.hpp index 84ae69ccfe..60794a79a0 100644 --- a/vm/gc_info.hpp +++ b/vm/gc_info.hpp @@ -39,13 +39,31 @@ struct gc_info { return (uint8_t*)base_pointer_map() - total_bitmap_bytes(); } - cell callsite_scrub_d(cell index) { return index * scrub_d_count; } + cell callsite_scrub_d(cell index) { + cell base = 0; + return base + index * scrub_d_count; + } cell callsite_scrub_r(cell index) { cell base = return_address_count * scrub_d_count; return base + index * scrub_r_count; } + cell callsite_check_d(cell index) { + cell base = + return_address_count * scrub_d_count + + return_address_count * scrub_r_count; + return base + index * check_d_count; + } + + cell callsite_check_r(cell index) { + cell base = + return_address_count * scrub_d_count + + return_address_count * scrub_r_count + + return_address_count * check_d_count; + return base + index + check_r_count; + } + cell callsite_gc_roots(cell index) { cell base = return_address_count * scrub_d_count + diff --git a/vm/slot_visitor.hpp b/vm/slot_visitor.hpp index ca126feecc..e288739d77 100644 --- a/vm/slot_visitor.hpp +++ b/vm/slot_visitor.hpp @@ -264,10 +264,12 @@ template void slot_visitor::visit_roots() { template struct call_frame_slot_visitor { factor_vm* parent; slot_visitor* visitor; + context* ctx; call_frame_slot_visitor(factor_vm* parent, - slot_visitor* visitor) - : parent(parent), visitor(visitor) {} + slot_visitor* visitor, + context* ctx) + : parent(parent), visitor(visitor), ctx(ctx) {} /* frame top -> [return address] @@ -310,6 +312,29 @@ template struct call_frame_slot_visitor { } } + /* Trace all overinitialized stack locations. */ + cell callsite_check_d = info->callsite_check_d(callsite); + for (uint32_t loc = 0; loc < info->check_d_count; loc++) { + if (bitmap_p(bitmap, callsite_check_d + loc)) { +#ifdef DEBUG_GC_MAPS + std::cout << "checking datastack location " << loc << std::endl; +#endif + cell* value_ptr = ((cell*)ctx->datastack + loc + 1); + visitor->visit_handle(value_ptr); + } + } + + cell callsite_check_r = info->callsite_check_r(callsite); + for (uint32_t loc = 0; loc < info->check_r_count; loc++) { + if (bitmap_p(bitmap, callsite_check_r + loc)) { +#ifdef DEBUG_GC_MAPS + std::cout << "checking retainstack location " << loc << std::endl; +#endif + cell* value_ptr = ((cell*)ctx->retainstack + loc + 1); + visitor->visit_handle(value_ptr); + } + } + /* Update all GC roots, including base pointers. */ cell callsite_gc_roots = info->callsite_gc_roots(callsite); @@ -334,13 +359,14 @@ template struct call_frame_slot_visitor { template void slot_visitor::visit_callstack_object(callstack* stack) { - call_frame_slot_visitor call_frame_visitor(parent, this); + /* TODO: is parent->ctx right? */ + call_frame_slot_visitor call_frame_visitor(parent, this, parent->ctx); parent->iterate_callstack_object(stack, call_frame_visitor, fixup); } template void slot_visitor::visit_callstack(context* ctx) { - call_frame_slot_visitor call_frame_visitor(parent, this); + call_frame_slot_visitor call_frame_visitor(parent, this, ctx); parent->iterate_callstack(ctx, call_frame_visitor, fixup); }