mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
GC for frame objects.
This commit is contained in:
parent
b20e9dbf89
commit
19cd292bbc
1 changed files with 101 additions and 12 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue