[pypy-commit] pypy cpyext-gc-support: Translates (and segfault for now)

arigo noreply at buildbot.pypy.org
Fri Oct 16 16:04:34 EDT 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: cpyext-gc-support
Changeset: r80297:14ff1bcf152c
Date: 2015-10-16 22:04 +0200
http://bitbucket.org/pypy/pypy/changeset/14ff1bcf152c/

Log:	Translates (and segfault for now)

diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -2757,6 +2757,8 @@
                               ('ob_refcnt', lltype.Signed),
                               ('ob_pypy_link', lltype.Signed))
     PYOBJ_HDR_PTR = lltype.Ptr(PYOBJ_HDR)
+    RAWREFCOUNT_DEALLOC = lltype.Ptr(lltype.FuncType([llmemory.Address],
+                                                     lltype.Void))
 
     def _pyobj(self, pyobjaddr):
         return llmemory.cast_adr_to_ptr(pyobjaddr, self.PYOBJ_HDR_PTR)
@@ -2792,7 +2794,7 @@
             self.rrc_p_list_young.append(pyobject)
         else:
             self.rrc_p_list_old.append(pyobject)
-        objint = llmemory.cast_adr_to_int(obj, mode="symbolic")
+        objint = llmemory.cast_adr_to_int(obj, "symbolic")
         self._pyobj(pyobject).ob_pypy_link = objint
         self.rrc_p_dict.setitem(obj, pyobject)
 
@@ -2803,7 +2805,7 @@
             self.rrc_o_list_young.append(pyobject)
         else:
             self.rrc_o_list_old.append(pyobject)
-        objint = llmemory.cast_adr_to_int(obj, mode="symbolic")
+        objint = llmemory.cast_adr_to_int(obj, "symbolic")
         self._pyobj(pyobject).ob_pypy_link = objint
         # there is no rrc_o_dict
 
@@ -2853,18 +2855,21 @@
             if self.is_forwarded(obj):
                 # Common case: survives and moves
                 obj = self.get_forwarding_address(obj)
-                intobj = llmemory.cast_adr_to_int(obj, mode="symbolic")
+                intobj = llmemory.cast_adr_to_int(obj, "symbolic")
                 self._pyobj(pyobject).ob_pypy_link = intobj
                 surviving = True
             else:
                 surviving = False
         elif (bool(self.young_rawmalloced_objects) and
-              self.young_rawmalloced_objects.contains(pointing_to)):
+              self.young_rawmalloced_objects.contains(obj)):
             # young weakref to a young raw-malloced object
-            if self.header(pointing_to).tid & GCFLAG_VISITED_RMY:
+            if self.header(obj).tid & GCFLAG_VISITED_RMY:
                 surviving = True    # survives, but does not move
             else:
                 surviving = False
+        else:
+            ll_assert(False, "rrc_X_list_young contains non-young obj")
+            return
         #
         if surviving:
             surviving_list.append(pyobject)
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
@@ -157,6 +157,7 @@
         else:
             # for regular translation: pick the GC from the config
             GCClass, GC_PARAMS = choose_gc_from_config(translator.config)
+            self.GCClass = GCClass
 
         if hasattr(translator, '_jit2gc'):
             self.layoutbuilder = translator._jit2gc['layoutbuilder']
@@ -487,6 +488,26 @@
                                             annmodel.SomeInteger(nonneg=True)],
                                            annmodel.s_None)
 
+        if hasattr(GCClass, 'rawrefcount_init'):
+            self.rawrefcount_init_ptr = getfn(
+                GCClass.rawrefcount_init,
+                [s_gc, SomePtr(GCClass.RAWREFCOUNT_DEALLOC)],
+                annmodel.s_None)
+            self.rawrefcount_create_link_pypy_ptr = getfn(
+                GCClass.rawrefcount_create_link_pypy,
+                [s_gc, s_gcref, SomeAddress()],
+                annmodel.s_None)
+            self.rawrefcount_create_link_pyobj_ptr = getfn(
+                GCClass.rawrefcount_create_link_pyobj,
+                [s_gc, s_gcref, SomeAddress()],
+                annmodel.s_None)
+            self.rawrefcount_from_obj_ptr = getfn(
+                GCClass.rawrefcount_from_obj, [s_gc, s_gcref], SomeAddress(),
+                inline = True)
+            self.rawrefcount_to_obj_ptr = getfn(
+                GCClass.rawrefcount_to_obj, [s_gc, SomeAddress()], s_gcref,
+                inline = True)
+
         if GCClass.can_usually_pin_objects:
             self.pin_ptr = getfn(GCClass.pin,
                                  [s_gc, SomeAddress()],
@@ -1232,6 +1253,44 @@
                   resultvar=hop.spaceop.result)
         self.pop_roots(hop, livevars)
 
