]> 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 7be76101338e113a890cc4c74dceb41cc65f7960..c934984e01e304ba99941c0b801dd426c7b0f193 100644 (file)
@@ -2,20 +2,38 @@
 
 namespace factor {
 
-struct aging_policy {
+struct to_aging_copier : no_fixup {
   aging_space* aging;
   tenured_space* tenured;
 
-  explicit aging_policy(factor_vm* parent)
-      : aging(parent->data->aging), tenured(parent->data->tenured) {}
+  to_aging_copier(aging_space* aging, tenured_space* tenured)
+      : aging(aging), tenured(tenured) { }
 
-  bool should_copy_p(object* untagged) {
-    return !(aging->contains_p(untagged) || tenured->contains_p(untagged));
-  }
+  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;
+    }
 
-  void promoted_object(object* obj) {}
+    cell size = obj->size();
+    object* newpointer = aging->allot(size);
+    if (!newpointer)
+      throw must_start_gc_again();
 
-  void visited_object(object* obj) {}
+    memcpy(newpointer, obj, size);
+    obj->forward_to(newpointer);
+
+    return newpointer;
+  }
 };
 
 void factor_vm::collect_aging() {
@@ -23,45 +41,46 @@ void factor_vm::collect_aging() {
   // 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;
+    current_gc->op = COLLECT_TO_TENURED_OP;
 
-    gc_workhorse<tenured_space, to_tenured_policy>
-        workhorse(this, data->tenured, to_tenured_policy(this));
-    slot_visitor<gc_workhorse<tenured_space, to_tenured_policy>>
-        visitor(this, workhorse);
+    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_card_scan(visitor.cards_scanned, visitor.decks_scanned);
+    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_code_scan(code->points_to_aging.size());
-
+    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;
+    current_gc->op = COLLECT_AGING_OP;
 
     std::swap(data->aging, data->aging_semispace);
     data->reset_aging();
 
-    aging_space *target = data->aging;
-    gc_workhorse<aging_space, aging_policy>
-        workhorse(this, target, aging_policy(this));
-    slot_visitor<gc_workhorse<aging_space, aging_policy>>
-        visitor(this, workhorse);
-    cell scan = target->start + target->occupied_space();
+    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(target, scan);
+    visitor.cheneys_algorithm(aging, scan);
 
     data->reset_nursery();
     code->clear_remembered_set();