#include "master.hpp" namespace factor { struct nursery_copier : no_fixup { bump_allocator* nursery; aging_space* aging; nursery_copier(bump_allocator* nursery, aging_space* aging) : nursery(nursery), aging(aging) { } object* fixup_data(object* obj) { if (!nursery->contains_p(obj)) { return obj; } // The while-loop is a needed micro-optimization. while (obj->forwarding_pointer_p()) { obj = obj->forwarding_pointer(); } if (!nursery->contains_p(obj)) { return obj; } cell size = obj->size(); object* newpointer = aging->allot(size); if (!newpointer) throw must_start_gc_again(); memcpy(newpointer, obj, size); obj->forward_to(newpointer); return newpointer; } }; 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. slot_visitor visitor(this, nursery_copier(data->nursery, data->aging)); 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_phase(PHASE_CARD_SCAN); event->cards_scanned += visitor.cards_scanned; event->decks_scanned += visitor.decks_scanned; } if (event) event->reset_timer(); visitor.visit_code_heap_roots(&code->points_to_nursery); if (event) { event->ended_phase(PHASE_CODE_SCAN); event->code_blocks_scanned += code->points_to_nursery.size(); } visitor.cheneys_algorithm(data->aging, scan); data->reset_nursery(); code->points_to_nursery.clear(); } }