[pypy-svn] r51646 - in pypy/branch/gc_hash/pypy: annotation rpython rpython/lltypesystem rpython/test

arigo at codespeak.net arigo at codespeak.net
Tue Feb 19 18:20:51 CET 2008


Author: arigo
Date: Tue Feb 19 18:20:51 2008
New Revision: 51646

Modified:
   pypy/branch/gc_hash/pypy/annotation/builtin.py
   pypy/branch/gc_hash/pypy/rpython/llinterp.py
   pypy/branch/gc_hash/pypy/rpython/lltypesystem/llheap.py
   pypy/branch/gc_hash/pypy/rpython/lltypesystem/lloperation.py
   pypy/branch/gc_hash/pypy/rpython/lltypesystem/lltype.py
   pypy/branch/gc_hash/pypy/rpython/lltypesystem/rclass.py
   pypy/branch/gc_hash/pypy/rpython/rbuiltin.py
   pypy/branch/gc_hash/pypy/rpython/test/test_rclass.py
   pypy/branch/gc_hash/pypy/rpython/test/test_rptr.py
Log:
Add the gc_hash operation and use hash_cache in rclass.py.


Modified: pypy/branch/gc_hash/pypy/annotation/builtin.py
==============================================================================
--- pypy/branch/gc_hash/pypy/annotation/builtin.py	(original)
+++ pypy/branch/gc_hash/pypy/annotation/builtin.py	Tue Feb 19 18:20:51 2008
@@ -487,6 +487,11 @@
     assert isinstance(s_p, SomePtr), "runtime_type_info of non-pointer: %r" % s_p
     return SomePtr(lltype.typeOf(lltype.runtime_type_info(s_p.ll_ptrtype._example())))
 
+def hash_gc_object(s_p):
+    assert isinstance(s_p, SomePtr), "hash_gc_object of non-pointer: %r" % s_p
+    lltype.hash_gc_object(s_p.ll_ptrtype._defl())    # for the checks
+    return SomeInteger()
+
 def constPtr(T):
     assert T.is_constant()
     return immutablevalue(lltype.Ptr(T.const))
@@ -505,6 +510,7 @@
 BUILTIN_ANALYZERS[lltype.cast_int_to_ptr] = cast_int_to_ptr
 BUILTIN_ANALYZERS[lltype.getRuntimeTypeInfo] = getRuntimeTypeInfo
 BUILTIN_ANALYZERS[lltype.runtime_type_info] = runtime_type_info
+BUILTIN_ANALYZERS[lltype.hash_gc_object] = hash_gc_object
 BUILTIN_ANALYZERS[lltype.Ptr] = constPtr
 
 # ootype

Modified: pypy/branch/gc_hash/pypy/rpython/llinterp.py
==============================================================================
--- pypy/branch/gc_hash/pypy/rpython/llinterp.py	(original)
+++ pypy/branch/gc_hash/pypy/rpython/llinterp.py	Tue Feb 19 18:20:51 2008
@@ -791,6 +791,9 @@
     def op_gc_id(self, v_ptr):
         return self.heap.gc_id(v_ptr)
 
+    def op_gc_hash(self, v_ptr):
+        return self.heap.gc_hash(v_ptr)
+
     def op_gc_set_max_heap_size(self, maxsize):
         raise NotImplementedError("gc_set_max_heap_size")
 

Modified: pypy/branch/gc_hash/pypy/rpython/lltypesystem/llheap.py
==============================================================================
--- pypy/branch/gc_hash/pypy/rpython/lltypesystem/llheap.py	(original)
+++ pypy/branch/gc_hash/pypy/rpython/lltypesystem/llheap.py	Tue Feb 19 18:20:51 2008
@@ -16,6 +16,7 @@
     inneraddr.ref()[0] = newvalue
 
 from pypy.rpython.lltypesystem.lltype import cast_ptr_to_int as gc_id
+from pypy.rpython.lltypesystem.lltype import hash_gc_object as gc_hash
 
 def weakref_create_getlazy(objgetter):
     return weakref_create(objgetter())

Modified: pypy/branch/gc_hash/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/branch/gc_hash/pypy/rpython/lltypesystem/lloperation.py	(original)
+++ pypy/branch/gc_hash/pypy/rpython/lltypesystem/lloperation.py	Tue Feb 19 18:20:51 2008
@@ -396,6 +396,7 @@
     'gc_pop_alive_pyobj':   LLOp(),
     'gc_reload_possibly_moved': LLOp(),
     'gc_id':                LLOp(canraise=(MemoryError,), sideeffects=False),
