1
0
forked from aniani/vim

updated for version 7.3.998

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)
This commit is contained in:
Bram Moolenaar
2013-05-21 20:51:59 +02:00
parent a7b64ce74e
commit 774267bbb9
4 changed files with 69 additions and 30 deletions

View File

@@ -461,7 +461,7 @@ VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
} }
static PyObject * static PyObject *
VimEval(PyObject *self UNUSED, PyObject *args UNUSED) VimEval(PyObject *self UNUSED, PyObject *args)
{ {
char *expr; char *expr;
typval_T *our_tv; typval_T *our_tv;
@@ -602,7 +602,7 @@ IterNew(void *start, destructorfun destruct, nextfun next, traversefun traverse,
{ {
IterObject *self; IterObject *self;
self = PyObject_NEW(IterObject, &IterType); self = PyObject_GC_New(IterObject, &IterType);
self->cur = start; self->cur = start;
self->next = next; self->next = next;
self->destruct = destruct; self->destruct = destruct;
@@ -615,9 +615,9 @@ IterNew(void *start, destructorfun destruct, nextfun next, traversefun traverse,
static void static void
IterDestructor(IterObject *self) IterDestructor(IterObject *self)
{ {
PyObject_GC_UnTrack((void *)(self));
self->destruct(self->cur); self->destruct(self->cur);
PyObject_GC_Del((void *)(self));
DESTRUCTOR_FINISH(self);
} }
static int static int
@@ -1414,7 +1414,7 @@ OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj)
{ {
OptionsObject *self; OptionsObject *self;
self = PyObject_NEW(OptionsObject, &OptionsType); self = PyObject_GC_New(OptionsObject, &OptionsType);
if (self == NULL) if (self == NULL)
return NULL; return NULL;
@@ -1431,9 +1431,9 @@ OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj)
static void static void
OptionsDestructor(OptionsObject *self) OptionsDestructor(OptionsObject *self)
{ {
if (self->fromObj) PyObject_GC_UnTrack((void *)(self));
Py_DECREF(self->fromObj); Py_XDECREF(self->fromObj);
DESTRUCTOR_FINISH(self); PyObject_GC_Del((void *)(self));
} }
static int static int
@@ -1869,7 +1869,7 @@ WindowNew(win_T *win, tabpage_T *tab)
} }
else else
{ {
self = PyObject_NEW(WindowObject, &WindowType); self = PyObject_GC_New(WindowObject, &WindowType);
if (self == NULL) if (self == NULL)
return NULL; return NULL;
self->win = win; self->win = win;
@@ -1884,12 +1884,25 @@ WindowNew(win_T *win, tabpage_T *tab)
static void static void
WindowDestructor(WindowObject *self) WindowDestructor(WindowObject *self)
{ {
PyObject_GC_UnTrack((void *)(self));
if (self->win && self->win != INVALID_WINDOW_VALUE) if (self->win && self->win != INVALID_WINDOW_VALUE)
WIN_PYTHON_REF(self->win) = NULL; 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 * static win_T *
@@ -1909,19 +1922,6 @@ get_firstwin(TabPageObject *tabObject)
else else
return firstwin; 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 * static PyObject *
WindowAttr(WindowObject *self, char *name) WindowAttr(WindowObject *self, char *name)
@@ -2917,7 +2917,7 @@ RangeNew(buf_T *buf, PyInt start, PyInt end)
{ {
BufferObject *bufr; BufferObject *bufr;
RangeObject *self; RangeObject *self;
self = PyObject_NEW(RangeObject, &RangeType); self = PyObject_GC_New(RangeObject, &RangeType);
if (self == NULL) if (self == NULL)
return NULL; return NULL;
@@ -2939,8 +2939,23 @@ RangeNew(buf_T *buf, PyInt start, PyInt end)
static void static void
RangeDestructor(RangeObject *self) RangeDestructor(RangeObject *self)
{ {
PyObject_GC_UnTrack((void *)(self));
Py_XDECREF(self->buf); 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 PyInt
@@ -3267,6 +3282,7 @@ BufMapIterDestruct(PyObject *buffer)
static int static int
BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg) BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
{ {
if (buffer)
Py_VISIT(buffer); Py_VISIT(buffer);
return 0; return 0;
} }
@@ -3274,6 +3290,7 @@ BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
static int static int
BufMapIterClear(PyObject **buffer) BufMapIterClear(PyObject **buffer)
{ {
if (*buffer)
Py_CLEAR(*buffer); Py_CLEAR(*buffer);
return 0; return 0;
} }
@@ -4144,6 +4161,8 @@ init_structs(void)
RangeType.tp_flags = Py_TPFLAGS_DEFAULT; RangeType.tp_flags = Py_TPFLAGS_DEFAULT;
RangeType.tp_doc = "vim Range object"; RangeType.tp_doc = "vim Range object";
RangeType.tp_methods = RangeMethods; RangeType.tp_methods = RangeMethods;
RangeType.tp_traverse = (traverseproc)RangeTraverse;
RangeType.tp_clear = (inquiry)RangeClear;
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
RangeType.tp_getattro = (getattrofunc)RangeGetattro; RangeType.tp_getattro = (getattrofunc)RangeGetattro;
RangeType.tp_alloc = call_PyType_GenericAlloc; RangeType.tp_alloc = call_PyType_GenericAlloc;

View File

@@ -224,6 +224,9 @@ struct PyMethodDef { Py_ssize_t a; };
# define Py_Finalize dll_Py_Finalize # define Py_Finalize dll_Py_Finalize
# define Py_IsInitialized dll_Py_IsInitialized # define Py_IsInitialized dll_Py_IsInitialized
# define _PyObject_New dll__PyObject_New # 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 # if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02070000
# define _PyObject_NextNotImplemented (*dll__PyObject_NextNotImplemented) # define _PyObject_NextNotImplemented (*dll__PyObject_NextNotImplemented)
# endif # endif
@@ -331,6 +334,9 @@ static void(*dll_Py_Initialize)(void);
static void(*dll_Py_Finalize)(void); static void(*dll_Py_Finalize)(void);
static int(*dll_Py_IsInitialized)(void); static int(*dll_Py_IsInitialized)(void);
static PyObject*(*dll__PyObject_New)(PyTypeObject *, PyObject *); 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_Init)(PyObject *, PyTypeObject *);
static PyObject* (*dll_PyObject_GetIter)(PyObject *); static PyObject* (*dll_PyObject_GetIter)(PyObject *);
static int (*dll_PyObject_IsTrue)(PyObject *); static int (*dll_PyObject_IsTrue)(PyObject *);
@@ -474,6 +480,9 @@ static struct
{"Py_Finalize", (PYTHON_PROC*)&dll_Py_Finalize}, {"Py_Finalize", (PYTHON_PROC*)&dll_Py_Finalize},
{"Py_IsInitialized", (PYTHON_PROC*)&dll_Py_IsInitialized}, {"Py_IsInitialized", (PYTHON_PROC*)&dll_Py_IsInitialized},
{"_PyObject_New", (PYTHON_PROC*)&dll__PyObject_New}, {"_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_Init", (PYTHON_PROC*)&dll__PyObject_Init},
{"PyObject_GetIter", (PYTHON_PROC*)&dll_PyObject_GetIter}, {"PyObject_GetIter", (PYTHON_PROC*)&dll_PyObject_GetIter},
{"PyObject_IsTrue", (PYTHON_PROC*)&dll_PyObject_IsTrue}, {"PyObject_IsTrue", (PYTHON_PROC*)&dll_PyObject_IsTrue},
@@ -632,7 +641,7 @@ static int initialised = 0;
#define DICTKEY_UNREF #define DICTKEY_UNREF
#define DICTKEY_DECL #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 WIN_PYTHON_REF(win) win->w_python_ref
#define BUF_PYTHON_REF(buf) buf->b_python_ref #define BUF_PYTHON_REF(buf) buf->b_python_ref

View File

@@ -213,6 +213,9 @@
# define PyObject_Malloc py3_PyObject_Malloc # define PyObject_Malloc py3_PyObject_Malloc
# define PyObject_Free py3_PyObject_Free # define PyObject_Free py3_PyObject_Free
# endif # 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_GenericAlloc py3_PyType_GenericAlloc
# define PyType_GenericNew py3_PyType_GenericNew # define PyType_GenericNew py3_PyType_GenericNew
# define PyModule_Create2 py3_PyModule_Create2 # define PyModule_Create2 py3_PyModule_Create2
@@ -334,6 +337,9 @@ static void* (*py3_PyCapsule_GetPointer)(PyObject *, char *);
static void (*py3_PyObject_Free)(void*); static void (*py3_PyObject_Free)(void*);
static void* (*py3_PyObject_Malloc)(size_t); static void* (*py3_PyObject_Malloc)(size_t);
# endif # 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 int (*py3_PyType_IsSubtype)(PyTypeObject *, PyTypeObject *);
static HINSTANCE hinstPy3 = 0; /* Instance of python.dll */ static HINSTANCE hinstPy3 = 0; /* Instance of python.dll */
@@ -463,6 +469,9 @@ static struct
{"PyObject_Malloc", (PYTHON_PROC*)&py3_PyObject_Malloc}, {"PyObject_Malloc", (PYTHON_PROC*)&py3_PyObject_Malloc},
{"PyObject_Free", (PYTHON_PROC*)&py3_PyObject_Free}, {"PyObject_Free", (PYTHON_PROC*)&py3_PyObject_Free},
# endif # 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}, {"PyType_IsSubtype", (PYTHON_PROC*)&py3_PyType_IsSubtype},
{"PyCapsule_New", (PYTHON_PROC*)&py3_PyCapsule_New}, {"PyCapsule_New", (PYTHON_PROC*)&py3_PyCapsule_New},
{"PyCapsule_GetPointer", (PYTHON_PROC*)&py3_PyCapsule_GetPointer}, {"PyCapsule_GetPointer", (PYTHON_PROC*)&py3_PyCapsule_GetPointer},
@@ -638,7 +647,7 @@ static int py3initialised = 0;
if (bytes != NULL) \ if (bytes != NULL) \
Py_XDECREF(bytes); 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 WIN_PYTHON_REF(win) win->w_python3_ref
#define BUF_PYTHON_REF(buf) buf->b_python3_ref #define BUF_PYTHON_REF(buf) buf->b_python3_ref

View File

@@ -728,6 +728,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
998,
/**/ /**/
997, 997,
/**/ /**/