Problem: Python: garbage collection issues.
Solution: Fix the GC issues: Use proper DESTRUCTOR_FINISH: avoids negative
refcounts, use PyObject_GC_* for objects with tp_traverse and
tp_clear, add RangeTraverse and RangeClear, use Py_XDECREF in some
places. (ZyX)
}
static PyObject *
-VimEval(PyObject *self UNUSED, PyObject *args UNUSED)
+VimEval(PyObject *self UNUSED, PyObject *args)
{
char *expr;
typval_T *our_tv;
{
IterObject *self;
- self = PyObject_NEW(IterObject, &IterType);
+ self = PyObject_GC_New(IterObject, &IterType);
self->cur = start;
self->next = next;
self->destruct = destruct;
static void
IterDestructor(IterObject *self)
{
+ PyObject_GC_UnTrack((void *)(self));
self->destruct(self->cur);
-
- DESTRUCTOR_FINISH(self);
+ PyObject_GC_Del((void *)(self));
}
static int
{
OptionsObject *self;
- self = PyObject_NEW(OptionsObject, &OptionsType);
+ self = PyObject_GC_New(OptionsObject, &OptionsType);
if (self == NULL)
return NULL;
static void
OptionsDestructor(OptionsObject *self)
{
- if (self->fromObj)
- Py_DECREF(self->fromObj);
- DESTRUCTOR_FINISH(self);
+ PyObject_GC_UnTrack((void *)(self));
+ Py_XDECREF(self->fromObj);
+ PyObject_GC_Del((void *)(self));
}
static int
}
else
{
- self = PyObject_NEW(WindowObject, &WindowType);
+ self = PyObject_GC_New(WindowObject, &WindowType);
if (self == NULL)
return NULL;
self->win = win;
static void
WindowDestructor(WindowObject *self)
{
+ PyObject_GC_UnTrack((void *)(self));
if (self->win && self->win != INVALID_WINDOW_VALUE)
WIN_PYTHON_REF(self->win) = NULL;
+ Py_XDECREF(((PyObject *)(self->tabObject)));
+ PyObject_GC_Del((void *)(self));
+}
- Py_DECREF(((PyObject *)(self->tabObject)));
+ static int
+WindowTraverse(WindowObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(((PyObject *)(self->tabObject)));
+ return 0;
+}
- DESTRUCTOR_FINISH(self);
+ static int
+WindowClear(WindowObject *self)
+{
+ Py_CLEAR(self->tabObject);
+ return 0;
}
static win_T *
else
return firstwin;
}
- static int
-WindowTraverse(WindowObject *self, visitproc visit, void *arg)
-{
- Py_VISIT(((PyObject *)(self->tabObject)));
- return 0;
-}
-
- static int
-WindowClear(WindowObject *self)
-{
- Py_CLEAR(self->tabObject);
- return 0;
-}
static PyObject *
WindowAttr(WindowObject *self, char *name)
{
BufferObject *bufr;
RangeObject *self;
- self = PyObject_NEW(RangeObject, &RangeType);
+ self = PyObject_GC_New(RangeObject, &RangeType);
if (self == NULL)
return NULL;
static void
RangeDestructor(RangeObject *self)
{
+ PyObject_GC_UnTrack((void *)(self));
Py_XDECREF(self->buf);
- DESTRUCTOR_FINISH(self);
+ PyObject_GC_Del((void *)(self));
+}
+
+ static int
+RangeTraverse(RangeObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(((PyObject *)(self->buf)));
+ return 0;
+}
+
+ static int
+RangeClear(RangeObject *self)
+{
+ Py_CLEAR(self->buf);
+ return 0;
}
static PyInt
static int
BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
{
- Py_VISIT(buffer);
+ if (buffer)
+ Py_VISIT(buffer);
return 0;
}
static int
BufMapIterClear(PyObject **buffer)
{
- Py_CLEAR(*buffer);
+ if (*buffer)
+ Py_CLEAR(*buffer);
return 0;
}
RangeType.tp_flags = Py_TPFLAGS_DEFAULT;
RangeType.tp_doc = "vim Range object";
RangeType.tp_methods = RangeMethods;
+ RangeType.tp_traverse = (traverseproc)RangeTraverse;
+ RangeType.tp_clear = (inquiry)RangeClear;
#if PY_MAJOR_VERSION >= 3
RangeType.tp_getattro = (getattrofunc)RangeGetattro;
RangeType.tp_alloc = call_PyType_GenericAlloc;
# define Py_Finalize dll_Py_Finalize
# define Py_IsInitialized dll_Py_IsInitialized
# define _PyObject_New dll__PyObject_New
+# define _PyObject_GC_New dll__PyObject_GC_New
+# define PyObject_GC_Del dll_PyObject_GC_Del
+# define PyObject_GC_UnTrack dll_PyObject_GC_UnTrack
# if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02070000
# define _PyObject_NextNotImplemented (*dll__PyObject_NextNotImplemented)
# endif
static void(*dll_Py_Finalize)(void);
static int(*dll_Py_IsInitialized)(void);
static PyObject*(*dll__PyObject_New)(PyTypeObject *, PyObject *);
+static PyObject*(*dll__PyObject_GC_New)(PyTypeObject *);
+static void(*dll_PyObject_GC_Del)(void *);
+static void(*dll_PyObject_GC_UnTrack)(void *);
static PyObject*(*dll__PyObject_Init)(PyObject *, PyTypeObject *);
static PyObject* (*dll_PyObject_GetIter)(PyObject *);
static int (*dll_PyObject_IsTrue)(PyObject *);
{"Py_Finalize", (PYTHON_PROC*)&dll_Py_Finalize},
{"Py_IsInitialized", (PYTHON_PROC*)&dll_Py_IsInitialized},
{"_PyObject_New", (PYTHON_PROC*)&dll__PyObject_New},
+ {"_PyObject_GC_New", (PYTHON_PROC*)&dll__PyObject_GC_New},
+ {"PyObject_GC_Del", (PYTHON_PROC*)&dll_PyObject_GC_Del},
+ {"PyObject_GC_UnTrack", (PYTHON_PROC*)&dll_PyObject_GC_UnTrack},
{"PyObject_Init", (PYTHON_PROC*)&dll__PyObject_Init},
{"PyObject_GetIter", (PYTHON_PROC*)&dll_PyObject_GetIter},
{"PyObject_IsTrue", (PYTHON_PROC*)&dll_PyObject_IsTrue},
#define DICTKEY_UNREF
#define DICTKEY_DECL
-#define DESTRUCTOR_FINISH(self) Py_DECREF(self);
+#define DESTRUCTOR_FINISH(self) Py_TYPE(self)->tp_free((PyObject*)self);
#define WIN_PYTHON_REF(win) win->w_python_ref
#define BUF_PYTHON_REF(buf) buf->b_python_ref
# define PyObject_Malloc py3_PyObject_Malloc
# define PyObject_Free py3_PyObject_Free
# endif
+# define _PyObject_GC_New py3__PyObject_GC_New
+# define PyObject_GC_Del py3_PyObject_GC_Del
+# define PyObject_GC_UnTrack py3_PyObject_GC_UnTrack
# define PyType_GenericAlloc py3_PyType_GenericAlloc
# define PyType_GenericNew py3_PyType_GenericNew
# define PyModule_Create2 py3_PyModule_Create2
static void (*py3_PyObject_Free)(void*);
static void* (*py3_PyObject_Malloc)(size_t);
# endif
+static PyObject*(*py3__PyObject_GC_New)(PyTypeObject *);
+static void(*py3_PyObject_GC_Del)(void *);
+static void(*py3_PyObject_GC_UnTrack)(void *);
static int (*py3_PyType_IsSubtype)(PyTypeObject *, PyTypeObject *);
static HINSTANCE hinstPy3 = 0; /* Instance of python.dll */
{"PyObject_Malloc", (PYTHON_PROC*)&py3_PyObject_Malloc},
{"PyObject_Free", (PYTHON_PROC*)&py3_PyObject_Free},
# endif
+ {"_PyObject_GC_New", (PYTHON_PROC*)&py3__PyObject_GC_New},
+ {"PyObject_GC_Del", (PYTHON_PROC*)&py3_PyObject_GC_Del},
+ {"PyObject_GC_UnTrack", (PYTHON_PROC*)&py3_PyObject_GC_UnTrack},
{"PyType_IsSubtype", (PYTHON_PROC*)&py3_PyType_IsSubtype},
{"PyCapsule_New", (PYTHON_PROC*)&py3_PyCapsule_New},
{"PyCapsule_GetPointer", (PYTHON_PROC*)&py3_PyCapsule_GetPointer},
if (bytes != NULL) \
Py_XDECREF(bytes);
-#define DESTRUCTOR_FINISH(self) Py_TYPE(self)->tp_free((PyObject*)self);
+#define DESTRUCTOR_FINISH(self) Py_TYPE(self)->tp_free((PyObject*)self)
#define WIN_PYTHON_REF(win) win->w_python3_ref
#define BUF_PYTHON_REF(buf) buf->b_python3_ref
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 998,
/**/
997,
/**/