void factor_vm::collect_nursery() { // Copy live objects from the nursery (as determined by the root set and // marked cards in aging and tenured) to aging space. gc_workhorse<aging_space, nursery_policy> workhorse(this, data->aging, nursery_policy(data->nursery)); slot_visitor<gc_workhorse<aging_space, nursery_policy>> visitor(this, workhorse); cell scan = data->aging->start + data->aging->occupied_space(); visitor.visit_all_roots(); gc_event* event = current_gc->event; if (event) event->reset_timer(); visitor.visit_cards(data->tenured, card_points_to_nursery, card_points_to_nursery); visitor.visit_cards(data->aging, card_points_to_nursery, 0xff); if (event) event->ended_card_scan(visitor.cards_scanned, visitor.decks_scanned); if (event) event->reset_timer(); visitor.visit_code_heap_roots(&code->points_to_nursery); if (event) event->ended_code_scan(code->points_to_nursery.size()); visitor.cheneys_algorithm(data->aging, scan); data->reset_nursery(); code->points_to_nursery.clear(); }
/* classes.tuple uses this to reshape tuples; tools.deploy.shaker uses this to coalesce equal but distinct quotations and wrappers. */ void factor_vm::primitive_become() { array *new_objects = untag_check<array>(ctx->pop()); array *old_objects = untag_check<array>(ctx->pop()); cell capacity = array_capacity(new_objects); if(capacity != array_capacity(old_objects)) critical_error("bad parameters to become",0); /* Build the forwarding map */ std::map<object *,object *> become_map; for(cell i = 0; i < capacity; i++) { tagged<object> old_obj(array_nth(old_objects,i)); tagged<object> new_obj(array_nth(new_objects,i)); if(old_obj != new_obj) become_map[old_obj.untagged()] = new_obj.untagged(); } /* Update all references to old objects to point to new objects */ { slot_visitor<slot_become_fixup> workhorse(this,slot_become_fixup(&become_map)); workhorse.visit_roots(); workhorse.visit_contexts(); object_become_visitor object_visitor(&workhorse); each_object(object_visitor); code_block_become_visitor code_block_visitor(&workhorse); each_code_block(code_block_visitor); } /* Since we may have introduced old->new references, need to revisit all objects and code blocks on a minor GC. */ data->mark_all_cards(); { code_block_write_barrier_visitor code_block_visitor(code); each_code_block(code_block_visitor); } }