Author: Armin Rigo <[email protected]>
Branch: stmgc-c7
Changeset: r69928:b341c6bd5059
Date: 2014-03-13 11:42 +0100
http://bitbucket.org/pypy/pypy/changeset/b341c6bd5059/
Log: Support weakrefs. Missing prebuilt weakrefs so far.
diff --git a/rpython/memory/gc/stmgc.py b/rpython/memory/gc/stmgc.py
--- a/rpython/memory/gc/stmgc.py
+++ b/rpython/memory/gc/stmgc.py
@@ -65,9 +65,10 @@
# XXX finalizers are ignored for now
#ll_assert(not needs_finalizer, 'XXX needs_finalizer')
#ll_assert(not is_finalizer_light, 'XXX is_finalizer_light')
- ll_assert(not contains_weakptr, 'contains_weakptr: use malloc_weakref')
if size < 16:
size = 16 # minimum size (test usually constant-folded)
+ if contains_weakptr: # check constant-folded
+ return llop.stm_allocate_weakref(llmemory.GCREF, size, typeid16)
return llop.stm_allocate_tid(llmemory.GCREF, size, typeid16)
def malloc_varsize_clear(self, typeid16, length, size, itemsize,
@@ -79,11 +80,6 @@
llop.stm_set_into_obj(lltype.Void, result, offset_to_length, length)
return result
- def malloc_weakref(self, typeid16, size, obj):
- raise NotImplementedError # XXX
- return llop.stm_weakref_allocate(llmemory.GCREF, size,
- typeid16, obj)
-
def can_optimize_clean_setarrayitems(self):
return False
diff --git a/rpython/memory/gctransform/framework.py
b/rpython/memory/gctransform/framework.py
--- a/rpython/memory/gctransform/framework.py
+++ b/rpython/memory/gctransform/framework.py
@@ -945,7 +945,15 @@
# cast_ptr_to_adr must be done after malloc, as the GC pointer
# might have moved just now.
v_instance, = op.args
- v_addr = hop.genop("cast_ptr_to_adr", [v_instance],
+ if self.translator.config.translation.stm:
+ # not untranslated-test-friendly, but good enough: we hide
+ # our GC object inside an Address field. It's not a correct
+ # "void *" address, as it's in the wrong address_space, but
+ # we will force_cast it again in weakref_deref().
+ opname = "force_cast"
+ else:
+ opname = "cast_ptr_to_adr"
+ v_addr = hop.genop(opname, [v_instance],
resulttype=llmemory.Address)
hop.genop("bare_setfield",
[v_result, rmodel.inputconst(lltype.Void, "weakptr"),
v_addr])
@@ -958,7 +966,12 @@
v_addr = hop.genop("direct_call",
[self.weakref_deref_ptr, v_wref],
resulttype=llmemory.Address)
- hop.cast_result(v_addr)
+ if self.translator.config.translation.stm:
+ # see gct_weakref_create()
+ hop.genop("force_cast", [v_addr],
+ resultvar=hop.spaceop.result)
+ else:
+ hop.cast_result(v_addr)
def gct_gc_identityhash(self, hop):
livevars = self.push_roots(hop)
diff --git a/rpython/memory/gctransform/stmframework.py
b/rpython/memory/gctransform/stmframework.py
--- a/rpython/memory/gctransform/stmframework.py
+++ b/rpython/memory/gctransform/stmframework.py
@@ -15,13 +15,6 @@
s_gc, s_typeid16)
gc = self.gcdata.gc
#
- s_gcref = llannotation.SomePtr(llmemory.GCREF)
-
- self.malloc_weakref_ptr = self._getfn(
- GCClass.malloc_weakref.im_func,
- [s_gc, s_typeid16, annmodel.SomeInteger(nonneg=True),
- s_gcref], s_gcref)
- #
def pypy_stmcb_size_rounded_up(obj):
return gc.get_size(obj)
pypy_stmcb_size_rounded_up.c_name = "pypy_stmcb_size_rounded_up"
@@ -98,40 +91,6 @@
def gct_gc_adr_of_root_stack_top(self, hop):
hop.genop("stm_get_root_stack_top", [], resultvar=hop.spaceop.result)
- def gct_weakref_create(self, hop):
- XXX
- op = hop.spaceop
-
- type_id = self.get_type_id(WEAKREF)
-
- c_type_id = rmodel.inputconst(TYPE_ID, type_id)
- info = self.layoutbuilder.get_info(type_id)
- c_size = rmodel.inputconst(lltype.Signed, info.fixedsize)
- malloc_ptr = self.malloc_weakref_ptr
- c_null = rmodel.inputconst(llmemory.Address, llmemory.NULL)
- args = [self.c_const_gc, c_type_id, c_size, c_null]
- # XXX: for now, set weakptr ourselves and simply pass NULL
-
- # push and pop the current live variables *including* the argument
- # to the weakref_create operation, which must be kept alive and
- # moved if the GC needs to collect
- livevars = self.push_roots(hop, keep_current_args=True)
- v_result = hop.genop("direct_call", [malloc_ptr] + args,
- resulttype=llmemory.GCREF)
- v_result = hop.genop("cast_opaque_ptr", [v_result],
- resulttype=WEAKREFPTR)
- self.pop_roots(hop, livevars)
- # cast_ptr_to_adr must be done after malloc, as the GC pointer
- # might have moved just now.
- v_instance, = op.args
- v_addr = hop.genop("cast_ptr_to_adr", [v_instance],
- resulttype=llmemory.Address)
- hop.genop("bare_setfield",
- [v_result, rmodel.inputconst(lltype.Void, "weakptr"),
v_addr])
- v_weakref = hop.genop("cast_ptr_to_weakrefptr", [v_result],
- resulttype=llmemory.WeakRefPtr)
- hop.cast_result(v_weakref)
-
## def _gct_with_roots_pushed(self, hop):
## livevars = self.push_roots(hop)
## self.default(hop)
diff --git a/rpython/rtyper/lltypesystem/lloperation.py
b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -417,6 +417,7 @@
'stm_write': LLOp(),
'stm_can_move': LLOp(),
'stm_allocate_tid': LLOp(sideeffects=False, canmallocgc=True),
+ 'stm_allocate_weakref': LLOp(sideeffects=False, canmallocgc=True),
'stm_get_from_obj': LLOp(sideeffects=False),
'stm_get_from_obj_const': LLOp(canfold=True),
'stm_set_into_obj': LLOp(),
diff --git a/rpython/translator/c/primitive.py
b/rpython/translator/c/primitive.py
--- a/rpython/translator/c/primitive.py
+++ b/rpython/translator/c/primitive.py
@@ -170,7 +170,7 @@
def name_address(value, db):
if value:
- return db.get(value.ref())
+ return '((void *)%s)' % (db.get(value.ref(), static=True),)
else:
return 'NULL'
diff --git a/rpython/translator/stm/funcgen.py
b/rpython/translator/stm/funcgen.py
--- a/rpython/translator/stm/funcgen.py
+++ b/rpython/translator/stm/funcgen.py
@@ -77,6 +77,14 @@
return ('%s = (rpygcchar_t *)stm_allocate(%s); ' % (result, arg_size) +
'((rpyobj_t *)%s)->tid = %s;' % (result, arg_type_id))
+def stm_allocate_weakref(funcgen, op):
+ arg_size = funcgen.expr(op.args[0])
+ arg_type_id = funcgen.expr(op.args[1])
+ result = funcgen.expr(op.result)
+ # XXX NULL returns?
+ return ('%s = (rpygcchar_t *)stm_allocate_weakref(%s); ' % (result,
arg_size) +
+ '((rpyobj_t *)%s)->tid = %s;' % (result, arg_type_id))
+
def stm_get_from_obj(funcgen, op):
assert op.args[0].concretetype == llmemory.GCREF
arg_obj = funcgen.expr(op.args[0])
diff --git a/rpython/translator/stm/test/test_ztranslated.py
b/rpython/translator/stm/test/test_ztranslated.py
--- a/rpython/translator/stm/test/test_ztranslated.py
+++ b/rpython/translator/stm/test/test_ztranslated.py
@@ -304,6 +304,22 @@
data = cbuilder.cmdexec('a b')
assert 'test ok\n' in data
+ def test_prebuilt_weakref(self):
+ import weakref
+ class Foo(object):
+ pass
+ foo = Foo(); foo.n = 42
+ wr = weakref.ref(foo)
+
+ def main(argv):
+ wr().n += 1
+ print '<', wr().n, '>'
+ return 0
+
+ t, cbuilder = self.compile(main)
+ data = cbuilder.cmdexec('')
+ assert '< 43 >\n' in data
+
def test_stm_pointer_equal(self):
class Foo:
pass
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit