[pypy-svn] r68370 - in pypy/branch/gc-hash/pypy: annotation rpython rpython/lltypesystem rpython/lltypesystem/test rpython/ootypesystem rpython/ootypesystem/test

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


Author: arigo
Date: Tue Oct 13 13:28:16 2009
New Revision: 68370

Modified:
   pypy/branch/gc-hash/pypy/annotation/builtin.py
   pypy/branch/gc-hash/pypy/rpython/llinterp.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/lltypesystem/rstr.py
   pypy/branch/gc-hash/pypy/rpython/lltypesystem/test/test_lltype.py
   pypy/branch/gc-hash/pypy/rpython/ootypesystem/ooregistry.py
   pypy/branch/gc-hash/pypy/rpython/ootypesystem/ootype.py
   pypy/branch/gc-hash/pypy/rpython/ootypesystem/rbuiltin.py
   pypy/branch/gc-hash/pypy/rpython/ootypesystem/rclass.py
   pypy/branch/gc-hash/pypy/rpython/ootypesystem/rstr.py
   pypy/branch/gc-hash/pypy/rpython/ootypesystem/rtupletype.py
   pypy/branch/gc-hash/pypy/rpython/ootypesystem/test/test_ootype.py
   pypy/branch/gc-hash/pypy/rpython/rbuiltin.py
   pypy/branch/gc-hash/pypy/rpython/rclass.py
   pypy/branch/gc-hash/pypy/rpython/rdict.py
   pypy/branch/gc-hash/pypy/rpython/rtuple.py
   pypy/branch/gc-hash/pypy/rpython/rtyper.py
Log:
Refactor lltype and ootype to have only one method in common,
called identityhash().  Refactor rclass to no longer generate
the hash_cache field.


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 Oct 13 13:28:16 2009
@@ -493,6 +493,10 @@
     assert PtrT.is_constant()
     return SomePtr(ll_ptrtype=PtrT.const)
 
+def identityhash(s_obj):
+    assert isinstance(s_obj, (SomePtr, SomeOOObject, SomeOOInstance))
+    return SomeInteger()
+
 def getRuntimeTypeInfo(T):
     assert T.is_constant()
     return immutablevalue(lltype.getRuntimeTypeInfo(T.const))
@@ -517,6 +521,7 @@
 BUILTIN_ANALYZERS[lltype.direct_ptradd] = direct_ptradd
 BUILTIN_ANALYZERS[lltype.cast_ptr_to_int] = cast_ptr_to_int
 BUILTIN_ANALYZERS[lltype.cast_int_to_ptr] = cast_int_to_ptr
+BUILTIN_ANALYZERS[lltype.identityhash] = identityhash
 BUILTIN_ANALYZERS[lltype.getRuntimeTypeInfo] = getRuntimeTypeInfo
 BUILTIN_ANALYZERS[lltype.runtime_type_info] = runtime_type_info
 BUILTIN_ANALYZERS[lltype.Ptr] = constPtr
@@ -562,10 +567,6 @@
     else:
         return SomeOOInstance(c.ootype)
 
-def ooidentityhash(i):
-    assert isinstance(i, (SomeOOInstance, SomeOOObject))
-    return SomeInteger()
-
 def ooupcast(I, i):
     assert isinstance(I.const, ootype.Instance)
     if ootype.isSubclass(i.ootype, I.const):
@@ -606,7 +607,6 @@
 BUILTIN_ANALYZERS[ootype.runtimenew] = runtimenew
 BUILTIN_ANALYZERS[ootype.classof] = classof
 BUILTIN_ANALYZERS[ootype.subclassof] = subclassof
-BUILTIN_ANALYZERS[ootype.ooidentityhash] = ooidentityhash
 BUILTIN_ANALYZERS[ootype.ooupcast] = ooupcast
 BUILTIN_ANALYZERS[ootype.oodowncast] = oodowncast
 BUILTIN_ANALYZERS[ootype.cast_to_object] = cast_to_object

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 Oct 13 13:28:16 2009
@@ -801,6 +801,9 @@
         checkadr(adr)
         return llmemory.cast_adr_to_int(adr)
 
