[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