/* next -> [entry_point] [size] [return address] -- x86 only, backend adds 1 to each spill location [spill area] ... frame -> [entry_point] [size] */ void operator()(stack_frame *frame) { cell return_address = parent->frame_offset(frame); if(return_address == (cell)-1) return; code_block *compiled = visitor->fixup.translate_code(parent->frame_code(frame)); gc_info *info = compiled->block_gc_info(); assert(return_address < compiled->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; #endif cell *stack_pointer = (cell *)(parent->frame_successor(frame) + 1); u8 *bitmap = info->gc_info_bitmap(); /* Subtract old value of base pointer from every derived pointer. */ for(cell spill_slot = 0; spill_slot < info->derived_root_count; spill_slot++) { u32 base_pointer = info->lookup_base_pointer(callsite, spill_slot); if(base_pointer != (u32)-1) { #ifdef DEBUG_GC_MAPS std::cout << "visiting derived root " << spill_slot << " with base pointer " << base_pointer << std::endl; #endif stack_pointer[spill_slot] -= stack_pointer[base_pointer]; } } /* Update all GC roots, including base pointers. */ cell callsite_gc_roots = info->callsite_gc_roots(callsite); for(cell spill_slot = 0; spill_slot < info->gc_root_count; spill_slot++) { if(bitmap_p(bitmap,callsite_gc_roots + spill_slot)) { #ifdef DEBUG_GC_MAPS std::cout << "visiting GC root " << spill_slot << std::endl; #endif visitor->visit_handle(stack_pointer + spill_slot); } } /* Add the base pointers to obtain new derived pointer values. */ for(cell spill_slot = 0; spill_slot < info->derived_root_count; spill_slot++) { u32 base_pointer = info->lookup_base_pointer(callsite, spill_slot); if(base_pointer != (u32)-1) stack_pointer[spill_slot] += stack_pointer[base_pointer]; } }
/* next -> [entry_point] [size] [return address] -- x86 only, backend adds 1 to each spill location [spill area] ... frame -> [entry_point] [size] */ void operator()(stack_frame *frame) { cell return_address = parent->frame_offset(frame); if(return_address == (cell)-1) return; code_block *compiled = visitor->fixup.translate_code(parent->frame_code(frame)); gc_info *info = compiled->block_gc_info(); assert(return_address < compiled->size()); int index = info->return_address_index(return_address); if(index == -1) return; u8 *bitmap = info->gc_info_bitmap(); cell base = info->spill_slot_base(index); cell *stack_pointer = (cell *)(parent->frame_successor(frame) + 1); for(cell spill_slot = 0; spill_slot < info->gc_root_count; spill_slot++) { if(bitmap_p(bitmap,base + spill_slot)) visitor->visit_handle(&stack_pointer[spill_slot]); } }