+    def op_identityhash(self, obj):
+        return lltype.identityhash(obj)
+
     def op_weakref_create(self, v_obj):
         def objgetter():    # special support for gcwrapper.py
             return self.getval(v_obj)
@@ -1180,9 +1183,6 @@
             raise RuntimeError("calling abstract method %r" % (m,))
         return self.perform_call(m, (lltype.typeOf(inst),)+lltype.typeOf(m).ARGS, [inst]+args)
 
-    def op_ooidentityhash(self, inst):
-        return ootype.ooidentityhash(inst)
-
     def op_oostring(self, obj, base):
         return ootype.oostring(obj, base)
 
@@ -1204,9 +1204,6 @@
         except ValueError:
             self.make_llexception()
 
-    def op_oohash(self, s):
-        return ootype.oohash(s)
-
 class Tracer(object):
     Counter = 0
     file = None

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 Oct 13 13:28:16 2009
@@ -378,6 +378,7 @@
     'direct_arrayitems':    LLOp(canfold=True),
     'direct_ptradd':        LLOp(canfold=True),
     'cast_opaque_ptr':      LLOp(sideeffects=False),
+    'identityhash':         LLOp(sideeffects=False),  # see rlib/objectmodel
 
     # __________ address operations __________
 
@@ -530,11 +531,9 @@
     'instanceof':           LLOp(oo=True, canfold=True),
     'classof':              LLOp(oo=True, canfold=True),
     'subclassof':           LLOp(oo=True, canfold=True),
-    'ooidentityhash':       LLOp(oo=True, sideeffects=False),  # not an id()!
     'oostring':             LLOp(oo=True, sideeffects=False),
     'ooparse_int':          LLOp(oo=True, canraise=(ValueError,)),
     'ooparse_float':        LLOp(oo=True, canraise=(ValueError,)),
-    'oohash':               LLOp(oo=True, sideeffects=False),
     'oounicode':            LLOp(oo=True, canraise=(UnicodeDecodeError,)),
 
     # _____ read frame var support ___

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 Oct 13 13:28:16 2009
@@ -1119,6 +1119,14 @@
             return callb(*args)
         raise TypeError("%r instance is not a function" % (self._T,))
 
+    def _identityhash(self):
+        p = normalizeptr(self)
+        try:
+            return p._obj._hash_cache_
+        except AttributeError:
+            result = p._obj._hash_cache_ = hash(p._obj)
+            return result
+
 class _ptr(_abstract_ptr):
     __slots__ = ('_TYPE', 
                  '_weak', '_solid',
@@ -1840,19 +1848,18 @@
                                  "should have been: %s" % (p, result2, result))
     return result
 
-def hash_gc_object(p):
-    """Returns the lltype-level hash of the given GcStruct."""
-    p = normalizeptr(p)
-    if not p:
-        return 0      # hash(NULL)
-    try:
-        return p._obj._hash_cache_
-    except AttributeError:
-        result = p._obj._hash_cache_ = intmask(id(p._obj))
-        return result
+def identityhash(p):
+    """Returns the lltype-level hash of the given GcStruct.
+    Also works with most ootype objects.  Not for NULL.
+    See rlib.objectmodel.compute_identiy_hash() for more
+    information about the RPython-level meaning of this.
+    """
+    assert p
+    return p._identityhash()
 
-def init_hash_gc_object(p, value):
+def init_identity_hash(p, value):
     """For a prebuilt object p, initialize its hash value to 'value'."""
+    assert isinstance(typeOf(p), Ptr)
     p = normalizeptr(p)
     if not p:
         raise ValueError("cannot change hash(NULL)!")

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 Oct 13 13:28:16 2009
@@ -20,6 +20,7 @@
 from pypy.rpython.extregistry import ExtRegistryEntry
 from pypy.annotation import model as annmodel
 from pypy.rlib.rarithmetic import intmask
+from pypy.rlib import objectmodel
 
 #
 #  There is one "vtable" per user class, with the following structure:
@@ -331,12 +332,6 @@
                     mangled_name = 'inst_' + name
                     fields[name] = mangled_name, r
                     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))
 
             self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef,
                                          self.gcflavor)
