[pypy-svn] r73419 - pypy/branch/cpython-extension/pypy/module/cpyext
xoraxax at codespeak.net
xoraxax at codespeak.net
Mon Apr 5 22:56:10 CEST 2010
Author: xoraxax
Date: Mon Apr 5 22:56:08 2010
New Revision: 73419
Modified:
pypy/branch/cpython-extension/pypy/module/cpyext/object.py
pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py
pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py
Log:
Fix refcounting issue that showed up after running fuu2(u"uuu") in the following tests.
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/object.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/object.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/object.py Mon Apr 5 22:56:08 2010
@@ -1,6 +1,6 @@
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.module.cpyext.api import cpython_api, generic_cpy_call, CANNOT_FAIL,\
- Py_ssize_t, PyVarObject
+ Py_ssize_t, PyVarObject, Py_TPFLAGS_HEAPTYPE
from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref
from pypy.module.cpyext.pyobject import Py_IncRef, Py_DecRef
from pypy.module.cpyext.state import State
@@ -27,6 +27,8 @@
pto = rffi.cast(PyTypeObjectPtr, obj.c_ob_type)
obj_voidp = rffi.cast(rffi.VOIDP_real, obj)
generic_cpy_call(space, pto.c_tp_free, obj_voidp)
+ if pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE:
+ Py_DecRef(space, rffi.cast(PyObject, obj.c_ob_type))
@cpython_api([PyObject], rffi.INT_real, error=-1)
def PyObject_IsTrue(space, w_obj):
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py Mon Apr 5 22:56:08 2010
@@ -3,7 +3,7 @@
from pypy.interpreter.baseobjspace import W_Root
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.module.cpyext.api import cpython_api, PyObject, PyStringObject, ADDR,\
- Py_TPFLAGS_HEAPTYPE, PyUnicodeObject
+ Py_TPFLAGS_HEAPTYPE, PyUnicodeObject, PyTypeObjectPtr
from pypy.module.cpyext.state import State
from pypy.objspace.std.stringobject import W_StringObject
from pypy.objspace.std.unicodeobject import W_UnicodeObject
@@ -18,7 +18,7 @@
class InvalidPointerException(Exception):
pass
-DEBUG_REFCOUNT = False
+DEBUG_REFCOUNT = True
def debug_refcount(*args, **kwargs):
frame_stackdepth = kwargs.pop("frame_stackdepth", 2)
@@ -33,7 +33,6 @@
def make_ref(space, w_obj, borrowed=False, steal=False):
from pypy.module.cpyext.typeobject import allocate_type_obj,\
W_PyCTypeObject, PyOLifeline
- from pypy.module.cpyext.typeobjectdefs import PyTypeObjectPtr
if w_obj is None:
return lltype.nullptr(PyObject.TO)
assert isinstance(w_obj, W_Root)
@@ -150,11 +149,12 @@
if obj.c_ob_refcnt == 0:
state = space.fromcache(State)
ptr = rffi.cast(ADDR, obj)
- if ptr not in state.py_objects_r2w and \
- space.is_w(from_ref(space, rffi.cast(PyObject, obj.c_ob_type)), space.w_str):
- # this is a half-allocated string, lets call the deallocator
- # without modifying the r2w/w2r dicts
- _Py_Dealloc(space, obj)
+ if ptr not in state.py_objects_r2w:
+ w_type = from_ref(space, rffi.cast(PyObject, obj.c_ob_type))
+ if space.is_w(w_type, space.w_str) or space.is_w(w_type, space.w_unicode):
+ # this is a half-allocated string, lets call the deallocator
+ # without modifying the r2w/w2r dicts
+ _Py_Dealloc(space, obj)
else:
w_obj = state.py_objects_r2w[ptr]
del state.py_objects_r2w[ptr]
@@ -180,7 +180,9 @@
hex(containee)
del state.borrow_mapping[ptr]
else:
- assert obj.c_ob_refcnt > 0
+ if not we_are_translated() and obj.c_ob_refcnt < 0:
+ print >>sys.stderr, "Negative refcount for obj %s with type %s" % (obj, rffi.charp2str(obj.c_ob_type.c_tp_name))
+ assert False
@cpython_api([PyObject], lltype.Void)
def Py_IncRef(space, obj):
@@ -192,7 +194,6 @@
debug_refcount("INCREF", obj, obj.c_ob_refcnt, frame_stackdepth=3)
def _Py_Dealloc(space, obj):
- from pypy.module.cpyext.typeobject import PyTypeObjectPtr
from pypy.module.cpyext.api import generic_cpy_call_dont_decref
pto = obj.c_ob_type
#print >>sys.stderr, "Calling dealloc slot", pto.c_tp_dealloc, "of", obj, \
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Mon Apr 5 22:56:08 2010
@@ -303,9 +303,9 @@
dealloc = base.c_tp_dealloc
# XXX call tp_del if necessary
generic_cpy_call(space, dealloc, obj)
- if pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE:
- pto = rffi.cast(PyObject, pto)
- Py_DecRef(space, pto)
+ # XXX cpy decrefs the pto here but we do it in the base-dealloc
+ # hopefully this does not clash with the memory model assumed in
+ # extension modules
@cpython_api([PyObject], lltype.Void, external=False)
@@ -344,7 +344,7 @@
obj_pto_voidp = rffi.cast(rffi.VOIDP_real, obj_pto)
generic_cpy_call(space, type_pto.c_tp_free, obj_pto_voidp)
pto = rffi.cast(PyObject, type_pto)
- Py_DecRef(space, pto) # XXX duplicate decref? (see above)
+ Py_DecRef(space, pto)
def allocate_type_obj(space, w_type):
More information about the Pypy-commit
mailing list