[pypy-svn] r68322 - in pypy/branch/gc-hash/pypy/rpython/lltypesystem: . test

arigo at codespeak.net arigo at codespeak.net
Sun Oct 11 20:34:36 CEST 2009


Author: arigo
Date: Sun Oct 11 20:34:35 2009
New Revision: 68322

Modified:
   pypy/branch/gc-hash/pypy/rpython/lltypesystem/lltype.py
   pypy/branch/gc-hash/pypy/rpython/lltypesystem/test/test_lltype.py
Log:
hash_cache support in lltype for GcStructs, including the
possibility to ask for prebuilt gcstructs to have a specific
hash value.

Repeats r51644 but gives hash support to all GcStructs, not
just some of them.


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	Sun Oct 11 20:34:35 2009
@@ -1390,7 +1390,7 @@
 class _struct(_parentable):
     _kind = "structure"
 
-    __slots__ = ()
+    __slots__ = ('_hash_cache_',)
 
     def __new__(self, TYPE, n=None, initialization=None, parent=None, parentindex=None):
         my_variety = _struct_variety(TYPE._names)
@@ -1840,6 +1840,26 @@
                                  "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 init_hash_gc_object(p, value):
+    """For a prebuilt object p, initialize its hash value to 'value'."""
+    p = normalizeptr(p)
+    if not p:
+        raise ValueError("cannot change hash(NULL)!")
+    if hasattr(p._obj, '_hash_cache_'):
+        raise ValueError("the hash of %r was already computed" % (p,))
+    p._obj._hash_cache_ = intmask(value)
+
 def isCompatibleType(TYPE1, TYPE2):
     return TYPE1._is_compatible(TYPE2)
 

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	Sun Oct 11 20:34:35 2009
@@ -739,3 +739,30 @@
     del ptr
     import gc; gc.collect(); gc.collect()
     ptr2[0] = 5    # crashes if the array was deallocated
+
+def test_hash_gc_object():
+    S = GcStruct('S', ('x', Signed))
+    S2 = GcStruct('S2', ('super', S))
+    S3 = GcStruct('S3', ('super', 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)
+
+    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)
+
+    from pypy.rpython.lltypesystem import llmemory
+    p3 = cast_opaque_ptr(llmemory.GCREF, s3)
+    assert -123 == hash_gc_object(p3)



More information about the Pypy-commit mailing list