[pypy-svn] r65409 - in pypy/branch/tagged-pointers-framework/pypy/rpython: lltypesystem memory/gc memory/test test
cfbolz at codespeak.net
cfbolz at codespeak.net
Mon May 25 14:25:21 CEST 2009
Author: cfbolz
Date: Mon May 25 14:25:19 2009
New Revision: 65409
Modified:
pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/llmemory.py
pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/lltype.py
pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gc/base.py
pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gc/hybrid.py
pypy/branch/tagged-pointers-framework/pypy/rpython/memory/test/test_gc.py
pypy/branch/tagged-pointers-framework/pypy/rpython/memory/test/test_transformed_gc.py
pypy/branch/tagged-pointers-framework/pypy/rpython/test/test_rptr.py
Log:
- fix casting of opaque pointers to ints. Needed for correct GCREF handing
- allowing casting of addresses of dead objects to int. Fixes some
test_transformed_gc tests
- proper id handling of tagged pointers in moving GCs
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/llmemory.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/llmemory.py Mon May 25 14:25:19 2009
@@ -461,8 +461,10 @@
return lltype.nullptr(EXPECTED_TYPE.TO)
def _cast_to_int(self):
+ # This is a bit annoying. We want this method to still work when the
+ # pointed-to object is dead
if self:
- return self.ptr._cast_to_int()
+ return self.ptr._cast_to_int(False)
else:
return 0
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/lltype.py Mon May 25 14:25:19 2009
@@ -816,6 +816,7 @@
if not ptr:
return nullptr(PTRTYPE.TO)
return opaqueptr(PTRTYPE.TO, 'hidden', container = ptr._obj,
+ ORIGTYPE = CURTYPE,
solid = ptr._solid)
elif (isinstance(CURTYPE.TO, OpaqueType)
and isinstance(PTRTYPE.TO, OpaqueType)):
@@ -899,7 +900,7 @@
top_parent = parent
return top_parent
-def normalizeptr(p):
+def normalizeptr(p, check=True):
# If p is a pointer, returns the same pointer casted to the largest
# containing structure (for the cast where p points to the header part).
# Also un-hides pointers to opaque. Null pointers become None.
@@ -907,12 +908,17 @@
T = typeOf(p)
if not isinstance(T, Ptr):
return p # primitive
- if not p:
+ obj = p._getobj(check)
+ if not obj:
return None # null pointer
if type(p._obj0) is int:
return p # a pointer obtained by cast_int_to_ptr
- container = p._obj._normalizedcontainer()
- if container is not p._obj:
+ container = obj._normalizedcontainer()
+ if type(container) is int:
+ # this must be an opaque ptr originating from an integer
+ assert isinstance(obj, _opaque)
+ return cast_int_to_ptr(obj.ORIGTYPE, container)
+ if container is not obj:
p = _ptr(Ptr(typeOf(container)), container, p._solid)
return p
@@ -1171,13 +1177,15 @@
raise RuntimeError("widening %r inside %r instead of %r" % (CURTYPE, PARENTTYPE, PTRTYPE.TO))
return _ptr(PTRTYPE, struc, solid=self._solid)
- def _cast_to_int(self):
- if not self:
+ def _cast_to_int(self, check=True):
+ obj = self._getobj(check)
+ if not obj:
return 0 # NULL pointer
- obj = self._obj
if isinstance(obj, int):
return obj # special case for cast_int_to_ptr() results
- obj = normalizeptr(self)._obj
+ obj = normalizeptr(self, check)._getobj(check)
+ if isinstance(obj, int):
+ return obj # special case for cast_int_to_ptr() results put into opaques
result = intmask(obj._getid())
# assume that id() returns an addressish value which is
# not zero and aligned to at least a multiple of 4
@@ -1718,6 +1726,9 @@
# if we are an opaque containing a normal Struct/GcStruct,
# unwrap it
if hasattr(self, 'container'):
+ # an integer, cast to a ptr, cast to an opaque
+ if type(self.container) is int:
+ return self.container
return self.container._normalizedcontainer()
else:
return _parentable._normalizedcontainer(self)
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gc/base.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gc/base.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gc/base.py Mon May 25 14:25:19 2009
@@ -243,6 +243,8 @@
GCBase.setup(self)
self.objects_with_id = self.AddressDict()
self.id_free_list = self.AddressStack()
+ # XXX XXX XXX think of something sane:
+ # how do we prevent clashing with tagged pointers?
self.next_free_id = 1
def can_move(self, addr):
@@ -252,6 +254,11 @@
# Default implementation for id(), assuming that "external" objects
# never move. Overriden in the HybridGC.
obj = llmemory.cast_ptr_to_adr(ptr)
+
+ # is it a tagged pointer?
+ if not self.is_valid_gc_object(obj):
+ return llmemory.cast_adr_to_int(obj) // 2
+
if self._is_external(obj):
result = obj
else:
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gc/hybrid.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gc/hybrid.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gc/hybrid.py Mon May 25 14:25:19 2009
@@ -553,6 +553,11 @@
def id(self, ptr):
obj = llmemory.cast_ptr_to_adr(ptr)
+
+ # is it a tagged pointer?
+ if not self.is_valid_gc_object(obj):
+ return llmemory.cast_adr_to_int(obj)
+
if self._is_external(obj):
# a prebuilt or rawmalloced object
if self.is_last_generation(obj):
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/memory/test/test_gc.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/memory/test/test_gc.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/memory/test/test_gc.py Mon May 25 14:25:19 2009
@@ -514,6 +514,35 @@
res = self.interpret(fn, [-1000])
assert res == -897
+ def test_tagged_id(self):
+ from pypy.rlib.objectmodel import UnboxedValue, compute_unique_id
+
+ class Unrelated(object):
+ pass
+
+ u = Unrelated()
+ u.x = UnboxedObject(47)
+ def fn(n):
+ id_prebuilt1 = compute_unique_id(u.x)
+ if n > 0:
+ x = BoxedObject(n)
+ else:
+ x = UnboxedObject(n)
+ id_x1 = compute_unique_id(x)
+ rgc.collect() # check that a prebuilt tagged pointer doesn't explode
+ id_prebuilt2 = compute_unique_id(u.x)
+ id_x2 = compute_unique_id(x)
+ print u.x, id_prebuilt1, id_prebuilt2
+ print x, id_x1, id_x2
+ return ((id_x1 == id_x2) * 1 +
+ (id_prebuilt1 == id_prebuilt2) * 10 +
+ (id_x1 != id_prebuilt1) * 100)
+ res = self.interpret(fn, [1000])
+ assert res == 111
+ res = self.interpret(fn, [-1000])
+ assert res == 111
+
+
from pypy.rlib.objectmodel import UnboxedValue
class TaggedBase(object):
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/memory/test/test_transformed_gc.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/memory/test/test_transformed_gc.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/memory/test/test_transformed_gc.py Mon May 25 14:25:19 2009
@@ -525,7 +525,7 @@
res = fn([])
assert res == 'y'
- def test_tagged(self):
+ def test_tagged_simple(self):
class Unrelated(object):
pass
@@ -546,6 +546,27 @@
res = func([])
assert res == fn(1000) + fn(-1000)
+ def test_tagged_prebuilt(self):
+
+ class F:
+ pass
+
+ f = F()
+ f.l = [UnboxedObject(10)]
+ def fn(n):
+ if n > 0:
+ x = BoxedObject(n)
+ else:
+ x = UnboxedObject(n)
+ f.l.append(x)
+ rgc.collect()
+ return f.l[-1].meth(100)
+ def func():
+ return fn(1000) ^ fn(-1000)
+ func = self.runner(func)
+ res = func([])
+ assert res == fn(1000) ^ fn(-1000)
+
from pypy.rlib.objectmodel import UnboxedValue
class TaggedBase(object):
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/test/test_rptr.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/test/test_rptr.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/test/test_rptr.py Mon May 25 14:25:19 2009
@@ -112,6 +112,20 @@
interpret(fn, [11521])
+def test_odd_ints_opaque():
+ T = GcStruct('T')
+ Q = GcOpaqueType('Q')
+ PT = Ptr(T)
+ PQ = Ptr(Q)
+ def fn(n):
+ t = cast_int_to_ptr(PT, n)
+ assert typeOf(t) == PT
+ assert cast_ptr_to_int(t) == n
+ o = cast_opaque_ptr(PQ, t)
+ assert cast_ptr_to_int(o) == n
+
+ fn(13)
+ interpret(fn, [11521])
def test_Ptr():
S = GcStruct('s')
More information about the Pypy-commit
mailing list