]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Variety of small INC/DECREF patches that fix reported memory leaks
authorJeremy Hylton <jeremy@alum.mit.edu>
Tue, 13 Mar 2001 01:58:22 +0000 (01:58 +0000)
committerJeremy Hylton <jeremy@alum.mit.edu>
Tue, 13 Mar 2001 01:58:22 +0000 (01:58 +0000)
with free variables.  Thanks to Martin v. Loewis for finding two of
the problems.  This fixes SF buf 405583.

There is also a C API change: PyFrame_New() is reverting to its
pre-2.1 signature.  The change introduced by nested scopes was a
mistake.  XXX Is this okay between beta releases?

cell_clear(), the GC helper, must decref its reference to break
cycles.

frame_dealloc() must dealloc all cell vars and free vars in addition
to locals.

eval_code2() setup code must INCREF cells it copies out of the
closure.

The STORE_DEREF opcode implementation must DECREF the object it passes
to PyCell_Set().

Include/frameobject.h
Modules/pyexpat.c
Objects/cellobject.c
Objects/frameobject.c
Python/ceval.c

index d1a310a288d3bbba1c5ecc4868bec178e313b096..10d4935591d15359dec81efd09a311d24ce997a0 100644 (file)
@@ -46,8 +46,7 @@ extern DL_IMPORT(PyTypeObject) PyFrame_Type;
 #define PyFrame_Check(op) ((op)->ob_type == &PyFrame_Type)
 
 DL_IMPORT(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *,
-                                       PyObject *, PyObject *,
-                                      PyObject *);
+                                       PyObject *, PyObject *);
 
 
 /* The rest of the interface is specific for frame objects */
index 4d7008dad2c01baae4e4255f13dce648d189eb85..ab5ca1841808e9403ad449c77155c8a4e47fd7a6 100644 (file)
@@ -356,9 +356,6 @@ call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args)
                     c,                         /*code*/
                     tstate->frame->f_globals,  /*globals*/
                     NULL                       /*locals*/
-#if PYTHON_API_VERSION >= 1010
-                    ,NULL                      /*closure*/
-#endif
                     );
     if (f == NULL)
         return NULL;
index d9ecfd76f00bff60ba1bb0d9842b4b104344eb9d..66fc8d1d52134c0165371a82501bea407ef08102 100644 (file)
@@ -83,6 +83,7 @@ cell_traverse(PyCellObject *op, visitproc visit, void *arg)
 static int
 cell_clear(PyCellObject *op)
 {
+       Py_XDECREF(op->ob_ref);
        op->ob_ref = NULL;
        return 0;
 }
index 18fb0b0adce4a1b8d94dd15e4635222dbf1e56a1..a5300d1de3e3c0fe286f69627332aa80d403c00c 100644 (file)
@@ -65,13 +65,14 @@ static PyFrameObject *free_list = NULL;
 static void
 frame_dealloc(PyFrameObject *f)
 {
-       int i;
+       int i, slots;
        PyObject **fastlocals;
 
        Py_TRASHCAN_SAFE_BEGIN(f)
        /* Kill all local variables */
+       slots = f->f_nlocals + f->f_ncells + f->f_nfreevars;
        fastlocals = f->f_localsplus;
-       for (i = f->f_nlocals; --i >= 0; ++fastlocals) {
+       for (i = slots; --i >= 0; ++fastlocals) {
                Py_XDECREF(*fastlocals);
        }
 
@@ -108,7 +109,7 @@ PyTypeObject PyFrame_Type = {
 
 PyFrameObject *
 PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, 
-           PyObject *locals, PyObject *closure)
+           PyObject *locals)
 {
        PyFrameObject *back = tstate->frame;
        static PyObject *builtin_object;
index 8f449a1e08fc2f96dbef7497caeb2350b646c1c9..cb5936de6160e1a451d0be24752da346f4e60a80 100644 (file)
@@ -430,7 +430,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
 
        f = PyFrame_New(tstate,                 /*back*/
                        co,                     /*code*/
-                       globals, locals, closure);
+                       globals, locals);
        if (f == NULL)
                return NULL;
 
@@ -578,8 +578,11 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
        }
        if (f->f_nfreevars) {
                int i;
-               for (i = 0; i < f->f_nfreevars; ++i)
-                       freevars[f->f_ncells + i] = PyTuple_GET_ITEM(closure, i);
+               for (i = 0; i < f->f_nfreevars; ++i) {
+                       PyObject *o = PyTuple_GET_ITEM(closure, i);
+                       Py_INCREF(o);
+                       freevars[f->f_ncells + i] = o;
+               }
        }
 
        if (tstate->sys_tracefunc != NULL) {
@@ -1662,7 +1665,6 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
                                err = -1;
                                break;
                        }
-                       Py_INCREF(w);
                        PUSH(w);
                        break;
 
@@ -1670,6 +1672,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
                        w = POP();
                        x = freevars[oparg];
                        PyCell_Set(x, w);
+                       Py_DECREF(w);
                        continue;
 
                case BUILD_TUPLE: