[pypy-svn] r46470 - in pypy/dist/pypy: rpython/memory/gctransform translator/c translator/c/test
arigo at codespeak.net
arigo at codespeak.net
Tue Sep 11 15:19:51 CEST 2007
Author: arigo
Date: Tue Sep 11 15:19:50 2007
New Revision: 46470
Modified:
pypy/dist/pypy/rpython/memory/gctransform/boehm.py
pypy/dist/pypy/translator/c/gc.py
pypy/dist/pypy/translator/c/primitive.py
pypy/dist/pypy/translator/c/test/test_boehm.py
Log:
Prebuilt weakrefs in genc/Boehm.
Modified: pypy/dist/pypy/rpython/memory/gctransform/boehm.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform/boehm.py (original)
+++ pypy/dist/pypy/rpython/memory/gctransform/boehm.py Tue Sep 11 15:19:50 2007
@@ -171,3 +171,12 @@
# abuse of llop.cast_pointer()
link = llop.cast_pointer(llmemory.Address, wref)
return link and link.address[0]
+
+def convert_prebuilt_weakref_to(targetptr):
+ # Prebuilt weakrefs don't really need to be weak at all,
+ # but we need to emulate the structure expected by ll_weakref_deref().
+ # This is essentially the same code as in ll_weakref_create(), but I'm
+ # not sure trying to share it is worth the hassle...
+ link = lltype.malloc(WEAKLINK, immortal=True)
+ link[0] = llmemory.cast_ptr_to_adr(targetptr)
+ return link
Modified: pypy/dist/pypy/translator/c/gc.py
==============================================================================
--- pypy/dist/pypy/translator/c/gc.py (original)
+++ pypy/dist/pypy/translator/c/gc.py Tue Sep 11 15:19:50 2007
@@ -175,6 +175,10 @@
class BoehmGcPolicy(BasicGcPolicy):
transformerclass = boehm.BoehmGCTransformer
+ def __init__(self, *args, **kwds):
+ BasicGcPolicy.__init__(self, *args, **kwds)
+ self.weakref_llwrapper_cache = {}
+
def array_setup(self, arraydefnode):
pass
@@ -213,6 +217,16 @@
yield 'GC_all_interior_pointers = 0;'
yield 'GC_init();'
+ def name_weakref_to(self, target):
+ # the cache is essential to ensure that repeated calls to
+ # db.get(weakref) don't return new llwrapper structures all
+ # the time, which defeats the db.complete() logic.
+ try:
+ llwrapper = self.weakref_llwrapper_cache[target._obj]
+ except KeyError:
+ llwrapper = boehm.convert_prebuilt_weakref_to(target)
+ self.weakref_llwrapper_cache[target._obj] = llwrapper
+ return '((GCWeakRef)%s)' % (self.db.get(llwrapper),)
def OP_GC_FETCH_EXCEPTION(self, funcgen, op):
result = funcgen.expr(op.result)
Modified: pypy/dist/pypy/translator/c/primitive.py
==============================================================================
--- pypy/dist/pypy/translator/c/primitive.py (original)
+++ pypy/dist/pypy/translator/c/primitive.py Tue Sep 11 15:19:50 2007
@@ -6,7 +6,7 @@
from pypy.rpython.lltypesystem.llmemory import Address, \
AddressOffset, ItemOffset, ArrayItemsOffset, FieldOffset, \
CompositeOffset, ArrayLengthOffset, WeakGcAddress, fakeweakaddress, \
- GCHeaderOffset, WeakRef
+ GCHeaderOffset, WeakRef, fakeweakref
from pypy.translator.c.support import cdecl
# ____________________________________________________________
@@ -121,6 +121,14 @@
assert ob is not None
return 'HIDE_POINTER(%s)'%db.get(ob)
+def name_weakref(value, db):
+ assert isinstance(value, fakeweakref)
+ target = value.get()
+ if target is None:
+ return 'NULL'
+ else:
+ return db.gcpolicy.name_weakref_to(target)
+
# On 64 bit machines, SignedLongLong and Signed are the same, so the
# order matters, because we want the Signed implementation.
PrimitiveName = {
@@ -135,6 +143,7 @@
Void: name_void,
Address: name_address,
WeakGcAddress: name_weakgcaddress,
+ WeakRef: name_weakref,
}
PrimitiveType = {
Modified: pypy/dist/pypy/translator/c/test/test_boehm.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_boehm.py (original)
+++ pypy/dist/pypy/translator/c/test/test_boehm.py Tue Sep 11 15:19:50 2007
@@ -318,6 +318,33 @@
# more than half of them should have been freed, ideally up to 6000
assert 3500 <= res <= 6000
+ def test_prebuilt_weakref(self):
+ import weakref
+ from pypy.rlib import rgc
+ class A:
+ pass
+ a = A()
+ a.hello = 42
+ r1 = weakref.ref(a)
+ r2 = weakref.ref(A())
+ rgc.collect()
+ assert r2() is None
+ def fn(n):
+ if n:
+ r = r1
+ else:
+ r = r2
+ a = r()
+ if a is None:
+ return -5
+ else:
+ return a.hello
+ c_fn = self.getcompiled(fn, [int])
+ res = c_fn(1)
+ assert res == 42
+ res = c_fn(0)
+ assert res == -5
+
class TestUsingExactBoehm(TestUsingBoehm):
gcpolicy = "exact_boehm"
More information about the Pypy-commit
mailing list