+    def gct_gc_rawrefcount_init(self, hop):
+        [v_fnptr] = hop.spaceop.args
+        assert v_fnptr.concretetype == self.GCClass.RAWREFCOUNT_DEALLOC
+        hop.genop("direct_call",
+                  [self.rawrefcount_init_ptr, self.c_const_gc, v_fnptr])
+
+    def gct_gc_rawrefcount_create_link_pypy(self, hop):
+        [v_gcobj, v_pyobject] = hop.spaceop.args
+        assert v_gcobj.concretetype == llmemory.GCREF
+        assert v_pyobject.concretetype == llmemory.Address
+        hop.genop("direct_call",
+                  [self.rawrefcount_create_link_pypy_ptr, self.c_const_gc,
+                   v_gcobj, v_pyobject])
+
+    def gct_gc_rawrefcount_create_link_pyobj(self, hop):
+        [v_gcobj, v_pyobject] = hop.spaceop.args
+        assert v_gcobj.concretetype == llmemory.GCREF
+        assert v_pyobject.concretetype == llmemory.Address
+        hop.genop("direct_call",
+                  [self.rawrefcount_create_link_pyobj_ptr, self.c_const_gc,
+                   v_gcobj, v_pyobject])
+
+    def gct_gc_rawrefcount_from_obj(self, hop):
+        [v_gcobj] = hop.spaceop.args
+        assert v_gcobj.concretetype == llmemory.GCREF
+        assert hop.spaceop.result.concretetype == llmemory.Address
+        hop.genop("direct_call",
+                  [self.rawrefcount_from_obj_ptr, self.c_const_gc, v_gcobj],
+                  resultvar=hop.spaceop.result)
+
+    def gct_gc_rawrefcount_to_obj(self, hop):
+        [v_pyobject] = hop.spaceop.args
+        assert v_pyobject.concretetype == llmemory.Address
+        assert hop.spaceop.result.concretetype == llmemory.GCREF
+        hop.genop("direct_call",
+                  [self.rawrefcount_to_obj_ptr, self.c_const_gc, v_pyobject],
+                  resultvar=hop.spaceop.result)
+
     def _set_into_gc_array_part(self, op):
         if op.opname == 'setarrayitem':
             return op.args[1]
