/* Compact just the code heap, after growing the data heap */ void factor_vm::collect_compact_code_impl(bool trace_contexts_p) { /* Figure out where blocks are going to go */ mark_bits<code_block> *code_forwarding_map = &code->allocator->state; code_forwarding_map->compute_forwarding(); const code_block *code_finger = code->allocator->first_block(); code_compaction_fixup fixup(code_forwarding_map,&code_finger); slot_visitor<code_compaction_fixup> data_forwarder(this,fixup); code_block_visitor<code_compaction_fixup> code_forwarder(this,fixup); code_forwarder.visit_uninitialized_code_blocks(); if(trace_contexts_p) code_forwarder.visit_context_code_blocks(); /* Update code heap references in data heap */ object_grow_heap_updater object_updater(code_forwarder); each_object(object_updater); /* Slide everything in the code heap up, and update code heap pointers inside code blocks. */ code_block_compaction_updater<code_compaction_fixup> code_block_updater(this,fixup,data_forwarder,code_forwarder); code->allocator->compact(code_block_updater,fixup,&code_finger); update_code_roots_for_compaction(); callbacks->update(); }
/* Compact data and code heaps */ void factor_vm::collect_compact_impl(bool trace_contexts_p) { gc_event *event = current_gc->event; #if defined(FACTOR_DEBUG) code->verify_all_blocks_set(); #endif if(event) event->started_compaction(); tenured_space *tenured = data->tenured; mark_bits<object> *data_forwarding_map = &tenured->state; mark_bits<code_block> *code_forwarding_map = &code->allocator->state; /* Figure out where blocks are going to go */ data_forwarding_map->compute_forwarding(); code_forwarding_map->compute_forwarding(); const object *data_finger = tenured->first_block(); const code_block *code_finger = code->allocator->first_block(); compaction_fixup fixup(data_forwarding_map,code_forwarding_map,&data_finger,&code_finger); slot_visitor<compaction_fixup> data_forwarder(this,fixup); code_block_visitor<compaction_fixup> code_forwarder(this,fixup); code_forwarder.visit_code_roots(); /* Object start offsets get recomputed by the object_compaction_updater */ data->tenured->starts.clear_object_start_offsets(); /* Slide everything in tenured space up, and update data and code heap pointers inside objects. */ object_compaction_updater object_updater(this,fixup); tenured->compact(object_updater,fixup,&data_finger); /* Slide everything in the code heap up, and update data and code heap pointers inside code blocks. */ code_block_compaction_updater<compaction_fixup> code_block_updater(this,fixup,data_forwarder,code_forwarder); code->allocator->compact(code_block_updater,fixup,&code_finger); data_forwarder.visit_roots(); if(trace_contexts_p) { data_forwarder.visit_contexts(); code_forwarder.visit_context_code_blocks(); } update_code_roots_for_compaction(); callbacks->update(); code->initialize_all_blocks_set(); if(event) event->ended_compaction(); }