Beispiel #1
0
 def entry_point(argv):
     ll_dealloc_trigger_callback = llhelper(FTYPE, dealloc_trigger)
     rawrefcount.init(ll_dealloc_trigger_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 != [1]:
         print "OB NOT COLLECTED"
         return 1
     if rawrefcount.next_dead(PyObject) != ob:
         print "NEXT_DEAD != OB"
         return 1
     if rawrefcount.next_dead(PyObject) != lltype.nullptr(PyObjectS):
         print "NEXT_DEAD second time != NULL"
         return 1
     if rawrefcount.to_obj(W_Root, ob) is not None:
         print "to_obj(dead) is not None?"
         return 1
     rawrefcount.mark_deallocating(w_marker, ob)
     if rawrefcount.to_obj(W_Root, ob) is not w_marker:
         print "to_obj(marked-dead) is not w_marker"
         return 1
     print "OK!"
     lltype.free(ob, flavor='raw')
     return 0
Beispiel #2
0
 def test_mark_deallocating(self):
     ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
     w_marker = W_Root(42)
     rawrefcount.mark_deallocating(w_marker, ob)
     assert rawrefcount.to_obj(W_Root, ob) is w_marker
     rawrefcount._collect()
     assert rawrefcount.to_obj(W_Root, ob) is w_marker
     lltype.free(ob, flavor='raw')
Beispiel #3
0
 def test_mark_deallocating(self):
     ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
     w_marker = W_Root(42)
     rawrefcount.mark_deallocating(w_marker, ob)
     assert rawrefcount.to_obj(W_Root, ob) is w_marker
     rawrefcount._collect()
     assert rawrefcount.to_obj(W_Root, ob) is w_marker
     lltype.free(ob, flavor='raw')
Beispiel #4
0
 def test_create_link_pyobj(self):
     p = W_Root(42)
     ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
     assert rawrefcount.from_obj(PyObject, p) == lltype.nullptr(PyObjectS)
     assert rawrefcount.to_obj(W_Root, ob) == None
     rawrefcount.create_link_pyobj(p, ob)
     assert ob.c_ob_refcnt == 0
     ob.c_ob_refcnt += REFCNT_FROM_PYPY
     assert rawrefcount.from_obj(PyObject, p) == lltype.nullptr(PyObjectS)
     assert rawrefcount.to_obj(W_Root, ob) == p
     lltype.free(ob, flavor='raw')
Beispiel #5
0
 def test_create_link_pyobj(self):
     p = W_Root(42)
     ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
     assert rawrefcount.from_obj(PyObject, p) == lltype.nullptr(PyObjectS)
     assert rawrefcount.to_obj(W_Root, ob) == None
     rawrefcount.create_link_pyobj(p, ob)
     assert ob.c_ob_refcnt == 0
     ob.c_ob_refcnt += REFCNT_FROM_PYPY
     assert rawrefcount.from_obj(PyObject, p) == lltype.nullptr(PyObjectS)
     assert rawrefcount.to_obj(W_Root, ob) == p
     lltype.free(ob, flavor='raw')
Beispiel #6
0
 def main(argv):
     rawrefcount.create_link_pypy(w1, ob1)
     w = None
     ob = lltype.nullptr(PyObjectS)
     oblist = []
     for op in argv[1:]:
         revdb.stop_point()
         w = W_Root(42)
         ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
         ob.c_ob_refcnt = rawrefcount.REFCNT_FROM_PYPY
         rawrefcount.create_link_pypy(w, ob)
         oblist.append(ob)
     del oblist[-1]
     #
     rgc.collect()
     assert rawrefcount.from_obj(PyObject, w) == ob
     assert rawrefcount.to_obj(W_Root, ob) == w
     while True:
         ob = rawrefcount.next_dead(PyObject)
         if not ob:
             break
         assert ob in oblist
         oblist.remove(ob)
     objectmodel.keepalive_until_here(w)
     revdb.stop_point()
     return 9
Beispiel #7
0
 def make_p():
     p = W_Root(42)
     ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
     rawrefcount.create_link_pypy(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
Beispiel #8
0
 def make_p():
     p = W_Root(42)
     ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
     rawrefcount.create_link_pypy(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
Beispiel #9
0
 def entry_point(argv):
     ll_dealloc_trigger_callback = llhelper(FTYPE, dealloc_trigger)
     rawrefcount.init(ll_dealloc_trigger_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 != [1]:
         print "OB NOT COLLECTED"
         return 1
     if rawrefcount.next_dead(PyObject) != ob:
         print "NEXT_DEAD != OB"
         return 1
     if ob.c_ob_refcnt != 1:
         print "next_dead().ob_refcnt != 1"
         return 1
     if rawrefcount.next_dead(PyObject) != lltype.nullptr(PyObjectS):
         print "NEXT_DEAD second time != NULL"
         return 1
     if rawrefcount.to_obj(W_Root, ob) is not None:
         print "to_obj(dead) is not None?"
         return 1
     rawrefcount.mark_deallocating(w_marker, ob)
     if rawrefcount.to_obj(W_Root, ob) is not w_marker:
         print "to_obj(marked-dead) is not w_marker"
         return 1
     print "OK!"
     lltype.free(ob, flavor='raw')
     return 0
Beispiel #10
0
 def test_collect_p_keepalive_w_root(self):
     p = W_Root(42)
     ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
     rawrefcount.create_link_pypy(p, ob)
     ob.c_ob_refcnt += REFCNT_FROM_PYPY_LIGHT
     assert rawrefcount._p_list == [ob]
     wr_ob = weakref.ref(ob)
     del ob  # p remains
     rawrefcount._collect()
     ob = wr_ob()
     assert ob is not None
     assert rawrefcount._p_list == [ob]
     assert rawrefcount.to_obj(W_Root, ob) == p
     assert rawrefcount.from_obj(PyObject, p) == ob
     lltype.free(ob, flavor='raw')
Beispiel #11
0
 def test_collect_p_keepalive_w_root(self):
     p = W_Root(42)
     ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
     rawrefcount.create_link_pypy(p, ob)
     ob.c_ob_refcnt += REFCNT_FROM_PYPY_LIGHT
     assert rawrefcount._p_list == [ob]
     wr_ob = weakref.ref(ob)
     del ob       # p remains
     rawrefcount._collect()
     ob = wr_ob()
     assert ob is not None
     assert rawrefcount._p_list == [ob]
     assert rawrefcount.to_obj(W_Root, ob) == p
     assert rawrefcount.from_obj(PyObject, p) == ob
     lltype.free(ob, flavor='raw')
Beispiel #12
0
def _type_realize(space, py_obj):
    """
    Creates an interpreter type from a PyTypeObject structure.
    """
    # missing:
    # unsupported:
    # tp_mro, tp_subclasses
    py_type = rffi.cast(PyTypeObjectPtr, py_obj)

    if not py_type.c_tp_base:
        # borrowed reference, but w_object is unlikely to disappear
        base = as_pyobj(space, space.w_object)
        py_type.c_tp_base = rffi.cast(PyTypeObjectPtr, base)

    finish_type_1(space, py_type)

    if py_type.c_ob_type:
        w_metatype = from_ref(space, rffi.cast(PyObject, py_type.c_ob_type))
    else:
        # Somehow the tp_base type is created with no ob_type, notably
        # PyString_Type and PyBaseString_Type
        # While this is a hack, cpython does it as well.
        w_metatype = space.w_type

    w_obj = rawrefcount.to_obj(W_PyCTypeObject, py_obj)
    if w_obj is None:
        w_obj = space.allocate_instance(W_PyCTypeObject, w_metatype)
        track_reference(space, py_obj, w_obj)
    # __init__ wraps all slotdefs functions from py_type via add_operators
    w_obj.__init__(space, py_type)
    w_obj.ready()

    finish_type_2(space, py_type, w_obj)
    base = py_type.c_tp_base
    if base:
        # XXX refactor - parts of this are done in finish_type_2 -> inherit_slots
        if not py_type.c_tp_as_number:
            py_type.c_tp_as_number = base.c_tp_as_number
            py_type.c_tp_flags |= base.c_tp_flags & Py_TPFLAGS_CHECKTYPES
            py_type.c_tp_flags |= base.c_tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS
        if not py_type.c_tp_as_sequence:
            py_type.c_tp_as_sequence = base.c_tp_as_sequence
            py_type.c_tp_flags |= base.c_tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS
        if not py_type.c_tp_as_mapping:
            py_type.c_tp_as_mapping = base.c_tp_as_mapping
        #if not py_type.c_tp_as_buffer: py_type.c_tp_as_buffer = base.c_tp_as_buffer

    return w_obj
Beispiel #13
0
 def test_collect_o_keepalive_w_root(self):
     p = W_Root(42)
     ob = lltype.malloc(PyObjectS, flavor="raw", zero=True)
     p.pyobj = ob
     rawrefcount.create_link_pyobj(p, ob)
     ob.c_ob_refcnt += REFCNT_FROM_PYPY
     assert rawrefcount._o_list == [ob]
     wr_ob = weakref.ref(ob)
     del ob  # p remains
     rawrefcount._collect()
     ob = wr_ob()
     assert ob is not None
     assert rawrefcount._o_list == [ob]
     assert rawrefcount.to_obj(W_Root, ob) == p
     assert p.pyobj == ob
     lltype.free(ob, flavor="raw")
Beispiel #14
0
 def test_collect_o_keepalive_pyobject(self):
     p = W_Root(42)
     ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
     p.pyobj = ob
     rawrefcount.create_link_pyobj(p, ob)
     ob.c_ob_refcnt += REFCNT_FROM_PYPY
     assert rawrefcount._o_list == [ob]
     wr_ob = weakref.ref(ob)
     wr_p = weakref.ref(p)
     ob.c_ob_refcnt += 1      # <=
     del p
     rawrefcount._collect()
     p = wr_p()
     assert p is None            # was unlinked
     assert ob.c_ob_refcnt == 1    # != REFCNT_FROM_PYPY_OBJECT + 1
     assert rawrefcount._o_list == []
     assert rawrefcount.to_obj(W_Root, ob) == None
     lltype.free(ob, flavor='raw')
Beispiel #15
0
 def test_collect_o_keepalive_pyobject(self):
     p = W_Root(42)
     ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
     p.pyobj = ob
     rawrefcount.create_link_pyobj(p, ob)
     ob.c_ob_refcnt += REFCNT_FROM_PYPY
     assert rawrefcount._o_list == [ob]
     wr_ob = weakref.ref(ob)
     wr_p = weakref.ref(p)
     ob.c_ob_refcnt += 1  # <=
     del p
     rawrefcount._collect()
     p = wr_p()
     assert p is None  # was unlinked
     assert ob.c_ob_refcnt == 1  # != REFCNT_FROM_PYPY_OBJECT + 1
     assert rawrefcount._o_list == []
     assert rawrefcount.to_obj(W_Root, ob) == None
     lltype.free(ob, flavor='raw')
Beispiel #16
0
 def test_collect_s_keepalive_pyobject(self):
     p = W_Root(42)
     ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
     p.pyobj = ob
     rawrefcount.create_link_pypy(p, ob)
     ob.c_ob_refcnt += REFCNT_FROM_PYPY
     assert rawrefcount._p_list == [ob]
     wr_ob = weakref.ref(ob)
     wr_p = weakref.ref(p)
     ob.c_ob_refcnt += 1  # <=
     del ob, p
     rawrefcount._collect()
     ob = wr_ob()
     p = wr_p()
     assert ob is not None and p is not None
     assert rawrefcount._p_list == [ob]
     assert rawrefcount.to_obj(W_Root, ob) == p
     lltype.free(ob, flavor='raw')
Beispiel #17
0
 def test_collect_s_keepalive_pyobject(self):
     p = W_Root(42)
     ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
     p.pyobj = ob
     rawrefcount.create_link_pypy(p, ob)
     ob.c_ob_refcnt += REFCNT_FROM_PYPY
     assert rawrefcount._p_list == [ob]
     wr_ob = weakref.ref(ob)
     wr_p = weakref.ref(p)
     ob.c_ob_refcnt += 1      # <=
     del ob, p
     rawrefcount._collect()
     ob = wr_ob()
     p = wr_p()
     assert ob is not None and p is not None
     assert rawrefcount._p_list == [ob]
     assert rawrefcount.to_obj(W_Root, ob) == p
     lltype.free(ob, flavor='raw')
Beispiel #18
0
def from_ref(space, ref):
    """
    Finds the interpreter object corresponding to the given reference.  If the
    object is not yet realized (see bytesobject.py), creates it.
    """
    assert is_pyobj(ref)
    if not ref:
        return None
    w_obj = rawrefcount.to_obj(W_Root, ref)
    if w_obj is not None:
        return w_obj

    # This reference is not yet a real interpreter object.
    # Realize it.
    ref_type = rffi.cast(PyObject, ref.c_ob_type)
    if ref_type == ref:  # recursion!
        raise InvalidPointerException(str(ref))
    w_type = from_ref(space, ref_type)
    assert isinstance(w_type, W_TypeObject)
    return get_typedescr(w_type.layout.typedef).realize(space, ref)
Beispiel #19
0
def from_ref(space, ref):
    """
    Finds the interpreter object corresponding to the given reference.  If the
    object is not yet realized (see bytesobject.py), creates it.
    """
    assert is_pyobj(ref)
    if not ref:
        return None
    w_obj = rawrefcount.to_obj(W_Root, ref)
    if w_obj is not None:
        return w_obj

    # This reference is not yet a real interpreter object.
    # Realize it.
    ref_type = rffi.cast(PyObject, ref.c_ob_type)
    if ref_type == ref: # recursion!
        raise InvalidPointerException(str(ref))
    w_type = from_ref(space, ref_type)
    assert isinstance(w_type, W_TypeObject)
    return get_typedescr(w_type.layout.typedef).realize(space, ref)
Beispiel #20
0
def from_ref(space, ref):
    """
    Finds the interpreter object corresponding to the given reference.  If the
    object is not yet realized (see bytesobject.py), creates it.
    """
    assert is_pyobj(ref)
    if not ref:
        return None
    w_obj = rawrefcount.to_obj(W_Root, ref)
    if w_obj is not None:
        if w_obj is not w_marker_deallocating:
            return w_obj
        type_name = rffi.charp2str(cts.cast('char*', ref.c_ob_type.c_tp_name))
        fatalerror(
            "*** Invalid usage of a dying CPython object ***\n"
            "\n"
            "cpyext, the emulation layer, detected that while it is calling\n"
            "an object's tp_dealloc, the C code calls back a function that\n"
            "tries to recreate the PyPy version of the object.  Usually it\n"
            "means that tp_dealloc calls some general PyXxx() API.  It is\n"
            "a dangerous and potentially buggy thing to do: even in CPython\n"
            "the PyXxx() function could, in theory, cause a reference to the\n"
            "object to be taken and stored somewhere, for an amount of time\n"
            "exceeding tp_dealloc itself.  Afterwards, the object will be\n"
            "freed, making that reference point to garbage.\n"
            ">>> PyPy could contain some workaround to still work if\n"
            "you are lucky, but it is not done so far; better fix the bug in\n"
            "the CPython extension.\n"
            ">>> This object is of type '%s'" % (type_name, ))

    # This reference is not yet a real interpreter object.
    # Realize it.
    ref_type = rffi.cast(PyObject, ref.c_ob_type)
    if ref_type == ref:  # recursion!
        raise InvalidPointerException(str(ref))
    w_type = from_ref(space, ref_type)
    assert isinstance(w_type, W_TypeObject)
    return get_typedescr(w_type.layout.typedef).realize(space, ref)
Beispiel #21
0
def from_ref(space, ref):
    """
    Finds the interpreter object corresponding to the given reference.  If the
    object is not yet realized (see bytesobject.py), creates it.
    """
    assert is_pyobj(ref)
    if not ref:
        return None
    w_obj = rawrefcount.to_obj(W_Root, ref)
    if w_obj is not None:
        if w_obj is not w_marker_deallocating:
            return w_obj
        fatalerror(
            "*** Invalid usage of a dying CPython object ***\n"
            "\n"
            "cpyext, the emulation layer, detected that while it is calling\n"
            "an object's tp_dealloc, the C code calls back a function that\n"
            "tries to recreate the PyPy version of the object.  Usually it\n"
            "means that tp_dealloc calls some general PyXxx() API.  It is\n"
            "a dangerous and potentially buggy thing to do: even in CPython\n"
            "the PyXxx() function could, in theory, cause a reference to the\n"
            "object to be taken and stored somewhere, for an amount of time\n"
            "exceeding tp_dealloc itself.  Afterwards, the object will be\n"
            "freed, making that reference point to garbage.\n"
            ">>> PyPy could contain some workaround to still work if\n"
            "you are lucky, but it is not done so far; better fix the bug in\n"
            "the CPython extension.")

    # This reference is not yet a real interpreter object.
    # Realize it.
    ref_type = rffi.cast(PyObject, ref.c_ob_type)
    if ref_type == ref: # recursion!
        raise InvalidPointerException(str(ref))
    w_type = from_ref(space, ref_type)
    assert isinstance(w_type, W_TypeObject)
    return get_typedescr(w_type.layout.typedef).realize(space, ref)
Beispiel #22
0
def pyobj_has_w_obj(pyobj):
    return rawrefcount.to_obj(W_Root, pyobj) is not None
Beispiel #23
0
def pyobj_has_w_obj(pyobj):
    return rawrefcount.to_obj(W_Root, pyobj) is not None
Beispiel #24
0
def pyobj_has_w_obj(pyobj):
    w_obj = rawrefcount.to_obj(W_Root, pyobj)
    return w_obj is not None and w_obj is not w_marker_deallocating
Beispiel #25
0
def pyobj_has_w_obj(pyobj):
    w_obj = rawrefcount.to_obj(W_Root, pyobj)
    return w_obj is not None and w_obj is not w_marker_deallocating