diff --git a/rpython/rlib/rawrefcount.py b/rpython/rlib/rawrefcount.py
--- a/rpython/rlib/rawrefcount.py
+++ b/rpython/rlib/rawrefcount.py
@@ -11,6 +11,9 @@
 REFCNT_FROM_PYPY        = 80
 REFCNT_FROM_PYPY_DIRECT = REFCNT_FROM_PYPY + (sys.maxint//2+1)
 
+RAWREFCOUNT_DEALLOC = lltype.Ptr(lltype.FuncType([llmemory.Address],
+                                                 lltype.Void))
+
 
 def _build_pypy_link(p):
     res = len(_adr2pypy)
@@ -129,6 +132,28 @@
 
 # ____________________________________________________________
 
+
+def _unspec_p(hop, v_p):
+    assert isinstance(v_p.concretetype, lltype.Ptr)
+    assert v_p.concretetype.TO._gckind == 'gc'
+    return hop.genop('cast_opaque_ptr', [v_p], resulttype=llmemory.GCREF)
+
+def _unspec_ob(hop, v_ob):
+    assert isinstance(v_ob.concretetype, lltype.Ptr)
+    assert v_ob.concretetype.TO._gckind == 'raw'
+    return hop.genop('cast_ptr_to_adr', [v_ob], resulttype=llmemory.Address)
+
+def _spec_p(hop, v_p):
+    assert v_p.concretetype == llmemory.GCREF
+    return hop.genop('cast_opaque_ptr', [v_p],
+                     resulttype=hop.r_result.lowleveltype)
+
+def _spec_ob(hop, v_ob):
+    assert v_ob.concretetype == llmemory.Address
+    return hop.genop('cast_adr_to_ptr', [v_ob],
+                     resulttype=hop.r_result.lowleveltype)
+
+
 class Entry(ExtRegistryEntry):
     _about_ = init
 
@@ -138,9 +163,10 @@
 
     def specialize_call(self, hop):
         hop.exception_cannot_occur()
-        [v_dealloc_callback] = hop.inputargs(hop.args_r[0].lowleveltype)
+        [v_dealloc_callback] = hop.inputargs(hop.args_r[0])
         hop.genop('gc_rawrefcount_init', [v_dealloc_callback])
 
+
 class Entry(ExtRegistryEntry):
     _about_ = (create_link_pypy, create_link_pyobj)
 
@@ -152,8 +178,10 @@
             name = 'gc_rawrefcount_create_link_pypy'
         elif self.instance is create_link_pyobj:
             name = 'gc_rawrefcount_create_link_pyobj'
+        v_p, v_ob = hop.inputargs(*hop.args_r)
         hop.exception_cannot_occur()
-        hop.genop(name, hop.args_v)
+        hop.genop(name, [_unspec_p(hop, v_p), _unspec_ob(hop, v_ob)])
+
 
 class Entry(ExtRegistryEntry):
     _about_ = from_obj
@@ -168,9 +196,10 @@
 
     def specialize_call(self, hop):
         hop.exception_cannot_occur()
-        [v_p] = hop.inputargs(hop.args_r[1].lowleveltype)
-        return hop.genop('gc_rawrefcount_from_obj', [v_p],
-                         resulttype = hop.r_result.lowleveltype)
+        v_p = hop.inputarg(hop.args_r[1], arg=1)
+        v_ob = hop.genop('gc_rawrefcount_from_obj', [_unspec_p(hop, v_p)],
+                         resulttype = llmemory.Address)
+        return _spec_ob(hop, v_ob)
 
 class Entry(ExtRegistryEntry):
     _about_ = to_obj
@@ -185,6 +214,7 @@
 
     def specialize_call(self, hop):
         hop.exception_cannot_occur()
-        v_ob = hop.inputargs(hop.args_r[1].lowleveltype)
-        return hop.genop('gc_rawrefcount_to_obj', [v_ob],
-                         resulttype = hop.r_result.lowleveltype)
+        v_ob = hop.inputarg(hop.args_r[1], arg=1)
+        v_p = hop.genop('gc_rawrefcount_to_obj', [_unspec_ob(hop, v_ob)],
+                        resulttype = llmemory.GCREF)
+        return _spec_p(hop, v_p)
diff --git a/rpython/rlib/test/test_rawrefcount.py b/rpython/rlib/test/test_rawrefcount.py
--- a/rpython/rlib/test/test_rawrefcount.py
+++ b/rpython/rlib/test/test_rawrefcount.py
@@ -1,7 +1,11 @@
 import weakref
-from rpython.rlib import rawrefcount
+from rpython.rlib import rawrefcount, objectmodel, rgc
 from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY, REFCNT_FROM_PYPY_DIRECT
 from rpython.rtyper.lltypesystem import lltype, llmemory
+from rpython.rtyper.annlowlevel import llhelper
+from rpython.translator.c.test.test_standalone import StandaloneTests
+from rpython.config.translationoption import get_combined_translation_config
+
 
 class W_Root(object):
     def __init__(self, intval=0):
@@ -201,3 +205,53 @@
         assert rawrefcount._p_list == [ob]
         assert rawrefcount.to_obj(W_Root, ob) == p
         lltype.free(ob, flavor='raw')
+
+
+class TestTranslated(StandaloneTests):
+
+    def test_full_translation(self):
+        class State:
+            pass
+        state = State()
+        state.seen = []
+        def dealloc_callback(ob):
+            state.seen.append(ob)
+
+        def make_p():
+            p = W_Root(42)
+            ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
+            rawrefcount.create_link_pyobj(p, ob)
+            ob.c_ob_refcnt += REFCNT_FROM_PYPY
+            assert rawrefcount.from_obj(PyObject, p) == ob
+            assert rawrefcount.to_obj(W_Root, ob) == p
+            return ob, p
+
+        FTYPE = rawrefcount.RAWREFCOUNT_DEALLOC
+
+        def entry_point(argv):
+            ll_dealloc_callback = llhelper(FTYPE, dealloc_callback)
+            rawrefcount.init(ll_dealloc_callback)
+            ob, p = make_p()
+            if state.seen != []:
+                print "OB COLLECTED REALLY TOO SOON"
+                return 1
+            rgc.collect()
+            if state.seen != []:
+                print "OB COLLECTED TOO SOON"
+                return 1
+            objectmodel.keepalive_until_here(p)
+            p = None
+            rgc.collect()
+            if state.seen == [llmemory.cast_ptr_to_adr(ob)]:
+                print "OK!"
+                lltype.free(ob, flavor='raw')
+                return 0
+            else:
+                print "OB NOT COLLECTED"
+                return 1
+
+        self.config = get_combined_translation_config(translating=True)
+        self.config.translation.gc = "incminimark"
+        t, cbuilder = self.compile(entry_point)
+        data = cbuilder.cmdexec('hi there')
+        assert data.startswith('OK!\n')


More information about the pypy-commit mailing list