@@ -348,10 +343,6 @@
             if hints is None:
                 hints = {}
             hints = self._check_for_immutable_hints(hints)
-            if ('_hash_cache_' in fields or
-                '_hash_cache_' in self.rbase.allinstancefields):
-                adtmeths = adtmeths.copy()
-                adtmeths['gethash'] = self.get_ll_hash_function()
             object_type = MkStruct(self.classdef.name,
                                    ('super', self.rbase.object_type),
                                    hints=hints,
@@ -406,21 +397,6 @@
     def create_instance(self):
         return malloc(self.object_type, flavor=self.gcflavor)
 
-    def get_ll_hash_function(self):
-        if self.classdef is None:
-            raise TyperError, 'missing hash support flag in classdef'
-        if self.rtyper.needs_hash_support(self.classdef):
-            try:
-                return self._ll_hash_function
-            except AttributeError:
-                INSPTR = self.lowleveltype
-                def _ll_hash_function(ins):
-                    return ll_inst_hash(cast_pointer(INSPTR, ins))
-                self._ll_hash_function = _ll_hash_function
-                return _ll_hash_function
-        else:
-            return self.rbase.get_ll_hash_function()
-
     def initialize_prebuilt_data(self, value, classdef, result):
         if self.classdef is not None:
             # recursively build the parent part of the instance
@@ -429,8 +405,6 @@
             for name, (mangled_name, r) in self.fields.items():
                 if r.lowleveltype is Void:
                     llattrvalue = None
-                elif name == '_hash_cache_': # hash() support
-                    continue   # already done by initialize_prebuilt_hash()
                 else:
                     try:
                         attrvalue = getattr(value, name)
@@ -451,12 +425,9 @@
             result.typeptr = rclass.getvtable()
 
     def initialize_prebuilt_hash(self, value, result):
-        if self.classdef is not None:
-            self.rbase.initialize_prebuilt_hash(value, result.super)
-            if '_hash_cache_' in self.fields:
-                mangled_name, r = self.fields['_hash_cache_']
-                llattrvalue = hash(value)
-                setattr(result, mangled_name, llattrvalue)
+        llattrvalue = getattr(value, '__precomputed_identity_hash', None)
+        if llattrvalue is not None:
+            lltype.init_identity_hash(result, llattrvalue)
 
     def getfieldrepr(self, attr):
         """Return the repr used for the given attribute."""
@@ -523,10 +494,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))
@@ -697,18 +665,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/lltypesystem/rstr.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/lltypesystem/rstr.py	(original)
+++ pypy/branch/gc-hash/pypy/rpython/lltypesystem/rstr.py	Tue Oct 13 13:28:16 2009
@@ -2,9 +2,9 @@
 from pypy.tool.pairtype import pairtype
 from pypy.rpython.error import TyperError
 from pypy.rlib.objectmodel import malloc_zero_filled, we_are_translated
+from pypy.rlib.objectmodel import _hash_string
 from pypy.rlib.debug import ll_assert
 from pypy.rpython.robject import PyObjRepr, pyobj_repr
-from pypy.rlib.rarithmetic import _hash_string
 from pypy.rpython.rmodel import inputconst, IntegerRepr
 from pypy.rpython.rstr import AbstractStringRepr,AbstractCharRepr,\
      AbstractUniCharRepr, AbstractStringIteratorRepr,\

Modified: pypy/branch/gc-hash/pypy/rpython/lltypesystem/test/test_lltype.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/lltypesystem/test/test_lltype.py	(original)
+++ pypy/branch/gc-hash/pypy/rpython/lltypesystem/test/test_lltype.py	Tue Oct 13 13:28:16 2009
@@ -740,29 +740,31 @@
     import gc; gc.collect(); gc.collect()
     ptr2[0] = 5    # crashes if the array was deallocated
 
-def test_hash_gc_object():
+def test_identityhash():
     S = GcStruct('S', ('x', Signed))
     S2 = GcStruct('S2', ('super', S))
     S3 = GcStruct('S3', ('super', S2))
 
+    py.test.raises(AssertionError, identityhash, nullptr(S2))
+
     s3 = malloc(S3)
