From cebbefc98dd7b30ae8c5f7640951e247ece49991 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Tue, 23 May 2006 18:28:17 +0000 Subject: Applied patch 1337051 by Neal Norwitz, saving 4 ints on frame objects. --- Include/frameobject.h | 4 ---- Misc/NEWS | 5 ++++ Objects/frameobject.c | 66 +++++++++++++++++++++++++-------------------------- Python/ceval.c | 34 +++++++++++++------------- 4 files changed, 54 insertions(+), 55 deletions(-) diff --git a/Include/frameobject.h b/Include/frameobject.h index 7dc14e3..1e3a01e 100644 --- a/Include/frameobject.h +++ b/Include/frameobject.h @@ -36,10 +36,6 @@ typedef struct _frame { in this scope */ int f_iblock; /* index in f_blockstack */ PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */ - int f_nlocals; /* number of locals */ - int f_ncells; - int f_nfreevars; - int f_stacksize; /* size of value stack */ PyObject *f_localsplus[1]; /* locals+stack, dynamically sized */ } PyFrameObject; diff --git a/Misc/NEWS b/Misc/NEWS index cfb1d15..0cccec9 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,11 @@ What's New in Python 2.5 alpha 3? Core and builtins ----------------- +- Patch #1337051: reduced size of frame objects. + +- PyErr_NewException now accepts a tuple of base classes as its + "base" parameter. + - PyErr_NewException now accepts a tuple of base classes as its "base" parameter. diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 9a65c8f..0803957 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -377,7 +377,6 @@ static PyGetSetDef frame_getsetlist[] = { a meaning: ob_type == &Frametype f_back next item on free list, or NULL - f_nlocals number of locals f_stacksize size of value stack ob_size size of localsplus Note that the value and block stacks are preserved -- this can save @@ -458,7 +457,7 @@ frame_traverse(PyFrameObject *f, visitproc visit, void *arg) Py_VISIT(f->f_exc_traceback); /* locals */ - slots = f->f_nlocals + f->f_ncells + f->f_nfreevars; + slots = f->f_code->co_nlocals + PyTuple_GET_SIZE(f->f_code->co_cellvars) + PyTuple_GET_SIZE(f->f_code->co_freevars); fastlocals = f->f_localsplus; for (i = slots; --i >= 0; ++fastlocals) Py_VISIT(*fastlocals); @@ -491,7 +490,7 @@ frame_clear(PyFrameObject *f) Py_CLEAR(f->f_trace); /* locals */ - slots = f->f_nlocals + f->f_ncells + f->f_nfreevars; + slots = f->f_code->co_nlocals + PyTuple_GET_SIZE(f->f_code->co_cellvars) + PyTuple_GET_SIZE(f->f_code->co_freevars); fastlocals = f->f_localsplus; for (i = slots; --i >= 0; ++fastlocals) Py_CLEAR(*fastlocals); @@ -760,7 +759,9 @@ PyFrame_FastToLocals(PyFrameObject *f) PyObject *locals, *map; PyObject **fast; PyObject *error_type, *error_value, *error_traceback; + PyCodeObject *co; Py_ssize_t j; + int ncells, nfreevars; if (f == NULL) return; locals = f->f_locals; @@ -771,27 +772,24 @@ PyFrame_FastToLocals(PyFrameObject *f) return; } } - map = f->f_code->co_varnames; + co = f->f_code; + map = co->co_varnames; if (!PyTuple_Check(map)) return; PyErr_Fetch(&error_type, &error_value, &error_traceback); fast = f->f_localsplus; j = PyTuple_GET_SIZE(map); - if (j > f->f_nlocals) - j = f->f_nlocals; - if (f->f_nlocals) + if (j > co->co_nlocals) + j = co->co_nlocals; + if (co->co_nlocals) map_to_dict(map, j, locals, fast, 0); - if (f->f_ncells || f->f_nfreevars) { - if (!(PyTuple_Check(f->f_code->co_cellvars) - && PyTuple_Check(f->f_code->co_freevars))) { - return; - } - map_to_dict(f->f_code->co_cellvars, - PyTuple_GET_SIZE(f->f_code->co_cellvars), - locals, fast + f->f_nlocals, 1); - map_to_dict(f->f_code->co_freevars, - PyTuple_GET_SIZE(f->f_code->co_freevars), - locals, fast + f->f_nlocals + f->f_ncells, 1); + ncells = PyTuple_GET_SIZE(co->co_cellvars); + nfreevars = PyTuple_GET_SIZE(co->co_freevars); + if (ncells || nfreevars) { + map_to_dict(co->co_cellvars, ncells, + locals, fast + co->co_nlocals, 1); + map_to_dict(co->co_freevars, nfreevars, + locals, fast + co->co_nlocals + ncells, 1); } PyErr_Restore(error_type, error_value, error_traceback); } @@ -803,11 +801,14 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear) PyObject *locals, *map; PyObject **fast; PyObject *error_type, *error_value, *error_traceback; + PyCodeObject *co; Py_ssize_t j; + int ncells, nfreevars; if (f == NULL) return; locals = f->f_locals; - map = f->f_code->co_varnames; + co = f->f_code; + map = co->co_varnames; if (locals == NULL) return; if (!PyTuple_Check(map)) @@ -815,21 +816,18 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear) PyErr_Fetch(&error_type, &error_value, &error_traceback); fast = f->f_localsplus; j = PyTuple_GET_SIZE(map); - if (j > f->f_nlocals) - j = f->f_nlocals; - if (f->f_nlocals) - dict_to_map(f->f_code->co_varnames, j, locals, fast, 0, clear); - if (f->f_ncells || f->f_nfreevars) { - if (!(PyTuple_Check(f->f_code->co_cellvars) - && PyTuple_Check(f->f_code->co_freevars))) - return; - dict_to_map(f->f_code->co_cellvars, - PyTuple_GET_SIZE(f->f_code->co_cellvars), - locals, fast + f->f_nlocals, 1, clear); - dict_to_map(f->f_code->co_freevars, - PyTuple_GET_SIZE(f->f_code->co_freevars), - locals, fast + f->f_nlocals + f->f_ncells, 1, - clear); + if (j > co->co_nlocals) + j = co->co_nlocals; + if (co->co_nlocals) + dict_to_map(co->co_varnames, j, locals, fast, 0, clear); + ncells = PyTuple_GET_SIZE(co->co_cellvars); + nfreevars = PyTuple_GET_SIZE(co->co_freevars); + if (ncells || nfreevars) { + dict_to_map(co->co_cellvars, ncells, + locals, fast + co->co_nlocals, 1, clear); + dict_to_map(co->co_freevars, nfreevars, + locals, fast + co->co_nlocals + ncells, 1, + clear); } PyErr_Restore(error_type, error_value, error_traceback); } diff --git a/Python/ceval.c b/Python/ceval.c index 43dcdd0..b59f718 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -654,11 +654,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) #ifdef LLTRACE #define PUSH(v) { (void)(BASIC_PUSH(v), \ lltrace && prtrace(TOP(), "push")); \ - assert(STACK_LEVEL() <= f->f_stacksize); } + assert(STACK_LEVEL() <= co->co_stacksize); } #define POP() ((void)(lltrace && prtrace(TOP(), "pop")), BASIC_POP()) #define STACKADJ(n) { (void)(BASIC_STACKADJ(n), \ lltrace && prtrace(TOP(), "stackadj")); \ - assert(STACK_LEVEL() <= f->f_stacksize); } + assert(STACK_LEVEL() <= co->co_stacksize); } #define EXT_POP(STACK_POINTER) (lltrace && prtrace(*(STACK_POINTER), "ext_pop"), *--(STACK_POINTER)) #else #define PUSH(v) BASIC_PUSH(v) @@ -729,7 +729,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) names = co->co_names; consts = co->co_consts; fastlocals = f->f_localsplus; - freevars = f->f_localsplus + f->f_nlocals; + freevars = f->f_localsplus + co->co_nlocals; first_instr = (unsigned char*) PyString_AS_STRING(co->co_code); /* An explanation is in order for the next line. @@ -780,7 +780,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) READ_TIMESTAMP(loop0); #endif assert(stack_pointer >= f->f_valuestack); /* else underflow */ - assert(STACK_LEVEL() <= f->f_stacksize); /* else overflow */ + assert(STACK_LEVEL() <= co->co_stacksize); /* else overflow */ /* Do periodic things. Doing this every time through the loop would add too much overhead, so we do it @@ -1916,17 +1916,17 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) /* Don't stomp existing exception */ if (PyErr_Occurred()) break; - if (oparg < f->f_ncells) { - v = PyTuple_GetItem(co->co_cellvars, + if (oparg < PyTuple_GET_SIZE(co->co_cellvars)) { + v = PyTuple_GET_ITEM(co->co_cellvars, oparg); format_exc_check_arg( PyExc_UnboundLocalError, UNBOUNDLOCAL_ERROR_MSG, v); } else { - v = PyTuple_GetItem( + v = PyTuple_GET_ITEM( co->co_freevars, - oparg - f->f_ncells); + oparg - PyTuple_GET_SIZE(co->co_cellvars)); format_exc_check_arg( PyExc_NameError, UNBOUNDFREE_ERROR_MSG, @@ -2610,7 +2610,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals, return NULL; fastlocals = f->f_localsplus; - freevars = f->f_localsplus + f->f_nlocals; + freevars = f->f_localsplus + co->co_nlocals; if (co->co_argcount > 0 || co->co_flags & (CO_VARARGS | CO_VARKEYWORDS)) { @@ -2746,7 +2746,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals, } /* Allocate and initialize storage for cell vars, and copy free vars into frame. This isn't too efficient right now. */ - if (f->f_ncells) { + if (PyTuple_GET_SIZE(co->co_cellvars)) { int i = 0, j = 0, nargs, found; char *cellname, *argname; PyObject *c; @@ -2764,7 +2764,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals, that are arguments at the beginning of the cellvars list so that we can march over it more efficiently? */ - for (i = 0; i < f->f_ncells; ++i) { + for (i = 0; i < PyTuple_GET_SIZE(co->co_cellvars); ++i) { cellname = PyString_AS_STRING( PyTuple_GET_ITEM(co->co_cellvars, i)); found = 0; @@ -2775,7 +2775,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals, c = PyCell_New(GETLOCAL(j)); if (c == NULL) goto fail; - GETLOCAL(f->f_nlocals + i) = c; + GETLOCAL(co->co_nlocals + i) = c; found = 1; break; } @@ -2784,16 +2784,16 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals, c = PyCell_New(NULL); if (c == NULL) goto fail; - SETLOCAL(f->f_nlocals + i, c); + SETLOCAL(co->co_nlocals + i, c); } } } - if (f->f_nfreevars) { + if (PyTuple_GET_SIZE(co->co_freevars)) { int i; - for (i = 0; i < f->f_nfreevars; ++i) { + for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) { PyObject *o = PyTuple_GET_ITEM(closure, i); Py_INCREF(o); - freevars[f->f_ncells + i] = o; + freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o; } } @@ -4214,7 +4214,7 @@ string_concatenate(PyObject *v, PyObject *w, } case STORE_DEREF: { - PyObject **freevars = f->f_localsplus + f->f_nlocals; + PyObject **freevars = f->f_localsplus + f->f_code->co_nlocals; PyObject *c = freevars[PEEKARG()]; if (PyCell_GET(c) == v) PyCell_Set(c, NULL); -- cgit v0.12