Index: Include/frameobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/frameobject.h,v retrieving revision 2.37 diff -c -r2.37 frameobject.h *** Include/frameobject.h 11 Sep 2002 15:36:31 -0000 2.37 --- Include/frameobject.h 8 Jan 2004 17:21:39 -0000 *************** *** 48,55 **** PyAPI_DATA(PyTypeObject) PyFrame_Type; ! #define PyFrame_Check(op) ((op)->ob_type == &PyFrame_Type) PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *, PyObject *, PyObject *); --- 48,58 ---- PyAPI_DATA(PyTypeObject) PyFrame_Type; ! #define PyFrame_Check(op) ((op)->ob_type == &PyFrame_Type \ ! || PyType_IsSubtype((op)->ob_type, &PyFrame_Type)) + PyAPI_FUNC(PyFrameObject *) PyFrame_NewLight(PyThreadState *, PyCodeObject *, + PyObject *); PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *, PyObject *, PyObject *); Index: Objects/frameobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/frameobject.c,v retrieving revision 2.76 diff -c -r2.76 frameobject.c *** Objects/frameobject.c 21 Oct 2003 18:14:20 -0000 2.76 --- Objects/frameobject.c 8 Jan 2004 17:21:40 -0000 *************** *** 334,341 **** Py_XINCREF(v); f->f_trace = v; ! if (v != NULL) f->f_lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); Py_XDECREF(old_value); --- 334,343 ---- Py_XINCREF(v); f->f_trace = v; ! if (v != NULL) { f->f_lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); + f->ob_type = &PyFrame_Type; + } Py_XDECREF(old_value); *************** *** 375,380 **** --- 377,383 ---- */ static PyFrameObject *free_list = NULL; + static PyFrameObject *light_free_list = NULL; static int numfree = 0; /* number of frames currently in free_list */ #define MAXFREELIST 200 /* max value for numfree */ *************** *** 419,424 **** --- 422,466 ---- Py_TRASHCAN_SAFE_END(f) } + static void + light_frame_dealloc(PyFrameObject *f) + { + int i, slots; + PyObject **fastlocals; + PyObject **p; + + PyObject_GC_UnTrack(f); + 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 = slots; --i >= 0; ++fastlocals) { + Py_XDECREF(*fastlocals); + } + + /* Free stack */ + if (f->f_stacktop != NULL) { + for (p = f->f_valuestack; p < f->f_stacktop; p++) + Py_XDECREF(*p); + } + + Py_XDECREF(f->f_back); + Py_DECREF(f->f_code); + Py_DECREF(f->f_builtins); + Py_DECREF(f->f_globals); + Py_XDECREF(f->f_exc_type); + Py_XDECREF(f->f_exc_value); + Py_XDECREF(f->f_exc_traceback); + if (numfree < MAXFREELIST) { + ++numfree; + f->f_back = light_free_list; + light_free_list = f; + } + else + PyObject_GC_Del(f); + Py_TRASHCAN_SAFE_END(f) + } + static int frame_traverse(PyFrameObject *f, visitproc visit, void *arg) { *************** *** 525,535 **** --- 567,614 ---- 0, /* tp_dict */ }; + PyTypeObject PyLightFrame_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "lightweight-frame", + sizeof(PyFrameObject), + sizeof(PyObject *), + (destructor)light_frame_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* 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 */ + PyObject_GenericGetAttr, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + 0, /* tp_doc */ + (traverseproc)frame_traverse, /* tp_traverse */ + (inquiry)frame_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + frame_memberlist, /* tp_members */ + frame_getsetlist, /* tp_getset */ + &PyFrame_Type, /* tp_base */ + 0, /* tp_dict */ + }; + static PyObject *builtin_object; int _PyFrame_Init() { builtin_object = PyString_InternFromString("__builtins__"); + PyType_Ready(&PyLightFrame_Type); return (builtin_object != NULL); } *************** *** 645,650 **** --- 724,800 ---- return f; } + PyFrameObject * + PyFrame_NewLight(PyThreadState *tstate, PyCodeObject *code, PyObject *globals) + { + PyFrameObject *back = tstate->frame; + PyFrameObject *f; + PyObject* builtins; + int extras; + + #ifdef Py_DEBUG + if (code == NULL || globals == NULL || !PyDict_Check(globals)) { + PyErr_BadInternalCall(); + return NULL; + } + assert(PyTuple_GET_SIZE(code->co_cellvars) == 0); + assert(PyTuple_GET_SIZE(code->co_freevars) == 0); + #endif + extras = code->co_stacksize + code->co_nlocals; + + /* XXX is this right? */ + builtins = back->f_builtins; + assert(builtins != NULL && PyDict_Check(builtins)); + + if (light_free_list == NULL) { + f = PyObject_GC_NewVar( + PyFrameObject, &PyLightFrame_Type, extras); + if (f == NULL) + return NULL; + f->f_ncells = 0; + f->f_nfreevars = 0; + f->f_locals = NULL; + f->f_trace = NULL; + } + else { + assert(numfree > 0); + --numfree; + f = light_free_list; + light_free_list = light_free_list->f_back; + if (f->ob_size < extras) { + f = PyObject_GC_Resize(PyFrameObject, f, extras); + if (f == NULL) + return NULL; + } + _Py_NewReference((PyObject *)f); + } + Py_INCREF(builtins); + f->f_builtins = builtins; + Py_INCREF(back); + f->f_back = back; + Py_INCREF(code); + f->f_code = code; + Py_INCREF(globals); + f->f_globals = globals; + + f->f_exc_type = f->f_exc_value = f->f_exc_traceback = NULL; + f->f_tstate = tstate; + + f->f_lasti = -1; + f->f_lineno = code->co_firstlineno; + f->f_restricted = (builtins != tstate->interp->builtins); + f->f_iblock = 0; + f->f_nlocals = code->co_nlocals; + f->f_stacksize = code->co_stacksize; + + memset(f->f_localsplus, 0, f->f_nlocals * sizeof(f->f_localsplus[0])); + + f->f_valuestack = f->f_localsplus + f->f_nlocals; + f->f_stacktop = f->f_valuestack; + _PyObject_GC_TRACK(f); + return f; + } + /* Block management */ void *************** *** 734,739 **** --- 884,890 ---- PyErr_Clear(); /* Can't report it :-( */ return; } + f->ob_type = &PyFrame_Type; } map = f->f_code->co_varnames; if (!PyDict_Check(locals) || !PyTuple_Check(map)) *************** *** 806,811 **** --- 957,968 ---- while (free_list != NULL) { PyFrameObject *f = free_list; free_list = free_list->f_back; + PyObject_GC_Del(f); + --numfree; + } + while (light_free_list != NULL) { + PyFrameObject *f = light_free_list; + light_free_list = light_free_list->f_back; PyObject_GC_Del(f); --numfree; } Index: Python/ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.373 diff -c -r2.373 ceval.c *** Python/ceval.c 20 Nov 2003 01:44:58 -0000 2.373 --- Python/ceval.c 8 Jan 2004 17:21:40 -0000 *************** *** 3516,3522 **** PyFrame_New() that doesn't take locals, but does take builtins without sanity checking them. */ ! f = PyFrame_New(tstate, co, globals, NULL); if (f == NULL) return NULL; --- 3516,3522 ---- PyFrame_New() that doesn't take locals, but does take builtins without sanity checking them. */ ! f = PyFrame_NewLight(tstate, co, globals); if (f == NULL) return NULL; Index: Python/sysmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v retrieving revision 2.121 diff -c -r2.121 sysmodule.c *** Python/sysmodule.c 9 Aug 2003 09:47:11 -0000 2.121 --- Python/sysmodule.c 8 Jan 2004 17:21:40 -0000 *************** *** 368,373 **** --- 368,374 ---- frame->f_trace = NULL; Py_XDECREF(temp); frame->f_trace = result; + frame->ob_type = &PyFrame_Type; } else { Py_DECREF(result);