[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