[pypy-commit] stmgc default: Tests, asserts, and fixes for stm_allocate() returning correctly

arigo noreply at buildbot.pypy.org
Sat Jun 29 11:55:26 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r318:c856b6a0d157
Date: 2013-06-29 11:55 +0200
http://bitbucket.org/pypy/stmgc/changeset/c856b6a0d157/

Log:	Tests, asserts, and fixes for stm_allocate() returning correctly
	cleared memory.

diff --git a/c4/dbgmem.c b/c4/dbgmem.c
--- a/c4/dbgmem.c
+++ b/c4/dbgmem.c
@@ -64,6 +64,7 @@
 
     dprintf(("stm_malloc(%zu): %p\n", sz, result));
     assert(((intptr_t)(result + sz) & (PAGE_SIZE-1)) == 0);
+    memset(result, 0xBB, sz);
     return result;
 }
 
@@ -89,6 +90,13 @@
     return accessible_pages[base] == 42;
 }
 
+void assert_cleared(char *p, size_t size)
+{
+    size_t i;
+    for (i = 0; i < size; i++)
+        assert(p[i] == 0);
+}
+
 /************************************************************/
 #endif
 
@@ -97,6 +105,7 @@
                                   size_t already_cleared)
 {
     char *baseaddr = base;
+    assert(already_cleared <= size);
 
     if (size > 2 * PAGE_SIZE) {
         int lowbits = ((intptr_t)baseaddr) & (PAGE_SIZE-1);
@@ -127,4 +136,5 @@
     if (size > already_cleared) { /* clear the final misaligned part, if any */
         memset(baseaddr, 0, size - already_cleared);
     }
+    assert_cleared(base, size);
 }
diff --git a/c4/dbgmem.h b/c4/dbgmem.h
--- a/c4/dbgmem.h
+++ b/c4/dbgmem.h
@@ -7,11 +7,13 @@
 void *stm_malloc(size_t);
 void stm_free(void *, size_t);
 int _stm_can_access_memory(char *);
+void assert_cleared(char *, size_t);
 
 #else
 
 #define stm_malloc(sz)    malloc(sz)
 #define stm_free(p,sz)    free(p)
+#define assert_cleared(p,sz)     do { } while(0)
 
 #endif
 
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -72,6 +72,15 @@
         P = (gcptr)cur;
         P->h_tid = tid;
     }
+#ifdef _GC_DEBUG
+    if (P != NULL) {
+        assert(P->h_tid != 0);
+        assert_cleared(((char *)P) + sizeof(revision_t),
+                       size - sizeof(revision_t));
+    }
+    else
+        assert(tid == -1);
+#endif
     return P;
 }
 
@@ -538,18 +547,6 @@
     */
     teardown_minor_collect(d);
 
-    /* if in debugging mode, we allocate a different nursery and make
-       the old one inaccessible
-    */
-#if defined(_GC_DEBUG) && _GC_DEBUG >= 2
-    stm_free(d->nursery_base, GC_NURSERY);
-    d->nursery_base = stm_malloc(GC_NURSERY);
-    d->nursery_end = d->nursery_base + GC_NURSERY;
-    d->nursery_nextlimit = d->nursery_base;
-    dprintf(("minor: nursery moved to [%p to %p]\n", d->nursery_base,
-             d->nursery_end));
-#endif
-
     /* When doing minor collections with the nursery "mostly empty",
        as occurs when other threads force major collections but this
        thread didn't do much at all, then we clear the nursery using
@@ -572,6 +569,20 @@
         d->nursery_cleared = NC_REGULAR;
     }
 
+    /* if in debugging mode, we allocate a different nursery and make
+       the old one inaccessible
+    */
+#if defined(_GC_DEBUG) && _GC_DEBUG >= 2
+    if (d->nursery_cleared == NC_ALREADY_CLEARED)
+        assert_cleared(d->nursery_base, GC_NURSERY);
+    stm_free(d->nursery_base, GC_NURSERY);
+    d->nursery_base = stm_malloc(GC_NURSERY);
+    d->nursery_end = d->nursery_base + GC_NURSERY;
+    dprintf(("minor: nursery moved to [%p to %p]\n", d->nursery_base,
+             d->nursery_end));
+    if (d->nursery_cleared == NC_ALREADY_CLEARED)
+        memset(d->nursery_base, 0, GC_NURSERY);
+#endif
     d->nursery_current = d->nursery_base;
     d->nursery_nextlimit = d->nursery_base;
 
@@ -640,6 +651,7 @@
 
         /* Allocate it externally, and make it old */
         gcptr P = stmgcpage_malloc(allocate_size);
+        memset(P, 0, allocate_size);
         P->h_tid = tid | GCFLAG_OLD;
         gcptrlist_insert(&d->old_objects_to_trace, P);
         return P;
@@ -672,5 +684,7 @@
     assert(d->nursery_current <= d->nursery_nextlimit);
 
     P->h_tid = tid;
+    assert_cleared(((char *)P) + sizeof(revision_t),
+                   allocate_size - sizeof(revision_t));
     return P;
 }
diff --git a/c4/test/support.py b/c4/test/support.py
--- a/c4/test/support.py
+++ b/c4/test/support.py
@@ -465,6 +465,7 @@
 def oalloc(size):
     "Allocate an 'old' protected object, outside any nursery"
     p = lib.stmgcpage_malloc(size)
+    lib.memset(p, 0, size)
     p.h_tid = GCFLAG_OLD | GCFLAG_WRITE_BARRIER
     p.h_revision = -sys.maxint
     lib.settid(p, 42 + size)
@@ -473,12 +474,12 @@
 def oalloc_refs(nrefs):
     """Allocate an 'old' protected object, outside any nursery,
     with nrefs pointers"""
-    p = lib.stmgcpage_malloc(HDR + WORD * nrefs)
+    size = HDR + WORD * nrefs
+    p = lib.stmgcpage_malloc(size)
+    lib.memset(p, 0, size)
     p.h_tid = GCFLAG_OLD | GCFLAG_WRITE_BARRIER
     p.h_revision = -sys.maxint
     lib.settid(p, 42142 + nrefs)
-    for i in range(nrefs):
-        rawsetptr(p, i, ffi.NULL)
     return p
 
 ofree = lib.stmgcpage_free
diff --git a/c4/test/test_nursery.py b/c4/test/test_nursery.py
--- a/c4/test/test_nursery.py
+++ b/c4/test/test_nursery.py
@@ -298,19 +298,23 @@
     assert lib.getlong(p2, 0) == 389719
 
 def test_nalloc_large_object():
-    for words in range(40, 81):
-        p1 = nalloc_refs(words)
-        lib.rawsetptr(p1, 0, p1)
-    p2 = nalloc(HDR)   # this alone should not collect
-    check_not_free(p1)
-    lib.rawsetptr(p1, 79, p2)
-    lib.stm_push_root(p1)
-    minor_collect()
-    p1b = lib.stm_pop_root()
-    assert p1b == p1
-    check_not_free(p1)
-    assert lib.rawgetptr(p1, 0) == p1
-    check_not_free(lib.rawgetptr(p1, 79))
+    for repeat in range(3):
+        for words in range(40, 81):
+            p1 = nalloc_refs(words)
+            for c in range(words):
+                assert lib.rawgetlong(p1, c) == 0     # null-initialized
+                lib.rawsetptr(p1, c, p1)
+        p2 = nalloc(HDR)   # this alone should not collect
+        check_not_free(p1)
+        lib.rawsetptr(p1, 79, p2)
+        lib.stm_push_root(p1)
+        minor_collect()
+        p1b = lib.stm_pop_root()
+        assert p1b == p1
+        check_not_free(p1)
+        assert lib.rawgetptr(p1, 0) == p1
+        check_not_free(lib.rawgetptr(p1, 79))
+        major_collect()
 
 def test_collect_soon():
     lib.stmgc_minor_collect_soon()


More information about the pypy-commit mailing list