@@ -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+
100172PyTypeObject 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
117199PyFrameObject *
@@ -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