summaryrefslogtreecommitdiffstats
path: root/Objects/frameobject.c
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2001-01-29 22:51:52 (GMT)
committerJeremy Hylton <jeremy@alum.mit.edu>2001-01-29 22:51:52 (GMT)
commit2b724da8d9cd0c41a51e798eca75018ce155e997 (patch)
tree96a1648e0d50dbbd7ae56b3b55e7b44b107362dd /Objects/frameobject.c
parent55087f0c351d6de453a5c95293792051d899f16b (diff)
downloadcpython-2b724da8d9cd0c41a51e798eca75018ce155e997.zip
cpython-2b724da8d9cd0c41a51e798eca75018ce155e997.tar.gz
cpython-2b724da8d9cd0c41a51e798eca75018ce155e997.tar.bz2
Remove f_closure slot of frameobject and use f_localsplus instead.
This change eliminates an extra malloc/free when a frame with free variables is created. Any cell vars or free vars are stored in f_localsplus after the locals and before the stack. eval_code2() fills in the appropriate values after handling initialization of locals. To track the size the frame has an f_size member that tracks the total size of f_localsplus. It used to be implicitly f_nlocals + f_stacksize.
Diffstat (limited to 'Objects/frameobject.c')
-rw-r--r--Objects/frameobject.c37
1 files changed, 14 insertions, 23 deletions
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 0f6372b..18fb0b0 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -49,6 +49,7 @@ frame_setattr(PyFrameObject *f, char *name, PyObject *value)
f_back next item on free list, or NULL
f_nlocals number of locals
f_stacksize size of value stack
+ f_size size of localsplus
Note that the value and block stacks are preserved -- this can save
another malloc() call or two (and two free() calls as well!).
Also note that, unlike for integers, each frame object is a
@@ -79,7 +80,6 @@ frame_dealloc(PyFrameObject *f)
Py_XDECREF(f->f_builtins);
Py_XDECREF(f->f_globals);
Py_XDECREF(f->f_locals);
- Py_XDECREF(f->f_closure);
Py_XDECREF(f->f_trace);
Py_XDECREF(f->f_exc_type);
Py_XDECREF(f->f_exc_value);
@@ -114,7 +114,7 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
static PyObject *builtin_object;
PyFrameObject *f;
PyObject *builtins;
- int extras, ncells;
+ int extras, ncells, nfrees;
if (builtin_object == NULL) {
builtin_object = PyString_InternFromString("__builtins__");
@@ -128,8 +128,9 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
PyErr_BadInternalCall();
return NULL;
}
- extras = code->co_stacksize + code->co_nlocals;
ncells = PyTuple_GET_SIZE(code->co_cellvars);
+ nfrees = PyTuple_GET_SIZE(code->co_freevars);
+ extras = code->co_stacksize + code->co_nlocals + ncells + nfrees;
if (back == NULL || back->f_globals != globals) {
builtins = PyDict_GetItem(globals, builtin_object);
if (builtins != NULL && PyModule_Check(builtins))
@@ -150,19 +151,21 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
if (f == NULL)
return (PyFrameObject *)PyErr_NoMemory();
PyObject_INIT(f, &PyFrame_Type);
+ f->f_size = extras;
}
else {
f = free_list;
free_list = free_list->f_back;
- if (f->f_nlocals + f->f_stacksize < extras) {
+ if (f->f_size < extras) {
f = (PyFrameObject *)
PyObject_REALLOC(f, sizeof(PyFrameObject) +
extras*sizeof(PyObject *));
if (f == NULL)
return (PyFrameObject *)PyErr_NoMemory();
+ f->f_size = extras;
}
else
- extras = f->f_nlocals + f->f_stacksize;
+ extras = f->f_size;
PyObject_INIT(f, &PyFrame_Type);
}
if (builtins == NULL) {
@@ -199,22 +202,6 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
locals = globals;
Py_INCREF(locals);
}
- if (closure || ncells) {
- int i, size;
- size = ncells;
- if (closure)
- size += PyTuple_GET_SIZE(closure);
- f->f_closure = PyTuple_New(size);
- for (i = 0; i < ncells; ++i)
- PyTuple_SET_ITEM(f->f_closure, i, PyCell_New(NULL));
- for (i = ncells; i < size; ++i) {
- PyObject *o = PyTuple_GET_ITEM(closure, i - ncells);
- Py_INCREF(o);
- PyTuple_SET_ITEM(f->f_closure, i, o);
- }
- }
- else
- f->f_closure = NULL;
f->f_locals = locals;
f->f_trace = NULL;
f->f_exc_type = f->f_exc_value = f->f_exc_traceback = NULL;
@@ -225,12 +212,14 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
f->f_restricted = (builtins != tstate->interp->builtins);
f->f_iblock = 0;
f->f_nlocals = code->co_nlocals;
- f->f_stacksize = extras - code->co_nlocals;
+ f->f_stacksize = code->co_stacksize;
+ f->f_ncells = ncells;
+ f->f_nfreevars = nfrees;
while (--extras >= 0)
f->f_localsplus[extras] = NULL;
- f->f_valuestack = f->f_localsplus + f->f_nlocals;
+ f->f_valuestack = f->f_localsplus + (f->f_nlocals + ncells + nfrees);
return f;
}
@@ -261,6 +250,8 @@ PyFrame_BlockPop(PyFrameObject *f)
/* Convert between "fast" version of locals and dictionary version */
+/* XXX should also copy free variables and cell variables */
+
void
PyFrame_FastToLocals(PyFrameObject *f)
{