[pypy-svn] r68389 - in pypy/branch/gc-hash/pypy: rpython/memory/gctransform translator/c translator/c/test

arigo at codespeak.net arigo at codespeak.net
Tue Oct 13 18:03:05 CEST 2009


Author: arigo
Date: Tue Oct 13 18:03:05 2009
New Revision: 68389

Modified:
   pypy/branch/gc-hash/pypy/rpython/memory/gctransform/boehm.py
   pypy/branch/gc-hash/pypy/rpython/memory/gctransform/refcounting.py
   pypy/branch/gc-hash/pypy/translator/c/gc.py
   pypy/branch/gc-hash/pypy/translator/c/test/test_boehm.py
Log:
A lot of copy & paste to make test_hash_preservation pass on Boehm.


Modified: pypy/branch/gc-hash/pypy/rpython/memory/gctransform/boehm.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/memory/gctransform/boehm.py	(original)
+++ pypy/branch/gc-hash/pypy/rpython/memory/gctransform/boehm.py	Tue Oct 13 18:03:05 2009
@@ -10,6 +10,7 @@
 class BoehmGCTransformer(GCTransformer):
     malloc_zero_filled = True
     FINALIZER_PTR = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Void))
+    HDR = lltype.Struct("header", ("hash", lltype.Signed))
 
     def __init__(self, translator, inline=False):
         super(BoehmGCTransformer, self).__init__(translator, inline=inline)
@@ -34,6 +35,15 @@
 
         ll_realloc = mh.ll_realloc
 
+        HDRPTR = lltype.Ptr(self.HDR)
+
+        def ll_identityhash(addr):
+            obj = llmemory.cast_adr_to_ptr(addr, HDRPTR)
+            h = obj.hash
+            if h == 0:
+                obj.hash = h = ~llmemory.cast_adr_to_int(addr)
+            return h
+
         if self.translator:
             self.malloc_fixedsize_ptr = self.inittime_helper(
                 ll_malloc_fixedsize, [lltype.Signed], llmemory.Address)
@@ -51,6 +61,9 @@
             self.realloc_ptr = self.inittime_helper(
                 ll_realloc, [llmemory.Address] + [lltype.Signed] * 4,
                 llmemory.Address)
+            self.identityhash_ptr = self.inittime_helper(
+                ll_identityhash, [llmemory.Address], lltype.Signed,
+                inline=False)
             self.mixlevelannotator.finish()   # for now
             self.mixlevelannotator.backend_optimize()
 
@@ -154,6 +167,13 @@
                            resulttype=llmemory.Address)
         hop.cast_result(v_addr)
 
+    def gct_gc_identityhash(self, hop):
+        v_obj = hop.spaceop.args[0]
+        v_adr = hop.genop("cast_ptr_to_adr", [v_obj],
+                          resulttype=llmemory.Address)
+        hop.genop("direct_call", [self.identityhash_ptr, v_adr],
+                  resultvar=hop.spaceop.result)
+
     def gct_gc_id(self, hop):
         # this is the logic from the HIDE_POINTER macro in <gc/gc.h>
         v_int = hop.genop('cast_ptr_to_int', [hop.spaceop.args[0]],

Modified: pypy/branch/gc-hash/pypy/rpython/memory/gctransform/refcounting.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/memory/gctransform/refcounting.py	(original)
+++ pypy/branch/gc-hash/pypy/rpython/memory/gctransform/refcounting.py	Tue Oct 13 18:03:05 2009
@@ -300,6 +300,7 @@
 
     def gct_gc_identityhash(self, hop):
         v_obj = hop.spaceop.args[0]
-        v_adr = gen_cast(hop.llops, llmemory.Address, v_obj)
+        v_adr = hop.genop("cast_ptr_to_adr", [v_obj],
+                          resulttype=llmemory.Address)
         hop.genop("direct_call", [self.identityhash_ptr, v_adr],
                   resultvar=hop.spaceop.result)

Modified: pypy/branch/gc-hash/pypy/translator/c/gc.py
==============================================================================
--- pypy/branch/gc-hash/pypy/translator/c/gc.py	(original)
+++ pypy/branch/gc-hash/pypy/translator/c/gc.py	Tue Oct 13 18:03:05 2009
@@ -18,10 +18,17 @@
         self.thread_enabled = thread_enabled
 
     def common_gcheader_definition(self, defnode):
-        return []
+        if defnode.db.gctransformer is not None:
+            HDR = defnode.db.gctransformer.HDR
+            return [(name, HDR._flds[name]) for name in HDR._names]
+        else:
+            return []
 
     def common_gcheader_initdata(self, defnode):
-        return []
+        if defnode.db.gctransformer is not None:
+            raise NotImplementedError
+        else:
+            return []
 
     def struct_gcheader_definition(self, defnode):
         return self.common_gcheader_definition(defnode)
@@ -102,13 +109,6 @@
 class RefcountingGcPolicy(BasicGcPolicy):
     transformerclass = refcounting.RefcountingGCTransformer
 
-    def common_gcheader_definition(self, defnode):
-        if defnode.db.gctransformer is not None:
-            HDR = defnode.db.gctransformer.HDR
-            return [(name, HDR._flds[name]) for name in HDR._names]
-        else:
-            return []
-
     def common_gcheader_initdata(self, defnode):
         if defnode.db.gctransformer is not None:
             gct = defnode.db.gctransformer
@@ -193,6 +193,15 @@
 class BoehmGcPolicy(BasicGcPolicy):
     transformerclass = boehm.BoehmGCTransformer
 
+    def common_gcheader_initdata(self, defnode):
+        if defnode.db.gctransformer is not None:
+            return [lltype.identityhash(defnode.obj._as_ptr())]
+        else:
+            return []
+
+    def get_header_fields(self, obj):
+        return [lltype.identityhash(obj._as_ptr())]
+
     def array_setup(self, arraydefnode):
         pass
 

Modified: pypy/branch/gc-hash/pypy/translator/c/test/test_boehm.py
==============================================================================
--- pypy/branch/gc-hash/pypy/translator/c/test/test_boehm.py	(original)
+++ pypy/branch/gc-hash/pypy/translator/c/test/test_boehm.py	Tue Oct 13 18:03:05 2009
@@ -422,3 +422,31 @@
             return True
         run = self.getcompiled(f)
         assert run() == True        
+
+    def test_hash_preservation(self):
+        from pypy.rlib.objectmodel import compute_hash
+        from pypy.rlib.objectmodel import current_object_addr_as_int
+        class C:
+            pass
+        class D(C):
+            pass
+        c = C()
+        d = D()
+        compute_hash(d)     # force to be cached on 'd', but not on 'c'
+        #
+        def fn():
+            d2 = D()
+            return (compute_hash(d2),
+                    current_object_addr_as_int(d2),
+                    compute_hash(c),
+                    compute_hash(d),
+                    compute_hash(("Hi", None, (7.5, 2, d))))
+        
+        f = self.getcompiled(fn)
+        res = f()
+
+        # xxx the next line is too precise, checking the exact implementation
+        assert res[0] == ~res[1]
+        assert res[2] != compute_hash(c)     # likely
+        assert res[3] == compute_hash(d)
+        assert res[4] == compute_hash(("Hi", None, (7.5, 2, d)))



More information about the Pypy-commit mailing list