]> gitweb.factorcode.org Git - factor.git/blobdiff - vm/aging_collector.cpp
Put brackets around ipv6 addresses in `inet6 present`
[factor.git] / vm / aging_collector.cpp
index 1695846ee7c086bc9c9292c7479e38a7252b8d06..c934984e01e304ba99941c0b801dd426c7b0f193 100644 (file)
@@ -1,57 +1,90 @@
 #include "master.hpp"
 
-namespace factor
-{
-
-aging_collector::aging_collector(factor_vm *parent_) :
-       copying_collector<aging_space,aging_policy>(
-               parent_,
-               parent_->data->aging,
-               aging_policy(parent_)) {}
-
-void factor_vm::collect_aging()
-{
-       /* Promote objects referenced from tenured space to tenured space, copy
-       everything else to the aging semi-space, and reset the nursery pointer. */
-       {
-               /* Change the op so that if we fail here, we proceed to a full
-               tenured collection. We are collecting to tenured space, and
-               cards were unmarked, so we can't proceed with a to_tenured
-               collection. */
-               current_gc->op = collect_to_tenured_op;
-
-               to_tenured_collector collector(this);
-
-               current_gc->event->started_code_scan();
-               collector.trace_cards(data->tenured,
-                       card_points_to_aging,
-                       full_unmarker());
-               current_gc->event->ended_card_scan(collector.cards_scanned,collector.decks_scanned);
-
-               current_gc->event->started_code_scan();
-               collector.trace_code_heap_roots(&code->points_to_aging);
-               current_gc->event->ended_code_scan(collector.code_blocks_scanned);
-
-               collector.tenure_reachable_objects();
-       }
-       {
-               /* If collection fails here, do a to_tenured collection. */
-               current_gc->op = collect_aging_op;
-
-               std::swap(data->aging,data->aging_semispace);
-               data->reset_generation(data->aging);
-
-               aging_collector collector(this);
-
-               collector.trace_roots();
-               collector.trace_contexts();
-
-               collector.cheneys_algorithm();
-
-               data->reset_generation(&nursery);
-               code->points_to_nursery.clear();
-               code->points_to_aging.clear();
-       }
+namespace factor {
+
+struct to_aging_copier : no_fixup {
+  aging_space* aging;
+  tenured_space* tenured;
+
+  to_aging_copier(aging_space* aging, tenured_space* tenured)
+      : aging(aging), tenured(tenured) { }
+
+  object* fixup_data(object* obj) {
+    if (aging->contains_p(obj) || tenured->contains_p(obj)) {
+      return obj;
+    }
+
+    // Is there another forwarding pointer?
+    while (obj->forwarding_pointer_p()) {
+      object* dest = obj->forwarding_pointer();
+      obj = dest;
+    }
+
+    if (aging->contains_p(obj) || tenured->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_aging() {
+  // Promote objects referenced from tenured space to tenured space, copy
+  // everything else to the aging semi-space, and reset the nursery pointer.
+  {
+    // Change the op so that if we fail here, an assertion will be raised.
+    current_gc->op = COLLECT_TO_TENURED_OP;
+
+    slot_visitor<from_tenured_refs_copier>
+        visitor(this, from_tenured_refs_copier(data->tenured, &mark_stack));
+
+    gc_event* event = current_gc->event;
+
+    if (event)
+      event->reset_timer();
+    visitor.visit_cards(data->tenured, card_points_to_aging, 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_aging);
+    if (event) {
+      event->ended_phase(PHASE_CODE_SCAN);
+      event->code_blocks_scanned += code->points_to_aging.size();
+    }
+    visitor.visit_mark_stack(&mark_stack);
+  }
+  {
+    // If collection fails here, do a to_tenured collection.
+    current_gc->op = COLLECT_AGING_OP;
+
+    std::swap(data->aging, data->aging_semispace);
+    data->reset_aging();
+
+    aging_space *aging = data->aging;
+    slot_visitor<to_aging_copier>
+        visitor(this, to_aging_copier(aging, data->tenured));
+
+    cell scan = aging->start + aging->occupied_space();
+
+    visitor.visit_all_roots();
+    visitor.cheneys_algorithm(aging, scan);
+
+    data->reset_nursery();
+    code->clear_remembered_set();
+  }
 }
 
 }