Author: Armin Rigo <ar...@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') _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit