[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