[pypy-commit] stmgc default: In inevitable transactions, clear the list_of_read_objects when

arigo noreply at buildbot.pypy.org
Thu Jun 20 16:11:30 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r210:8065a37d6daa
Date: 2013-06-20 16:11 +0200
http://bitbucket.org/pypy/stmgc/changeset/8065a37d6daa/

Log:	In inevitable transactions, clear the list_of_read_objects when
	collecting, rather than fixing it.

diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -339,6 +339,11 @@
     if (d->active < 0)
         return;       /* already "aborted" during forced minor collection */
 
+    if (d->active == 2) {
+        /* inevitable transaction: clear the list of read objects */
+        gcptrlist_clear(&d->list_of_read_objects);
+    }
+
     for (i = d->list_of_read_objects.size - 1; i >= 0; --i) {
         gcptr obj = items[i];
 
@@ -357,16 +362,13 @@
             return;
         }
 
-        /* on the other hand, if we see a non-visited object in the read
-           list, then we need to remove it --- it's wrong to just abort.
-           Consider the following case: the transaction is inevitable,
-           and since it started, it popped objects out of its shadow
-           stack.  Some popped objects might become free even if they
-           have been read from.  We must not abort such transactions
-           (and cannot anyway: they are inevitable!). */
-        if (!(obj->h_tid & GCFLAG_VISITED)) {
-            items[i] = items[--d->list_of_read_objects.size];
-        }
+        /* It should not be possible to see a non-visited object in the
+           read list.  I think the only case is: the transaction is
+           inevitable, and since it started, it popped objects out of
+           its shadow stack.  Some popped objects might become free even
+           if they have been read from.  But for inevitable transactions,
+           we clear the 'list_of_read_objects' above anyway. */
+        assert(obj->h_tid & GCFLAG_VISITED);
     }
 
     d->num_read_objects_known_old = d->list_of_read_objects.size;
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -281,6 +281,11 @@
     gcptr *items = d->list_of_read_objects.items;
     assert(d->list_of_read_objects.size >= limit);
 
+    if (d->active == 2) {
+        /* inevitable transaction: clear the list of read objects */
+        gcptrlist_clear(&d->list_of_read_objects);
+    }
+
     for (i = d->list_of_read_objects.size - 1; i >= limit; --i) {
         gcptr obj = items[i];
 


More information about the pypy-commit mailing list