[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