[pypy-commit] pypy cpyext-gc-support-2: Next fix (rawrefcount debugging code takes weakrefs to the W_Root objects)
arigo
pypy.commits at gmail.com
Tue Feb 16 11:33:26 EST 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: cpyext-gc-support-2
Changeset: r82285:860e2a46b04c
Date: 2016-02-16 17:32 +0100
http://bitbucket.org/pypy/pypy/changeset/860e2a46b04c/
Log: Next fix (rawrefcount debugging code takes weakrefs to the W_Root
objects)
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -27,7 +27,7 @@
class W_Root(object):
"""This is the abstract root class of all wrapped objects that live
in a 'normal' object space like StdObjSpace."""
- __slots__ = ()
+ __slots__ = ('__weakref__',)
user_overridden_class = False
def getdict(self, space):
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -911,7 +911,7 @@
def prepare(self, py_obj, w_obj):
from pypy.module.cpyext.pyobject import track_reference
- py_obj.c_ob_refcnt = 1
+ py_obj.c_ob_refcnt = 1 # 1 for kept immortal
track_reference(self.space, py_obj, w_obj)
self.to_attach.append((py_obj, w_obj))
diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -6,7 +6,7 @@
Py_GE, CONST_STRING, FILEP, fwrite)
from pypy.module.cpyext.pyobject import (
PyObject, PyObjectP, create_ref, from_ref, Py_IncRef, Py_DecRef,
- track_reference, get_typedescr, _Py_NewReference, RefcountState)
+ get_typedescr, _Py_NewReference, RefcountState)
from pypy.module.cpyext.typeobject import PyTypeObjectPtr
from pypy.module.cpyext.pyerrors import PyErr_NoMemory, PyErr_BadInternalCall
from pypy.objspace.std.typeobject import W_TypeObject
@@ -33,7 +33,7 @@
assert isinstance(w_type, W_TypeObject)
typedescr = get_typedescr(w_type.instancetypedef)
py_obj = typedescr.allocate(space, w_type, itemcount=itemcount)
- py_obj.c_ob_refcnt = 0
+ #py_obj.c_ob_refcnt = 0 --- will be set to 1 again by PyObject_Init{Var}
if type.c_tp_itemsize == 0:
w_obj = PyObject_Init(space, py_obj, type)
else:
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
@@ -32,14 +32,15 @@
def allocate(self, space, w_type, itemcount=0):
# similar to PyType_GenericAlloc?
# except that it's not related to any pypy object.
+ # this returns a PyObject with ob_refcnt == 1.
- pytype = make_ref(space, w_type)
+ pytype = as_pyobj(space, w_type)
pytype = rffi.cast(PyTypeObjectPtr, pytype)
assert pytype
# Don't increase refcount for non-heaptypes
flags = rffi.cast(lltype.Signed, pytype.c_tp_flags)
- if not flags & Py_TPFLAGS_HEAPTYPE:
- Py_DecRef(space, w_type)
+ if flags & Py_TPFLAGS_HEAPTYPE:
+ Py_IncRef(space, w_type)
if pytype:
size = pytype.c_tp_basicsize
@@ -170,12 +171,22 @@
typedescr = get_typedescr(w_obj.typedef)
py_obj = typedescr.allocate(space, w_type, itemcount=itemcount)
track_reference(space, py_obj, w_obj)
+ #
+ # py_obj.c_ob_refcnt should be exactly REFCNT_FROM_PYPY + 1 here,
+ # and we want only REFCNT_FROM_PYPY, i.e. only count as attached
+ # to the W_Root but not with any reference from the py_obj side.
+ assert py_obj.c_ob_refcnt > rawrefcount.REFCNT_FROM_PYPY
+ py_obj.c_ob_refcnt -= 1
+ #
typedescr.attach(space, py_obj, w_obj)
return py_obj
def track_reference(space, py_obj, w_obj):
"""
Ties together a PyObject and an interpreter object.
+ The PyObject's refcnt is increased by REFCNT_FROM_PYPY.
+ The reference in 'py_obj' is not stolen! Remember to Py_DecRef()
+ it is you need to.
"""
# XXX looks like a PyObject_GC_TRACK
assert py_obj.c_ob_refcnt < rawrefcount.REFCNT_FROM_PYPY
@@ -226,7 +237,6 @@
py_obj = rawrefcount.from_obj(PyObject, w_obj)
if not py_obj:
py_obj = create_ref(space, w_obj)
- #track_reference(space, py_obj, w_obj) -- included with create_ref()
return py_obj
else:
return lltype.nullptr(PyObject.TO)
diff --git a/pypy/module/cpyext/stringobject.py b/pypy/module/cpyext/stringobject.py
--- a/pypy/module/cpyext/stringobject.py
+++ b/pypy/module/cpyext/stringobject.py
@@ -69,9 +69,9 @@
def new_empty_str(space, length):
"""
- Allocatse a PyStringObject and its buffer, but without a corresponding
+ Allocate a PyStringObject and its buffer, but without a corresponding
interpreter object. The buffer may be mutated, until string_realize() is
- called.
+ called. Refcount of the result is 1.
"""
typedescr = get_typedescr(space.w_str.instancetypedef)
py_obj = typedescr.allocate(space, space.w_str)
diff --git a/pypy/module/cpyext/tupleobject.py b/pypy/module/cpyext/tupleobject.py
--- a/pypy/module/cpyext/tupleobject.py
+++ b/pypy/module/cpyext/tupleobject.py
@@ -52,7 +52,7 @@
"""
Allocate a PyTupleObject and its array of PyObject *, but without a
corresponding interpreter object. The array may be mutated, until
- tuple_realize() is called.
+ tuple_realize() is called. Refcount of the result is 1.
"""
typedescr = get_typedescr(space.w_tuple.instancetypedef)
py_obj = typedescr.allocate(space, space.w_tuple)
diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -44,9 +44,9 @@
def new_empty_unicode(space, length):
"""
- Allocatse a PyUnicodeObject and its buffer, but without a corresponding
+ Allocate a PyUnicodeObject and its buffer, but without a corresponding
interpreter object. The buffer may be mutated, until unicode_realize() is
- called.
+ called. Refcount of the result is 1.
"""
typedescr = get_typedescr(space.w_unicode.instancetypedef)
py_obj = typedescr.allocate(space, space.w_unicode)
More information about the pypy-commit
mailing list