+    'gc_hash':              LLOp(sideeffects=False),
     'gc_set_max_heap_size': LLOp(),
     # experimental operations in support of thread cloning, only
     # implemented by the Mark&Sweep GC

Modified: pypy/branch/gc_hash/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/branch/gc_hash/pypy/rpython/lltypesystem/lltype.py	(original)
+++ pypy/branch/gc_hash/pypy/rpython/lltypesystem/lltype.py	Tue Feb 19 18:20:51 2008
@@ -143,6 +143,7 @@
 
 class ContainerType(LowLevelType):
     _adtmeths = {}
+    _hash_cache = False
 
     def _inline_is_varsize(self, last):
         raise TypeError, "%r cannot be inlined in structure" % self
@@ -310,7 +311,6 @@
 
 class GcStruct(RttiStruct):
     _gckind = 'gc'
-    _hash_cache = False
 
     def _install_extras(self, hash_cache=False, **extras):
         RttiStruct._install_extras(self, **extras)
@@ -1859,7 +1859,7 @@
     try:
         return container._hash_cache_
     except AttributeError:
-        result = container._hash_cache_ = intmask(id(container))
+        result = container._hash_cache_ = cast_ptr_to_int(p)
         return result
 
 def init_hash_gc_object(p, value):

Modified: pypy/branch/gc_hash/pypy/rpython/lltypesystem/rclass.py
==============================================================================
--- pypy/branch/gc_hash/pypy/rpython/lltypesystem/rclass.py	(original)
+++ pypy/branch/gc_hash/pypy/rpython/lltypesystem/rclass.py	Tue Feb 19 18:20:51 2008
@@ -330,10 +330,7 @@
                     llfields.append((mangled_name, r.lowleveltype))
             #
             # hash() support
-            if self.rtyper.needs_hash_support(self.classdef):
-                from pypy.rpython import rint
-                fields['_hash_cache_'] = 'hash_cache', rint.signed_repr
-                llfields.append(('hash_cache', Signed))
+            hash_cache = self.rtyper.needs_hash_support(self.classdef)
 
             self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef,
                                          self.gcflavor)
@@ -351,6 +348,7 @@
                                    ('super', self.rbase.object_type),
                                    hints=hints,
                                    adtmeths=adtmeths,
+                                   hash_cache=hash_cache,
                                    *llfields)
             self.object_type.become(object_type)
             allinstancefields.update(self.rbase.allinstancefields)
@@ -402,7 +400,7 @@
             except AttributeError:
                 INSPTR = self.lowleveltype
                 def _ll_hash_function(ins):
-                    return ll_inst_hash(cast_pointer(INSPTR, ins))
+                    return lltype.hash_gc_object(cast_pointer(INSPTR, ins))
                 self._ll_hash_function = _ll_hash_function
                 return _ll_hash_function
         else:
@@ -417,8 +415,6 @@
             for name, (mangled_name, r) in self.fields.items():
                 if r.lowleveltype is Void:
                     llattrvalue = None
-                elif name == '_hash_cache_': # hash() support
-                    llattrvalue = hash(value)
                 else:
                     try:
                         attrvalue = getattr(value, name)
@@ -433,6 +429,10 @@
                     else:
                         llattrvalue = r.convert_const(attrvalue)
                 setattr(result, mangled_name, llattrvalue)
+            # hash support
+            if self.rtyper.needs_hash_support(self.classdef):
+                llhashvalue = hash(value)
+                lltype.init_hash_gc_object(result, llhashvalue)
         else:
             # OBJECT part
             rclass = getclassrepr(self.rtyper, classdef)
@@ -498,10 +498,7 @@
                 mangled_name, r = self.allinstancefields[fldname]
                 if r.lowleveltype is Void:
                     continue
-                if fldname == '_hash_cache_':
-                    value = Constant(0, Signed)
-                else:
-                    value = self.classdef.classdesc.read_attribute(fldname, None)
+                value = self.classdef.classdesc.read_attribute(fldname, None)
                 if value is not None:
                     cvalue = inputconst(r.lowleveltype,
                                         r.convert_desc_or_const(value))
@@ -696,18 +693,6 @@
 def ll_runtime_type_info(obj):
     return obj.typeptr.rtti
 
-def ll_inst_hash(ins):
-    if not ins:
-        return 0    # for None
-    cached = ins.hash_cache
-    if cached == 0:
-        # XXX this should ideally be done in a GC-dependent way: we only
-        # need a hash_cache for moving GCs, and we only need the '~' to
-        # avoid Boehm keeping the object alive if the value is passed
-        # around
-       cached = ins.hash_cache = ~cast_ptr_to_int(ins)
-    return cached
-
 def ll_inst_type(obj):
     if obj:
         return obj.typeptr

Modified: pypy/branch/gc_hash/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/branch/gc_hash/pypy/rpython/rbuiltin.py	(original)
+++ pypy/branch/gc_hash/pypy/rpython/rbuiltin.py	Tue Feb 19 18:20:51 2008
@@ -479,6 +479,12 @@
     return hop.genop('runtime_type_info', vlist,
                      resulttype = hop.r_result.lowleveltype)
 
+def rtype_hash_gc_object(hop):
+    assert isinstance(hop.args_r[0], rptr.PtrRepr)
+    vlist = hop.inputargs(hop.args_r[0])
+    return hop.genop('gc_hash', vlist,
+                     resulttype = lltype.Signed)
+
 BUILTIN_TYPER[lltype.malloc] = rtype_malloc
 BUILTIN_TYPER[lltype.free] = rtype_free
 BUILTIN_TYPER[lltype.cast_primitive] = rtype_cast_primitive
@@ -494,6 +500,7 @@
 BUILTIN_TYPER[lltype.getRuntimeTypeInfo] = rtype_const_result
 BUILTIN_TYPER[lltype.Ptr] = rtype_const_result
 BUILTIN_TYPER[lltype.runtime_type_info] = rtype_runtime_type_info
+BUILTIN_TYPER[lltype.hash_gc_object] = rtype_hash_gc_object
 BUILTIN_TYPER[rarithmetic.intmask] = rtype_intmask
 BUILTIN_TYPER[objectmodel.we_are_translated] = rtype_we_are_translated
 

Modified: pypy/branch/gc_hash/pypy/rpython/test/test_rclass.py
==============================================================================
--- pypy/branch/gc_hash/pypy/rpython/test/test_rclass.py	(original)
+++ pypy/branch/gc_hash/pypy/rpython/test/test_rclass.py	Tue Feb 19 18:20:51 2008
@@ -403,10 +403,8 @@
 
         res = self.interpret(f, [])
         # xxx this is too precise, checking the exact implementation
-        if isinstance(self, OORtypeMixin):
-            assert res.item0 == res.item1
-        else:
-            assert res.item0 == ~res.item1
+        # but it works on top of lltype.py and ootype.py
+        assert res.item0 == res.item1
         # the following property is essential on top of the lltypesystem
         # otherwise prebuilt dictionaries are broken.  It's not that
         # relevant on top of the ootypesystem though.

Modified: pypy/branch/gc_hash/pypy/rpython/test/test_rptr.py
==============================================================================
--- pypy/branch/gc_hash/pypy/rpython/test/test_rptr.py	(original)
+++ pypy/branch/gc_hash/pypy/rpython/test/test_rptr.py	Tue Feb 19 18:20:51 2008
@@ -313,3 +313,25 @@
     res = interpret(f, [])
     assert res == 1
  
+def test_hash_gc_object():
+    T = GcStruct('T', ('x', Signed))
+    t1 = malloc(T)
+    t2 = malloc(T)
+    hash1 = hash_gc_object(t1)
+    def gethash(p): # indirection to prevent constant-folding by the flow space
+        return hash_gc_object(p)
+    def f():
+        t3 = malloc(T)
+        hash1 = gethash(t1)
+        hash2 = gethash(t2)
+        hash3 = gethash(t3)
+        assert hash1 == gethash(t1)
+        assert hash2 == gethash(t2)
+        assert hash3 == gethash(t3)
+        assert hash1 == hash_gc_object(t1)
+        assert hash2 == hash_gc_object(t2)
+        assert hash3 == hash_gc_object(t3)
+        return hash1
+
+    res = interpret(f, [])
+    assert res == hash1



More information about the Pypy-commit mailing list