]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GC for frame objects.
authorNeil Schemenauer <nascheme@enme.ucalgary.ca>
Thu, 12 Jul 2001 13:27:11 +0000 (13:27 +0000)
committerNeil Schemenauer <nascheme@enme.ucalgary.ca>
Thu, 12 Jul 2001 13:27:11 +0000 (13:27 +0000)
Objects/frameobject.c

index 6af4e6e88ad75b68438bca53371d457927a65eb5..0801b932c516c55345c276a29f1c5027f08e6c0e 100644 (file)
@@ -70,6 +70,7 @@ frame_dealloc(PyFrameObject *f)
        PyObject **p;
 
        Py_TRASHCAN_SAFE_BEGIN(f)
+       PyObject_GC_Fini(f);
        /* Kill all local variables */
        slots = f->f_nlocals + f->f_ncells + f->f_nfreevars;
        fastlocals = f->f_localsplus;
@@ -97,21 +98,102 @@ frame_dealloc(PyFrameObject *f)
        Py_TRASHCAN_SAFE_END(f)
 }
 
+static int
+frame_traverse(PyFrameObject *f, visitproc visit, void *arg)
+{
+       PyObject **fastlocals, **p;
+       int i, err, slots;
+#define VISIT(o) if (o) {if ((err = visit((PyObject *)(o), arg))) return err;}
+
+       VISIT(f->f_back);
+       VISIT(f->f_code);
+       VISIT(f->f_builtins);
+       VISIT(f->f_globals);
+       VISIT(f->f_locals);
+       VISIT(f->f_trace);
+       VISIT(f->f_exc_type);
+       VISIT(f->f_exc_value);
+       VISIT(f->f_exc_traceback);
+
+       /* locals */
+       slots = f->f_nlocals + f->f_ncells + f->f_nfreevars;
+       fastlocals = f->f_localsplus;
+       for (i = slots; --i >= 0; ++fastlocals) {
+               VISIT(*fastlocals);
+       }
+
+       /* stack */
+       if (f->f_stacktop != NULL) {
+               for (p = f->f_valuestack; p < f->f_stacktop; p++)
+                       VISIT(*p);
+       }
+
+       return 0;
+}
+
+static void
+frame_clear(PyFrameObject *f)
+{
+       PyObject **fastlocals, **p;
+       int i, slots;
+
+       Py_XDECREF(f->f_exc_type);
+       f->f_exc_type = NULL;
+
+       Py_XDECREF(f->f_exc_value);
+       f->f_exc_value = NULL;
+
+       Py_XDECREF(f->f_exc_traceback);
+       f->f_exc_traceback = NULL;
+
+       Py_XDECREF(f->f_trace);
+       f->f_trace = NULL;
+
+       /* locals */
+       slots = f->f_nlocals + f->f_ncells + f->f_nfreevars;
+       fastlocals = f->f_localsplus;
+       for (i = slots; --i >= 0; ++fastlocals) {
+               if (*fastlocals != NULL) {
+                       Py_XDECREF(*fastlocals);
+                       *fastlocals = NULL;
+               }
+       }
+
+       /* stack */
+       if (f->f_stacktop != NULL) {
+               for (p = f->f_valuestack; p < f->f_stacktop; p++) {
+                       Py_XDECREF(*p);
+                       *p = NULL;
+               }
+       }
+}
+
+
 PyTypeObject PyFrame_Type = {
        PyObject_HEAD_INIT(&PyType_Type)
        0,
        "frame",
-       sizeof(PyFrameObject),
+       sizeof(PyFrameObject) + PyGC_HEAD_SIZE,
        0,
-       (destructor)frame_dealloc, /*tp_dealloc*/
-       0,              /*tp_print*/
-       (getattrfunc)frame_getattr, /*tp_getattr*/
-       (setattrfunc)frame_setattr, /*tp_setattr*/
-       0,              /*tp_compare*/
-       0,              /*tp_repr*/
-       0,              /*tp_as_number*/
-       0,              /*tp_as_sequence*/
-       0,              /*tp_as_mapping*/
+       (destructor)frame_dealloc,              /* tp_dealloc */
+       0,                                      /* tp_print */
+       (getattrfunc)frame_getattr,             /* tp_getattr */
+       (setattrfunc)frame_setattr,             /* tp_setattr */
+       0,                                      /* tp_compare */
+       0,                                      /* tp_repr */
+       0,                                      /* tp_as_number */
+       0,                                      /* tp_as_sequence */
+       0,                                      /* tp_as_mapping */
+       0,                                      /* tp_hash */
+       0,                                      /* tp_call */
+       0,                                      /* tp_str */
+       0,                                      /* tp_getattro */
+       0,                                      /* tp_setattro */
+       0,                                      /* tp_as_buffer */
+       Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,     /* tp_flags */
+       0,                                      /* tp_doc */
+       (traverseproc)frame_traverse,           /* tp_traverse */
+       (inquiry)frame_clear,                   /* tp_clear */
 };
 
 PyFrameObject *
@@ -155,9 +237,11 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
                /* PyObject_New is inlined */
                f = (PyFrameObject *)
                        PyObject_MALLOC(sizeof(PyFrameObject) +
-                                       extras*sizeof(PyObject *));
+                                       extras*sizeof(PyObject *) +
+                                       PyGC_HEAD_SIZE);
                if (f == NULL)
                        return (PyFrameObject *)PyErr_NoMemory();
+               f = (PyFrameObject *) PyObject_FROM_GC(f);
                PyObject_INIT(f, &PyFrame_Type);
                f->f_size = extras;
        }
@@ -165,11 +249,14 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
                f = free_list;
                free_list = free_list->f_back;
                if (f->f_size < extras) {
+                       f = (PyFrameObject *) PyObject_AS_GC(f);
                        f = (PyFrameObject *)
                                PyObject_REALLOC(f, sizeof(PyFrameObject) +
-                                                extras*sizeof(PyObject *));
+                                                extras*sizeof(PyObject *) +
+                                                PyGC_HEAD_SIZE);
                        if (f == NULL)
                                return (PyFrameObject *)PyErr_NoMemory();
+                       f = (PyFrameObject *) PyObject_FROM_GC(f);
                        f->f_size = extras;
                }
                else
@@ -230,6 +317,7 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
        f->f_valuestack = f->f_localsplus + (f->f_nlocals + ncells + nfrees);
        f->f_stacktop = f->f_valuestack;
 
+       PyObject_GC_Init(f);
        return f;
 }
 
@@ -391,6 +479,7 @@ PyFrame_Fini(void)
        while (free_list != NULL) {
                PyFrameObject *f = free_list;
                free_list = free_list->f_back;
+               f = (PyFrameObject *) PyObject_AS_GC(f);
                PyObject_DEL(f);
        }
 }