[pypy-commit] stmgc default: Finish support for big objects (missing: LARGE objects, the ones too big for the nursery)

arigo noreply at buildbot.pypy.org
Wed Jun 26 21:19:11 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r292:aa1ae03711e1
Date: 2013-06-26 21:18 +0200
http://bitbucket.org/pypy/stmgc/changeset/aa1ae03711e1/

Log:	Finish support for big objects (missing: LARGE objects, the ones too
	big for the nursery)

diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -552,9 +552,24 @@
 static void free_unused_local_pages(struct tx_public_descriptor *gcp)
 {
     int i;
+    wlog_t *item;
+
     for (i = 1; i < GC_SMALL_REQUESTS; i++) {
         sweep_pages(gcp, i);
     }
+
+    G2L_LOOP_FORWARD(gcp->nonsmall_objects, item) {
+
+        gcptr p = item->addr;
+        if (p->h_tid & GCFLAG_VISITED) {
+            p->h_tid &= ~GCFLAG_VISITED;
+        }
+        else {
+            g2l_mark_as_deleted(item);
+            stm_free(p, stmgc_size(p));
+        }
+
+    } G2L_LOOP_END;
 }
 
 static void free_all_unused_local_pages(void)
@@ -567,7 +582,6 @@
 
 static void free_closed_thread_descriptors(void)
 {
-    int i;
     struct tx_public_descriptor *gcp;
     revision_t index = -1;
 
diff --git a/c4/test/support.py b/c4/test/support.py
--- a/c4/test/support.py
+++ b/c4/test/support.py
@@ -133,7 +133,8 @@
     int gettid(gcptr obj)
     {
         int result = stm_get_tid(obj);
-        assert(0 <= result && result < 521);
+        assert((0 <= result && result < 2000) ||
+               (42142 <= result && result < 42142 + 2000));
         return result;
     }
 
@@ -144,14 +145,14 @@
 
     gcptr rawgetptr(gcptr obj, long index)
     {
-        assert(gettid(obj) > 421 + index);
+        assert(gettid(obj) > 42142 + index);
         return ((gcptr *)(obj + 1))[index];
     }
 
     void rawsetptr(gcptr obj, long index, gcptr newvalue)
     {
         fprintf(stderr, "%p->[%ld] = %p\n", obj, index, newvalue);
-        assert(gettid(obj) > 421 + index);
+        assert(gettid(obj) > 42142 + index);
         ((gcptr *)(obj + 1))[index] = newvalue;
     }
 
@@ -249,13 +250,13 @@
 
     size_t stmcb_size(gcptr obj)
     {
-        if (gettid(obj) < 421) {
+        if (gettid(obj) < 42142) {
             /* basic case: tid equals 42 plus the size of the object */
             assert(gettid(obj) >= 42 + sizeof(struct stm_object_s));
             return gettid(obj) - 42;
         }
         else {
-            int nrefs = gettid(obj) - 421;
+            int nrefs = gettid(obj) - 42142;
             assert(nrefs < 100);
             return sizeof(*obj) + nrefs * sizeof(gcptr);
         }
@@ -264,11 +265,11 @@
     void stmcb_trace(gcptr obj, void visit(gcptr *))
     {
         int i;
-        if (gettid(obj) < 421) {
+        if (gettid(obj) < 42142) {
             /* basic case: no references */
             return;
         }
-        for (i=0; i < gettid(obj) - 421; i++) {
+        for (i=0; i < gettid(obj) - 42142; i++) {
             gcptr *ref = ((gcptr *)(obj + 1)) + i;
             visit(ref);
         }
@@ -459,7 +460,7 @@
     p = lib.stmgcpage_malloc(HDR + WORD * nrefs)
     p.h_tid = GCFLAG_OLD | GCFLAG_WRITE_BARRIER
     p.h_revision = -sys.maxint
-    lib.settid(p, 421 + nrefs)
+    lib.settid(p, 42142 + nrefs)
     for i in range(nrefs):
         rawsetptr(p, i, ffi.NULL)
     return p
@@ -475,7 +476,7 @@
 
 def nalloc_refs(nrefs):
     "Allocate a fresh object from the nursery, with nrefs pointers"
-    p = lib.stm_allocate(HDR + WORD * nrefs, 421 + nrefs)
+    p = lib.stm_allocate(HDR + WORD * nrefs, 42142 + nrefs)
     assert p.h_revision == lib.get_private_rev_num()
     for i in range(nrefs):
         assert rawgetptr(p, i) == ffi.NULL   # must already be zero-filled
@@ -493,10 +494,10 @@
 def palloc_refs(nrefs, prehash=None):
     "Get a ``prebuilt'' object with nrefs pointers."
     if prehash is None:
-        p = lib.pseudoprebuilt(HDR + WORD * nrefs, 421 + nrefs)
+        p = lib.pseudoprebuilt(HDR + WORD * nrefs, 42142 + nrefs)
     else:
         p = lib.pseudoprebuilt_with_hash(HDR + WORD * nrefs,
-                                         421 + nrefs, prehash)
+                                         42142 + nrefs, prehash)
     return p
 
 gettid = lib.gettid
@@ -518,7 +519,8 @@
 
 def check_not_free(p):
     #print >> sys.stderr, "[checking %r..." % p,
-    assert 42 < (p.h_tid & 0xFFFF) < 521
+    assert ((42 < (p.h_tid & 0xFFFF) < 2000) or
+            (42142 <= (p.h_tid & 0xFFFF) < 42142 + 2000))
     #print >> sys.stderr, "ok]"
 
 def check_nursery_free(p):
@@ -539,7 +541,7 @@
         DEBUG_WORD(0x55), DEBUG_WORD(0xAA))
 
 def check_prebuilt(p):
-    assert 42 < (p.h_tid & 0xFFFF) < 521
+    check_not_free(p)
     assert p.h_tid & GCFLAG_PREBUILT_ORIGINAL
 
 def delegate(p1, p2):
diff --git a/c4/test/test_gcpage.py b/c4/test/test_gcpage.py
--- a/c4/test/test_gcpage.py
+++ b/c4/test/test_gcpage.py
@@ -415,26 +415,29 @@
     check_not_free(p1b)
 
 def test_big_old_object():
-    p1 = oalloc(HDR + 50 * WORD)
+    for words in range(80):
+        p1 = oalloc(HDR + words * WORD)
     # assert did not crash
 
 def test_big_old_object_free():
-    p1 = oalloc(HDR + 50 * WORD)
-    p1b = lib.stm_write_barrier(p1)
-    assert p1b == p1
-    lib.stm_commit_transaction()
-    lib.stm_begin_inevitable_transaction()
+    for words in range(80):
+        p1 = oalloc(HDR + words * WORD)
+        p1b = lib.stm_write_barrier(p1)
+        assert p1b == p1
+        lib.stm_commit_transaction()
+        lib.stm_begin_inevitable_transaction()
 
 def test_big_old_object_collect():
-    p1 = oalloc(HDR + 50 * WORD)
-    lib.stm_push_root(p1)
-    major_collect()
-    p1b = lib.stm_pop_root()
-    assert p1b == p1
-    check_not_free(p1)
-    #
-    major_collect()
-    check_free_old(p1)
-    #
-    major_collect()
-    check_free_old(p1)
+    for words in range(80):
+        p1 = oalloc(HDR + words * WORD)
+        lib.stm_push_root(p1)
+        major_collect()
+        p1b = lib.stm_pop_root()
+        assert p1b == p1
+        check_not_free(p1)
+        #
+        major_collect()
+        check_free_old(p1)
+        #
+        major_collect()
+        check_free_old(p1)


More information about the pypy-commit mailing list