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

Reply via email to