/* 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]; } }
/* frame top -> [return address] [spill area] ... [entry_point] [size] */ void operator()(void* frame_top, cell frame_size, code_block* owner, void* addr) { cell return_address = owner->offset(addr); code_block* compiled = Fixup::translated_code_block_map ? owner : visitor->fixup.translate_code(owner); gc_info* info = compiled->block_gc_info(); FACTOR_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*)frame_top; uint8_t* 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++) { uint32_t base_pointer = info->lookup_base_pointer(callsite, spill_slot); if (base_pointer != (uint32_t)-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++) { uint32_t base_pointer = info->lookup_base_pointer(callsite, spill_slot); if (base_pointer != (uint32_t)-1) stack_pointer[spill_slot] += stack_pointer[base_pointer]; } }
void trace_partial_objects(cell start, cell end, cell card_start, cell card_end) { if(card_start < end) { start += sizeof(cell); if(start < card_start) start = card_start; if(end > card_end) end = card_end; cell *slot_ptr = (cell *)start; cell *end_ptr = (cell *)end; for(; slot_ptr < end_ptr; slot_ptr++) data_visitor.visit_handle(slot_ptr); } }
/* 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]); } }
void trace_handle(cell *handle) { data_visitor.visit_handle(handle); }
void operator()(code_block* stub) { visitor->visit_handle(&stub->owner); }