Author: Ronan Lamy <[email protected]>
Branch: cpyext-leakchecking
Changeset: r91959:20521e5ee07a
Date: 2017-07-24 00:07 +0200
http://bitbucket.org/pypy/pypy/changeset/20521e5ee07a/
Log: Mark the tp_bases of non-heap types as immortal
diff --git a/pypy/module/cpyext/pyobject.py b/pypy/module/cpyext/pyobject.py
--- a/pypy/module/cpyext/pyobject.py
+++ b/pypy/module/cpyext/pyobject.py
@@ -29,7 +29,7 @@
from pypy.module.cpyext.typeobject import subtype_dealloc
return subtype_dealloc.api_func
- def allocate(self, space, w_type, itemcount=0):
+ def allocate(self, space, w_type, itemcount=0, immortal=False):
# typically called from PyType_GenericAlloc via typedescr.allocate
# this returns a PyObject with ob_refcnt == 1.
@@ -50,7 +50,7 @@
assert size >= rffi.sizeof(PyObject.TO)
buf = lltype.malloc(rffi.VOIDP.TO, size,
flavor='raw', zero=True,
- add_memory_pressure=True)
+ add_memory_pressure=True, immortal=immortal)
pyobj = rffi.cast(PyObject, buf)
if pytype.c_tp_itemsize:
pyvarobj = rffi.cast(PyVarObject, pyobj)
@@ -102,7 +102,7 @@
basestruct = tp_basestruct
if tp_alloc:
- def allocate(self, space, w_type, itemcount=0):
+ def allocate(self, space, w_type, itemcount=0, immortal=False):
return tp_alloc(space, w_type, itemcount)
if tp_dealloc:
@@ -151,7 +151,7 @@
class InvalidPointerException(Exception):
pass
-def create_ref(space, w_obj, w_userdata=None):
+def create_ref(space, w_obj, w_userdata=None, immortal=False):
"""
Allocates a PyObject, and fills its fields with info from the given
interpreter object.
@@ -163,7 +163,7 @@
itemcount = space.len_w(w_obj) # PyBytesObject and subclasses
else:
itemcount = 0
- py_obj = typedescr.allocate(space, w_type, itemcount=itemcount)
+ py_obj = typedescr.allocate(space, w_type, itemcount=itemcount,
immortal=immortal)
track_reference(space, py_obj, w_obj)
#
# py_obj.c_ob_refcnt should be exactly REFCNT_FROM_PYPY + 1 here,
@@ -227,7 +227,7 @@
assert isinstance(w_type, W_TypeObject)
return get_typedescr(w_type.layout.typedef).realize(space, ref)
-def as_pyobj(space, w_obj, w_userdata=None):
+def as_pyobj(space, w_obj, w_userdata=None, immortal=False):
"""
Returns a 'PyObject *' representing the given intepreter object.
This doesn't give a new reference, but the returned 'PyObject *'
@@ -239,7 +239,7 @@
assert not is_pyobj(w_obj)
py_obj = rawrefcount.from_obj(PyObject, w_obj)
if not py_obj:
- py_obj = create_ref(space, w_obj, w_userdata)
+ py_obj = create_ref(space, w_obj, w_userdata, immortal=immortal)
return py_obj
else:
return lltype.nullptr(PyObject.TO)
@@ -270,7 +270,7 @@
return hop.inputconst(lltype.Bool, hop.s_result.const)
@specialize.ll()
-def make_ref(space, obj, w_userdata=None):
+def make_ref(space, obj, w_userdata=None, immortal=False):
"""Increment the reference counter of the PyObject and return it.
Can be called with either a PyObject or a W_Root.
"""
@@ -278,7 +278,7 @@
pyobj = rffi.cast(PyObject, obj)
at_least = 1
else:
- pyobj = as_pyobj(space, obj, w_userdata)
+ pyobj = as_pyobj(space, obj, w_userdata, immortal=immortal)
at_least = rawrefcount.REFCNT_FROM_PYPY
if pyobj:
assert pyobj.c_ob_refcnt >= at_least
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -922,7 +922,9 @@
bases_w = []
else:
bases_w = [from_ref(space, base_pyo)]
- pto.c_tp_bases = make_ref(space, space.newtuple(bases_w))
+ is_heaptype = bool(pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE)
+ pto.c_tp_bases = make_ref(space, space.newtuple(bases_w),
+ immortal=not is_heaptype)
def finish_type_2(space, pto, w_obj):
"""
@@ -948,7 +950,7 @@
if w_obj.is_cpytype():
Py_DecRef(space, pto.c_tp_dict)
- w_dict = w_obj.getdict(space)
+ #w_dict = w_obj.getdict(space)
# pass in the w_obj to convert any values that are
# unbound GetSetProperty into bound PyGetSetDescrObject
#pto.c_tp_dict = make_ref(space, w_dict, w_obj)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit