[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