-    hash3 = hash_gc_object(s3.super)
-    assert hash3 == hash_gc_object(s3)
-    assert hash3 == hash_gc_object(s3.super)
-    assert hash3 == hash_gc_object(s3.super.super)
-    py.test.raises(ValueError, init_hash_gc_object, s3, hash3^1)
-    py.test.raises(ValueError, init_hash_gc_object, s3.super, hash3^4)
-    py.test.raises(ValueError, init_hash_gc_object, s3.super.super, hash3^9)
+    hash3 = identityhash(s3.super)
+    assert hash3 == identityhash(s3)
+    assert hash3 == identityhash(s3.super)
+    assert hash3 == identityhash(s3.super.super)
+    py.test.raises(ValueError, init_identity_hash, s3, hash3^1)
+    py.test.raises(ValueError, init_identity_hash, s3.super, hash3^4)
+    py.test.raises(ValueError, init_identity_hash, s3.super.super, hash3^9)
 
     s3 = malloc(S3)
-    init_hash_gc_object(s3.super, -123)
-    assert -123 == hash_gc_object(s3)
-    assert -123 == hash_gc_object(s3.super)
-    assert -123 == hash_gc_object(s3.super.super)
-    py.test.raises(ValueError, init_hash_gc_object, s3, 4313)
-    py.test.raises(ValueError, init_hash_gc_object, s3.super, 0)
-    py.test.raises(ValueError, init_hash_gc_object, s3.super.super, -124)
+    init_identity_hash(s3.super, -123)
+    assert -123 == identityhash(s3)
+    assert -123 == identityhash(s3.super)
+    assert -123 == identityhash(s3.super.super)
+    py.test.raises(ValueError, init_identity_hash, s3, 4313)
+    py.test.raises(ValueError, init_identity_hash, s3.super, 0)
+    py.test.raises(ValueError, init_identity_hash, s3.super.super, -124)
 
     from pypy.rpython.lltypesystem import llmemory
     p3 = cast_opaque_ptr(llmemory.GCREF, s3)
-    assert -123 == hash_gc_object(p3)
+    assert -123 == identityhash(p3)

Modified: pypy/branch/gc-hash/pypy/rpython/ootypesystem/ooregistry.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/ootypesystem/ooregistry.py	(original)
+++ pypy/branch/gc-hash/pypy/rpython/ootypesystem/ooregistry.py	Tue Oct 13 13:28:16 2009
@@ -81,21 +81,3 @@
         hop.has_implicit_exception(ValueError)
         hop.exception_is_here()
         return hop.genop('ooparse_float', vlist, resulttype = ootype.Float)
-
-
-class Entry_oohash(ExtRegistryEntry):
-    _about_ = ootype.oohash
-
-    def compute_result_annotation(self, str_s):
-        if not (isinstance(str_s, annmodel.SomeOOInstance)
-                and (str_s.ootype is ootype.String or
-                     str_s.ootype is ootype.Unicode)):
-            return annmodel.s_ImpossibleValue
-        return annmodel.SomeInteger()
-
-    def specialize_call(self, hop):
-        assert isinstance(hop.args_s[0], annmodel.SomeOOInstance)\
-               and (hop.args_s[0].ootype is ootype.String or
-                    hop.args_s[0].ootype is ootype.Unicode)
-        vlist = hop.inputargs(hop.args_r[0])
-        return hop.genop('oohash', vlist, resulttype=ootype.Signed)

Modified: pypy/branch/gc-hash/pypy/rpython/ootypesystem/ootype.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/ootypesystem/ootype.py	(original)
+++ pypy/branch/gc-hash/pypy/rpython/ootypesystem/ootype.py	Tue Oct 13 13:28:16 2009
@@ -4,6 +4,7 @@
 from pypy.rpython.lltypesystem.lltype import Bool, Void, UniChar, typeOf, \
         Primitive, isCompatibleType, enforce, saferecursive, SignedLongLong, UnsignedLongLong
 from pypy.rpython.lltypesystem.lltype import frozendict, isCompatibleType
+from pypy.rpython.lltypesystem.lltype import identityhash
 from pypy.rlib.rarithmetic import intmask
 from pypy.rlib import objectmodel
 from pypy.tool.uid import uid
@@ -331,9 +332,14 @@
     # can treat them polymorphically, if they choose to do so.
 
     def __init__(self, fields, _hints={}):
+        if isinstance(fields, dict):
+            fields = fields.items()    # random order in that case
         self._fields = frozendict()
-        for name, ITEMTYPE in fields.items():
+        fields_in_order = []
+        for name, ITEMTYPE in fields:
             self._fields[name] = ITEMTYPE, ITEMTYPE._defl()
+            fields_in_order.append(name)
+        self._fields_in_order = tuple(fields_in_order)
         self._null = _null_record(self)
         self._hints = frozendict(_hints)
 
@@ -361,8 +367,8 @@
             return self, None
 
     def __str__(self):
-        item_str = ["%s: %s" % (str(name), str(ITEMTYPE))
-                    for name, (ITEMTYPE, _) in self._fields.items()]
+        item_str = ["%s: %s" % (str(name), str(self._fields[name][0]))
+                    for name in self._fields_in_order]
         return '%s(%s)' % (self.__class__.__name__, ", ".join(item_str))
 
 class BuiltinADTType(BuiltinType):
@@ -411,6 +417,7 @@
 
         generic_types = { self.SELFTYPE_T: self }
         self._GENERIC_METHODS = frozendict({
+            "ll_hash": Meth([], Signed),
             "ll_stritem_nonneg": Meth([Signed], self.CHAR),
             "ll_strlen": Meth([], Signed),
             "ll_strconcat": Meth([self.SELFTYPE_T], self.SELFTYPE_T),
@@ -881,13 +888,10 @@
         return hash(self.obj)
 
     def _identityhash(self):
-        if self:
-            try:
-                return self.obj._identityhash()
-            except AttributeError:
-                return intmask(id(self.obj))
-        else:
-            return 0 # for all null objects
+        try:
+            return self.obj._identityhash()
+        except AttributeError:
+            return hash(self.obj)
 
     def _cast_to_object(self):
         return self
@@ -986,10 +990,7 @@
         return self
 
     def _identityhash(self):
-        if self:
-            return intmask(id(self))
-        else:
-            return 0   # for all null instances
+        return hash(self)
 
     def _cast_to_object(self):
         return make_object(ooupcast(ROOT, self))
@@ -1386,6 +1387,12 @@
         else:
             assert False, 'Unknown type %s' % self._TYPE
 
+    def ll_hash(self):
+        # NOT_RPYTHON
+        # hopefully, ll_hash() should not be called on NULL
+        assert self._str is not None
+        return objectmodel._hash_string(self._str)
+
     def ll_stritem_nonneg(self, i):
         # NOT_RPYTHON
         s = self._str
@@ -1622,10 +1629,7 @@
         self._array[index] = item
 
     def _identityhash(self):
-        if self:
-            return intmask(id(self))
-        else:
-            return 0   # for all null arrays
+        return hash(self)
 
 class _null_array(_null_mixin(_array), _array):
 
@@ -1772,13 +1776,16 @@
             self.__dict__[name] = value
 
     def _identityhash(self):
-        if self:
-            return intmask(id(self))
-        else:
-            return 0 # for all null tuples
+        return hash(self)
+
+    def _items_in_order(self):
+        return [self._items[name] for name in self._TYPE._fields_in_order]
+
+    def _ll_hash(self):
+        return objectmodel._ll_hash_tuple(self._items_in_order())
 
     def __hash__(self):
-        key = tuple(self._items.keys()), tuple(self._items.values())
+        key = tuple(self._items_in_order())
         return hash(key)
 
     def __eq__(self, other):
@@ -1898,16 +1905,6 @@
     assert typeOf(obj) is Object
     return obj._cast_to(EXPECTED_TYPE)
 
-def ooidentityhash(inst):
-    T = typeOf(inst)
-    assert T is Object or isinstance(T, (Instance, Record, Array))
-    return inst._identityhash()
-
-def oohash(inst):
-    assert typeOf(inst) is String or typeOf(inst) is Unicode
-    # for now only strings and unicode are supported
-    return hash(inst._str)
-
 def oostring(obj, base):
     """
     Convert char, int, float, instances and str to str.

Modified: pypy/branch/gc-hash/pypy/rpython/ootypesystem/rbuiltin.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/ootypesystem/rbuiltin.py	(original)
+++ pypy/branch/gc-hash/pypy/rpython/ootypesystem/rbuiltin.py	Tue Oct 13 13:28:16 2009
@@ -48,12 +48,6 @@
     return hop.genop('runtimenew', vlist,
                      resulttype = hop.r_result.lowleveltype)
 
-def rtype_ooidentityhash(hop):
-    assert isinstance(hop.args_s[0], (annmodel.SomeOOInstance, annmodel.SomeOOObject))
-    vlist = hop.inputargs(hop.args_r[0])
-    return hop.genop('ooidentityhash', vlist,
-                     resulttype = ootype.Signed)
-
 def rtype_ooupcast(hop):
     assert isinstance(hop.args_s[0].const, ootype.Instance)
     assert isinstance(hop.args_s[1], annmodel.SomeOOInstance)
@@ -132,7 +126,6 @@
 BUILTIN_TYPER[ootype.subclassof] = rtype_subclassof
 BUILTIN_TYPER[ootype.instanceof] = rtype_instanceof
 BUILTIN_TYPER[ootype.runtimenew] = rtype_runtimenew
-BUILTIN_TYPER[ootype.ooidentityhash] = rtype_ooidentityhash
 BUILTIN_TYPER[ootype.ooupcast] = rtype_ooupcast
 BUILTIN_TYPER[ootype.oodowncast] = rtype_oodowncast
 BUILTIN_TYPER[ootype.cast_from_object] = rtype_cast_from_object

Modified: pypy/branch/gc-hash/pypy/rpython/ootypesystem/rclass.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/ootypesystem/rclass.py	(original)
+++ pypy/branch/gc-hash/pypy/rpython/ootypesystem/rclass.py	Tue Oct 13 13:28:16 2009
@@ -152,7 +152,7 @@
     if config.translation.ootype.mangle:
         return 'o' + name
     else:
-        not_allowed = ('_hash_cache_', 'meta', 'class_')
+        not_allowed = ('meta', 'class_')
         assert name not in not_allowed, "%s is a reserved name" % name
         return name
 
@@ -253,13 +253,6 @@
                     allmethods[mangled] = meth_name, s_meth
                 # else: it's the __init__ of a builtin exception
 
-        #
-        # hash() support
-        if self.rtyper.needs_hash_support(self.classdef):
-            from pypy.rpython import rint
-            allfields['_hash_cache_'] = rint.signed_repr
-            fields['_hash_cache_'] = ootype.Signed
-
         ootype.addFields(self.lowleveltype, fields)
 
         self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef)
@@ -413,9 +406,6 @@
                         graph=graph)
         ootype.addMethods(self.lowleveltype, {mangled: m})
 
-    def get_ll_hash_function(self):
-        return ll_inst_hash
-
     def rtype_getattr(self, hop):
         if hop.s_result.is_constant():
             return hop.inputconst(hop.r_result, hop.s_result.const)
@@ -526,8 +516,6 @@
                 llattrvalue = None
             elif mangled == 'meta':
                 llattrvalue = classrepr.get_meta_instance()
-            elif mangled == '_hash_cache_': # hash() support
-                continue   # already done by initialize_prebuilt_hash()
             else:
                 name = unmangle(mangled, self.rtyper.getconfig())
                 try:
@@ -544,8 +532,7 @@
             setattr(result, mangled, llattrvalue)
 
     def initialize_prebuilt_hash(self, value, result):
-        if '_hash_cache_' in self.lowleveltype._allfields():
-            result._hash_cache_ = hash(value)
+        pass
 
 
 class __extend__(pairtype(InstanceRepr, InstanceRepr)):
@@ -581,15 +568,6 @@
         v = rpair.rtype_eq(hop)
         return hop.genop("bool_not", [v], resulttype=ootype.Bool)
 
-
-def ll_inst_hash(ins):
-    if not ins:
-        return 0
-    cached = ins._hash_cache_
-    if cached == 0:
-        cached = ins._hash_cache_ = ootype.ooidentityhash(ins)
-    return cached
-
 def ll_inst_type(obj):
     if obj:
         return ootype.classof(obj)

Modified: pypy/branch/gc-hash/pypy/rpython/ootypesystem/rstr.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/ootypesystem/rstr.py	(original)
+++ pypy/branch/gc-hash/pypy/rpython/ootypesystem/rstr.py	Tue Oct 13 13:28:16 2009
@@ -113,10 +113,10 @@
         return ootype.oounicode(ch, -1)
 
     def ll_strhash(s):
-        return ootype.oohash(s)
+        return s.ll_hash()
 
     def ll_strfasthash(s):
-        return ootype.oohash(s)
+        return s.ll_hash()
 
     def ll_char_mul(ch, times):
         if times < 0:

Modified: pypy/branch/gc-hash/pypy/rpython/ootypesystem/rtupletype.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/ootypesystem/rtupletype.py	(original)
+++ pypy/branch/gc-hash/pypy/rpython/ootypesystem/rtupletype.py	Tue Oct 13 13:28:16 2009
@@ -12,4 +12,4 @@
         fields = [('item%d' % i, TYPE) for i, TYPE in enumerate(field_lltypes)]
         hints = {'immutable': True,
                  'noidentity': True}
-        return ootype.Record(dict(fields), _hints=hints)
+        return ootype.Record(fields, _hints=hints)

Modified: pypy/branch/gc-hash/pypy/rpython/ootypesystem/test/test_ootype.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/ootypesystem/test/test_ootype.py	(original)
+++ pypy/branch/gc-hash/pypy/rpython/ootypesystem/test/test_ootype.py	Tue Oct 13 13:28:16 2009
@@ -622,27 +622,27 @@
     cls2 = cast_from_object(Class, obj)
     assert cls is cls2
     
-def test_object_ooidentityhash():
+def test_object_identityhash():
     A = Instance("Foo", ROOT)
     a = new(A)
     obj1 = cast_to_object(a)
     obj2 = cast_to_object(a)
-    assert ooidentityhash(obj1) == ooidentityhash(obj2)
+    assert identityhash(obj1) == identityhash(obj2)
 
-def test_object_ooidentityhash_sm():
+def test_object_identityhash_sm():
     M = StaticMethod([Signed], Signed)
     def m_(x):
        return x
     m = static_meth(M, "m", _callable=m_)
     obj1 = cast_to_object(m)
     obj2 = cast_to_object(m)
-    assert ooidentityhash(obj1) == ooidentityhash(obj2)
+    assert identityhash(obj1) == identityhash(obj2)
 
-def test_ooidentityhash_array():
+def test_identityhash_array():
     A = Array(Signed)
     a = oonewarray(A, 10)
     b = oonewarray(A, 10)
-    assert ooidentityhash(a) != ooidentityhash(b)
+    assert identityhash(a) != identityhash(b)     # likely
 
 def test_bool_class():
     A = Instance("Foo", ROOT)

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 Oct 13 13:28:16 2009
@@ -492,6 +492,10 @@
     return hop.genop('cast_int_to_ptr', [v_input],
                      resulttype = hop.r_result.lowleveltype)
 
+def rtype_identity_hash(hop):
+    vlist = hop.inputargs(hop.args_r[0])
+    return hop.genop('identityhash', vlist, resulttype=lltype.Signed)
+
 def rtype_runtime_type_info(hop):
     assert isinstance(hop.args_r[0], rptr.PtrRepr)
     vlist = hop.inputargs(hop.args_r[0])
@@ -510,6 +514,7 @@
 BUILTIN_TYPER[lltype.cast_int_to_ptr] = rtype_cast_int_to_ptr
 BUILTIN_TYPER[lltype.typeOf] = rtype_const_result
 BUILTIN_TYPER[lltype.nullptr] = rtype_const_result
+BUILTIN_TYPER[lltype.identityhash] = rtype_identity_hash
 BUILTIN_TYPER[lltype.getRuntimeTypeInfo] = rtype_const_result
 BUILTIN_TYPER[lltype.Ptr] = rtype_const_result
 BUILTIN_TYPER[lltype.runtime_type_info] = rtype_runtime_type_info

Modified: pypy/branch/gc-hash/pypy/rpython/rclass.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/rclass.py	(original)
+++ pypy/branch/gc-hash/pypy/rpython/rclass.py	Tue Oct 13 13:28:16 2009
@@ -236,15 +236,18 @@
             self.setup()
             result = self.create_instance()
             self._reusable_prebuilt_instance = result
-            self.initialize_prebuilt_instance(Ellipsis, self.classdef, result)
+            self.initialize_prebuilt_data(Ellipsis, self.classdef, result)
             return result
 
     def initialize_prebuilt_instance(self, value, classdef, result):
-        # must fill in the _hash_cache_ field before the other ones
+        # must fill in the hash cache before the other ones
         # (see test_circular_hash_initialization)
         self.initialize_prebuilt_hash(value, result)
         self.initialize_prebuilt_data(value, classdef, result)
 
+    def get_ll_hash_function(self):
+        return ll_inst_hash
+
     def rtype_type(self, hop):
         raise NotImplementedError
 
@@ -272,6 +275,13 @@
     rinstance = getinstancerepr(rtyper, classdef)
     return rinstance.new_instance(llops, classcallhop)
 
+def ll_inst_hash(ins):
+    if not ins:
+        return 0    # for None
+    else:
+        from pypy.rpython.lltypesystem import lltype
+        return lltype.identityhash(ins)     # also works for ootype
+
 
 _missing = object()
 

Modified: pypy/branch/gc-hash/pypy/rpython/rdict.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/rdict.py	(original)
+++ pypy/branch/gc-hash/pypy/rpython/rdict.py	Tue Oct 13 13:28:16 2009
@@ -46,14 +46,8 @@
         else:
             return self._externalvsinternal(self.rtyper, item_repr)
 
-    def pickkeyrepr(self, key_repr):
-        external, internal = self.pickrepr(key_repr)
-        if external != internal:
-            internal = external
-            while not self.rtyper.needs_hash_support(internal.classdef):
-                internal = internal.rbase
-        return external, internal
-        
+    pickkeyrepr = pickrepr
+
     def compact_repr(self):
         return 'DictR %s %s' % (self.key_repr.compact_repr(), self.value_repr.compact_repr())
 

Modified: pypy/branch/gc-hash/pypy/rpython/rtuple.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/rtuple.py	(original)
+++ pypy/branch/gc-hash/pypy/rpython/rtuple.py	Tue Oct 13 13:28:16 2009
@@ -100,14 +100,14 @@
         autounrolling_funclist = unrolling_iterable(enumerate(hash_funcs))
 
         def ll_hash(t):
-            retval = 0x345678
-            mult = 1000003
+            """Must be kept in sync with rlib.objectmodel._hash_tuple()."""
+            x = 0x345678
             for i, hash_func in autounrolling_funclist:
                 attrname = 'item%d' % i
                 item = getattr(t, attrname)
-                retval = intmask((retval ^ hash_func(item)) * intmask(mult))
-                mult = mult + 82520 + 2*len(items_r)
-            return retval
+                y = hash_func(item)
+                x = intmask((1000003 * x) ^ y)
+            return x
 
         _gen_hash_function_cache[key] = ll_hash
         return ll_hash

Modified: pypy/branch/gc-hash/pypy/rpython/rtyper.py
==============================================================================
--- pypy/branch/gc-hash/pypy/rpython/rtyper.py	(original)
+++ pypy/branch/gc-hash/pypy/rpython/rtyper.py	Tue Oct 13 13:28:16 2009
@@ -651,9 +651,6 @@
 
     # __________ utilities __________
 
-    def needs_hash_support(self, clsdef):
-        return clsdef in self.annotator.bookkeeper.needs_hash_support
-
     def needs_wrapper(self, cls):
         return cls in self.classes_with_wrapper
 



More information about the Pypy-commit mailing list