Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 19cd292

Browse files
committed
GC for frame objects.
1 parent b20e9db commit 19cd292

1 file changed

Lines changed: 101 additions & 12 deletions

File tree

Objects/frameobject.c

Lines changed: 101 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ frame_dealloc(PyFrameObject *f)
7070
PyObject **p;
7171

7272
Py_TRASHCAN_SAFE_BEGIN(f)
73+
PyObject_GC_Fini(f);
7374
/* Kill all local variables */
7475
slots = f->f_nlocals + f->f_ncells + f->f_nfreevars;
7576
fastlocals = f->f_localsplus;
@@ -97,21 +98,102 @@ frame_dealloc(PyFrameObject *f)
9798
Py_TRASHCAN_SAFE_END(f)
9899
}
99100

101+
static int
102+
frame_traverse(PyFrameObject *f, visitproc visit, void *arg)
103+
{
104+
PyObject **fastlocals, **p;
105+
int i, err, slots;
106+
#define VISIT(o) if (o) {if ((err = visit((PyObject *)(o), arg))) return err;}
107+
108+
VISIT(f->f_back);
109+
VISIT(f->f_code);
110+
VISIT(f->f_builtins);
111+
VISIT(f->f_globals);
112+
VISIT(f->f_locals);
113+
VISIT(f->f_trace);
114+
VISIT(f->f_exc_type);
115+
VISIT(f->f_exc_value);
116+
VISIT(f->f_exc_traceback);
117+
118+
/* locals */
119+
slots = f->f_nlocals + f->f_ncells + f->f_nfreevars;
120+
fastlocals = f->f_localsplus;
121+
for (i = slots; --i >= 0; ++fastlocals) {
122+
VISIT(*fastlocals);
123+
}
124+
125+
/* stack */
126+
if (f->f_stacktop != NULL) {
127+
for (p = f->f_valuestack; p < f->f_stacktop; p++)
128+
VISIT(*p);
129+
}
130+
131+
return 0;
132+
}
133+
134+
static void
135+
frame_clear(PyFrameObject *f)
136+
{
137+
PyObject **fastlocals, **p;
138+
int i, slots;
139+
140+
Py_XDECREF(f->f_exc_type);
141+
f->f_exc_type = NULL;
142+
143+
Py_XDECREF(f->f_exc_value);
144+
f->f_exc_value = NULL;
145+
146+
Py_XDECREF(f->f_exc_traceback);
147+
f->f_exc_traceback = NULL;
148+
149+
Py_XDECREF(f->f_trace);
150+
f->f_trace = NULL;
151+
152+
/* locals */
153+
slots = f->f_nlocals + f->f_ncells + f->f_nfreevars;
154+
fastlocals = f->f_localsplus;
155+
for (i = slots; --i >= 0; ++fastlocals) {
156+
if (*fastlocals != NULL) {
157+
Py_XDECREF(*fastlocals);
158+
*fastlocals = NULL;
159+
}
160+
}
161+
162+
/* stack */
163+
if (f->f_stacktop != NULL) {
164+
for (p = f->f_valuestack; p < f->f_stacktop; p++) {
165+
Py_XDECREF(*p);
166+
*p = NULL;
167+
}
168+
}
169+
}
170+
171+
100172
PyTypeObject PyFrame_Type = {
101173
PyObject_HEAD_INIT(&PyType_Type)
102174
0,
103175
"frame",
104-
sizeof(PyFrameObject),
176+
sizeof(PyFrameObject) + PyGC_HEAD_SIZE,
105177
0,
106-
(destructor)frame_dealloc, /*tp_dealloc*/
107-
0, /*tp_print*/
108-
(getattrfunc)frame_getattr, /*tp_getattr*/
109-
(setattrfunc)frame_setattr, /*tp_setattr*/
110-
0, /*tp_compare*/
111-
0, /*tp_repr*/
112-
0, /*tp_as_number*/
113-
0, /*tp_as_sequence*/
114-
0, /*tp_as_mapping*/
178+
(destructor)frame_dealloc, /* tp_dealloc */
179+
0, /* tp_print */
180+
(getattrfunc)frame_getattr, /* tp_getattr */
181+
(setattrfunc)frame_setattr, /* tp_setattr */
182+
0, /* tp_compare */
183+
0, /* tp_repr */
184+
0, /* tp_as_number */
185+
0, /* tp_as_sequence */
186+
0, /* tp_as_mapping */
187+
0, /* tp_hash */
188+
0, /* tp_call */
189+
0, /* tp_str */
190+
0, /* tp_getattro */
191+
0, /* tp_setattro */
192+
0, /* tp_as_buffer */
193+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /* tp_flags */
194+
0, /* tp_doc */
195+
(traverseproc)frame_traverse, /* tp_traverse */
196+
(inquiry)frame_clear, /* tp_clear */
115197
};
116198

117199
PyFrameObject *
@@ -155,21 +237,26 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
155237
/* PyObject_New is inlined */
156238
f = (PyFrameObject *)
157239
PyObject_MALLOC(sizeof(PyFrameObject) +
158-
extras*sizeof(PyObject *));
240+
extras*sizeof(PyObject *) +
241+
PyGC_HEAD_SIZE);
159242
if (f == NULL)
160243
return (PyFrameObject *)PyErr_NoMemory();
244+
f = (PyFrameObject *) PyObject_FROM_GC(f);
161245
PyObject_INIT(f, &PyFrame_Type);
162246
f->f_size = extras;
163247
}
164248
else {
165249
f = free_list;
166250
free_list = free_list->f_back;
167251
if (f->f_size < extras) {
252+
f = (PyFrameObject *) PyObject_AS_GC(f);
168253
f = (PyFrameObject *)
169254
PyObject_REALLOC(f, sizeof(PyFrameObject) +
170-
extras*sizeof(PyObject *));
255+
extras*sizeof(PyObject *) +
256+
PyGC_HEAD_SIZE);
171257
if (f == NULL)
172258
return (PyFrameObject *)PyErr_NoMemory();
259+
f = (PyFrameObject *) PyObject_FROM_GC(f);
173260
f->f_size = extras;
174261
}
175262
else
@@ -230,6 +317,7 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
230317
f->f_valuestack = f->f_localsplus + (f->f_nlocals + ncells + nfrees);
231318
f->f_stacktop = f->f_valuestack;
232319

320+
PyObject_GC_Init(f);
233321
return f;
234322
}
235323

@@ -391,6 +479,7 @@ PyFrame_Fini(void)
391479
while (free_list != NULL) {
392480
PyFrameObject *f = free_list;
393481
free_list = free_list->f_back;
482+
f = (PyFrameObject *) PyObject_AS_GC(f);
394483
PyObject_DEL(f);
395484
}
396485
}

0 commit comments

Comments
 (0)