[pypy-commit] stmgc default: Copying the hash/id logic from minimark.py, first part

arigo noreply at buildbot.pypy.org
Wed Mar 5 09:34:10 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r955:8185ee16c279
Date: 2014-03-05 08:24 +0100
http://bitbucket.org/pypy/stmgc/changeset/8185ee16c279/

Log:	Copying the hash/id logic from minimark.py, first part

diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -46,6 +46,14 @@
     */
     GCFLAG_SMALL_UNIFORM = 0x02,
 
+    /* The following flag is set on nursery objects of which we asked
+       the id or the identityhash.  It means that a space of the size of
+       the object has already been allocated in the nonmovable part.
+       The same flag is abused to mark prebuilt objects whose hash has
+       been taken during translation and is statically recorded just
+       after the object. */
+    GCFLAG_HAS_SHADOW = 0x04,
+
     /* All remaining bits of the 32-bit 'stm_flags' field are taken by
        the "overflow number".  This is a number that identifies the
        "overflow objects" from the current transaction among all old
@@ -53,7 +61,7 @@
        current transaction that have been flushed out of the nursery,
        which occurs if the same transaction allocates too many objects.
     */
-    GCFLAG_OVERFLOW_NUMBER_bit0 = 0x04   /* must be last */
+    GCFLAG_OVERFLOW_NUMBER_bit0 = 0x08   /* must be last */
 };
 
 
diff --git a/c7/stm/prebuilt.c b/c7/stm/prebuilt.c
--- a/c7/stm/prebuilt.c
+++ b/c7/stm/prebuilt.c
@@ -27,9 +27,10 @@
         return;
     }
 
-    /* We need to make a copy of this object. */
+    /* We need to make a copy of this object.  The extra "long" is for
+       the prebuilt hash. */
     size_t size = stmcb_size_rounded_up(obj);
-    object_t *nobj = _stm_allocate_old(size);
+    object_t *nobj = _stm_allocate_old(size + sizeof(long));
 
     /* Copy the object */
     char *realnobj = REAL_ADDRESS(stm_object_pages, nobj);
diff --git a/c7/stmgc.c b/c7/stmgc.c
--- a/c7/stmgc.c
+++ b/c7/stmgc.c
@@ -22,6 +22,7 @@
 #include "stm/nursery.c"
 #include "stm/sync.c"
 #include "stm/setup.c"
+#include "stm/hash_id.c"
 #include "stm/core.c"
 #include "stm/contention.c"
 #include "stm/fprintcolor.c"
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -261,6 +261,14 @@
    static structure, but it should never be used anyway.) */
 object_t *stm_setup_prebuilt(object_t *);
 
+/* Hash, id.  The id is just the address of the object (of the address
+   where it *will* be after the next minor collection).  The hash is the
+   same, mangled -- except on prebuilt objects, where it can be
+   controlled for each prebuilt object individually.  (Useful uor PyPy) */
+long stm_identityhash(object_t *obj);
+long stm_id(object_t *obj);
+void stm_set_prebuilt_identityhash(object_t *obj, uint64_t hash);
+
 
 /* ==================== END ==================== */
 
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -74,6 +74,10 @@
 
 void stm_collect(long level);
 uint64_t _stm_total_allocated(void);
+
+long stm_identityhash(object_t *obj);
+long stm_id(object_t *obj);
+void stm_set_prebuilt_identityhash(object_t *obj, uint64_t hash);
 """)
 
 
diff --git a/c7/test/test_hash_id.py b/c7/test/test_hash_id.py
new file mode 100644
--- /dev/null
+++ b/c7/test/test_hash_id.py
@@ -0,0 +1,39 @@
+from support import *
+from test_prebuilt import prebuilt
+import py
+
+class TestHashId(BaseTest):
+
+    def test_hash_old_object(self):
+        lp1 = stm_allocate_old(16)
+        lp2 = stm_allocate_old(16)
+        lp3 = stm_allocate_old(16)
+        lp4 = stm_allocate_old(16)
+        self.start_transaction()
+        h1 = lib.stm_identityhash(lp1)
+        h2 = lib.stm_identityhash(lp2)
+        h3 = lib.stm_identityhash(lp3)
+        h4 = lib.stm_identityhash(lp4)
+        assert len(set([h1, h2, h3, h4])) == 4     # guaranteed by the algo
+
+    def test_id_old_object(self):
+        lp1 = stm_allocate_old(16)
+        self.start_transaction()
+        h1 = lib.stm_id(lp1)
+        assert h1 == int(ffi.cast("long", lp1))
+
+    def test_set_prebuilt_identityhash(self):
+        static1 = prebuilt(16)
+        static2 = prebuilt(16)
+        lp1 = lib.stm_setup_prebuilt(static1)
+        lp2 = lib.stm_setup_prebuilt(static2)
+        lib.stm_set_prebuilt_identityhash(lp1, 42)
+        self.start_transaction()
+        h1 = lib.stm_identityhash(lp1)
+        h2 = lib.stm_identityhash(lp2)
+        assert h1 == 42
+        assert h2 != 0
+        h1 = lib.stm_id(lp1)
+        h2 = lib.stm_id(lp2)
+        assert h1 == int(ffi.cast("long", lp1))
+        assert h2 == int(ffi.cast("long", lp2))


More information about the pypy-commit mailing list