I believe that process_worklist() only needs to enforce the GC invariant if
the object moved.

The comment notes "In moving an object to generation 2"... but the code had
been doing the work for *all* objects in generation 2, not just those moved
there. We know whether we have just moved an object from the nursery to gen2,
so track that, and only walk the recently marked items for a newly moved
object.

I can't spot any assert()s that the invariant is enforced, so I don't know if
I've messed this up somehow. But it works on "my" machine (not tested with
"torture") and the setting compilation is faster.

Confirming how faster, and whether it's just the setting, is left as an
exercise for the reader :-)

Nicholas Clark
>From ace9d7a50510a85e8c7b63a17946a9e9bf027a84 Mon Sep 17 00:00:00 2001
From: Nicholas Clark <n...@ccl4.org>
Date: Tue, 28 Jan 2014 20:23:21 +0100
Subject: [PATCH] process_worklist() only needs to enforce the GC invariant if the object moved.

The comment notes "In moving an object to generation 2"... but the code had
been doing the work for *all* objects in generation 2, not just those moved
there. We know whether we have just moved an object from the nursery to gen2,
so track that, and only walk the recently marked items for a newly moved
object.
---
 src/gc/collect.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/src/gc/collect.c b/src/gc/collect.c
index abd9aa9..a88e985 100644
--- a/src/gc/collect.c
+++ b/src/gc/collect.c
@@ -160,6 +160,7 @@ static void process_worklist(MVMThreadContext *tc, MVMGCWorklist *worklist, Work
         /* Dereference the object we're considering. */
         MVMCollectable *item = *item_ptr;
         MVMuint8 item_gen2;
+        MVMuint8 to_gen2 = 0;
 
         /* If the item is NULL, that's fine - it's just a null reference and
          * thus we've no object to consider. */
@@ -227,6 +228,7 @@ static void process_worklist(MVMThreadContext *tc, MVMGCWorklist *worklist, Work
             if (item->flags & MVM_CF_NURSERY_SEEN) {
                 /* Yes; we should move it to the second generation. Allocate
                  * space in the second generation. */
+                to_gen2 = 1;
                 new_addr = MVM_gc_gen2_allocate(gen2, item->size);
 
                 /* Copy the object to the second generation and mark it as
@@ -288,7 +290,7 @@ static void process_worklist(MVMThreadContext *tc, MVMGCWorklist *worklist, Work
 
         /* In moving an object to generation 2, we may have left it pointing
          * to nursery objects. If so, make sure it's in the gen2 roots. */
-        if (new_addr->flags & MVM_CF_SECOND_GEN) {
+        if (to_gen2) {
             MVMCollectable **j;
             MVMuint32 max = worklist->items, k;
 
-- 
1.7.1

Reply via email to