Applied patch 1337051 by Neal Norwitz, saving 4 ints on frame objects.

This commit is contained in:
Richard Jones 2006-05-23 18:28:17 +00:00
parent 69c347655d
commit cebbefc98d
4 changed files with 54 additions and 55 deletions

View File

@ -36,10 +36,6 @@ typedef struct _frame {
in this scope */ in this scope */
int f_iblock; /* index in f_blockstack */ int f_iblock; /* index in f_blockstack */
PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */ 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 */ PyObject *f_localsplus[1]; /* locals+stack, dynamically sized */
} PyFrameObject; } PyFrameObject;

View File

@ -12,6 +12,11 @@ What's New in Python 2.5 alpha 3?
Core and builtins 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 - PyErr_NewException now accepts a tuple of base classes as its
"base" parameter. "base" parameter.

View File

@ -377,7 +377,6 @@ static PyGetSetDef frame_getsetlist[] = {
a meaning: a meaning:
ob_type == &Frametype ob_type == &Frametype
f_back next item on free list, or NULL f_back next item on free list, or NULL
f_nlocals number of locals
f_stacksize size of value stack f_stacksize size of value stack
ob_size size of localsplus ob_size size of localsplus
Note that the value and block stacks are preserved -- this can save 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); Py_VISIT(f->f_exc_traceback);
/* locals */ /* 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; fastlocals = f->f_localsplus;
for (i = slots; --i >= 0; ++fastlocals) for (i = slots; --i >= 0; ++fastlocals)
Py_VISIT(*fastlocals); Py_VISIT(*fastlocals);
@ -491,7 +490,7 @@ frame_clear(PyFrameObject *f)
Py_CLEAR(f->f_trace); Py_CLEAR(f->f_trace);
/* locals */ /* 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; fastlocals = f->f_localsplus;
for (i = slots; --i >= 0; ++fastlocals) for (i = slots; --i >= 0; ++fastlocals)
Py_CLEAR(*fastlocals); Py_CLEAR(*fastlocals);
@ -760,7 +759,9 @@ PyFrame_FastToLocals(PyFrameObject *f)
PyObject *locals, *map; PyObject *locals, *map;
PyObject **fast; PyObject **fast;
PyObject *error_type, *error_value, *error_traceback; PyObject *error_type, *error_value, *error_traceback;
PyCodeObject *co;
Py_ssize_t j; Py_ssize_t j;
int ncells, nfreevars;
if (f == NULL) if (f == NULL)
return; return;
locals = f->f_locals; locals = f->f_locals;
@ -771,27 +772,24 @@ PyFrame_FastToLocals(PyFrameObject *f)
return; return;
} }
} }
map = f->f_code->co_varnames; co = f->f_code;
map = co->co_varnames;
if (!PyTuple_Check(map)) if (!PyTuple_Check(map))
return; return;
PyErr_Fetch(&error_type, &error_value, &error_traceback); PyErr_Fetch(&error_type, &error_value, &error_traceback);
fast = f->f_localsplus; fast = f->f_localsplus;
j = PyTuple_GET_SIZE(map); j = PyTuple_GET_SIZE(map);
if (j > f->f_nlocals) if (j > co->co_nlocals)
j = f->f_nlocals; j = co->co_nlocals;
if (f->f_nlocals) if (co->co_nlocals)
map_to_dict(map, j, locals, fast, 0); map_to_dict(map, j, locals, fast, 0);
if (f->f_ncells || f->f_nfreevars) { ncells = PyTuple_GET_SIZE(co->co_cellvars);
if (!(PyTuple_Check(f->f_code->co_cellvars) nfreevars = PyTuple_GET_SIZE(co->co_freevars);
&& PyTuple_Check(f->f_code->co_freevars))) { if (ncells || nfreevars) {
return; map_to_dict(co->co_cellvars, ncells,
} locals, fast + co->co_nlocals, 1);
map_to_dict(f->f_code->co_cellvars, map_to_dict(co->co_freevars, nfreevars,
PyTuple_GET_SIZE(f->f_code->co_cellvars), locals, fast + co->co_nlocals + ncells, 1);
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);
} }
PyErr_Restore(error_type, error_value, error_traceback); PyErr_Restore(error_type, error_value, error_traceback);
} }
@ -803,11 +801,14 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear)
PyObject *locals, *map; PyObject *locals, *map;
PyObject **fast; PyObject **fast;
PyObject *error_type, *error_value, *error_traceback; PyObject *error_type, *error_value, *error_traceback;
PyCodeObject *co;
Py_ssize_t j; Py_ssize_t j;
int ncells, nfreevars;
if (f == NULL) if (f == NULL)
return; return;
locals = f->f_locals; locals = f->f_locals;
map = f->f_code->co_varnames; co = f->f_code;
map = co->co_varnames;
if (locals == NULL) if (locals == NULL)
return; return;
if (!PyTuple_Check(map)) if (!PyTuple_Check(map))
@ -815,20 +816,17 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear)
PyErr_Fetch(&error_type, &error_value, &error_traceback); PyErr_Fetch(&error_type, &error_value, &error_traceback);
fast = f->f_localsplus; fast = f->f_localsplus;
j = PyTuple_GET_SIZE(map); j = PyTuple_GET_SIZE(map);
if (j > f->f_nlocals) if (j > co->co_nlocals)
j = f->f_nlocals; j = co->co_nlocals;
if (f->f_nlocals) if (co->co_nlocals)
dict_to_map(f->f_code->co_varnames, j, locals, fast, 0, clear); dict_to_map(co->co_varnames, j, locals, fast, 0, clear);
if (f->f_ncells || f->f_nfreevars) { ncells = PyTuple_GET_SIZE(co->co_cellvars);
if (!(PyTuple_Check(f->f_code->co_cellvars) nfreevars = PyTuple_GET_SIZE(co->co_freevars);
&& PyTuple_Check(f->f_code->co_freevars))) if (ncells || nfreevars) {
return; dict_to_map(co->co_cellvars, ncells,
dict_to_map(f->f_code->co_cellvars, locals, fast + co->co_nlocals, 1, clear);
PyTuple_GET_SIZE(f->f_code->co_cellvars), dict_to_map(co->co_freevars, nfreevars,
locals, fast + f->f_nlocals, 1, clear); locals, fast + co->co_nlocals + ncells, 1,
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); clear);
} }
PyErr_Restore(error_type, error_value, error_traceback); PyErr_Restore(error_type, error_value, error_traceback);

View File

@ -654,11 +654,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
#ifdef LLTRACE #ifdef LLTRACE
#define PUSH(v) { (void)(BASIC_PUSH(v), \ #define PUSH(v) { (void)(BASIC_PUSH(v), \
lltrace && prtrace(TOP(), "push")); \ 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 POP() ((void)(lltrace && prtrace(TOP(), "pop")), BASIC_POP())
#define STACKADJ(n) { (void)(BASIC_STACKADJ(n), \ #define STACKADJ(n) { (void)(BASIC_STACKADJ(n), \
lltrace && prtrace(TOP(), "stackadj")); \ 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)) #define EXT_POP(STACK_POINTER) (lltrace && prtrace(*(STACK_POINTER), "ext_pop"), *--(STACK_POINTER))
#else #else
#define PUSH(v) BASIC_PUSH(v) #define PUSH(v) BASIC_PUSH(v)
@ -729,7 +729,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
names = co->co_names; names = co->co_names;
consts = co->co_consts; consts = co->co_consts;
fastlocals = f->f_localsplus; 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); first_instr = (unsigned char*) PyString_AS_STRING(co->co_code);
/* An explanation is in order for the next line. /* An explanation is in order for the next line.
@ -780,7 +780,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
READ_TIMESTAMP(loop0); READ_TIMESTAMP(loop0);
#endif #endif
assert(stack_pointer >= f->f_valuestack); /* else underflow */ 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 /* Do periodic things. Doing this every time through
the loop would add too much overhead, so we do it 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 */ /* Don't stomp existing exception */
if (PyErr_Occurred()) if (PyErr_Occurred())
break; break;
if (oparg < f->f_ncells) { if (oparg < PyTuple_GET_SIZE(co->co_cellvars)) {
v = PyTuple_GetItem(co->co_cellvars, v = PyTuple_GET_ITEM(co->co_cellvars,
oparg); oparg);
format_exc_check_arg( format_exc_check_arg(
PyExc_UnboundLocalError, PyExc_UnboundLocalError,
UNBOUNDLOCAL_ERROR_MSG, UNBOUNDLOCAL_ERROR_MSG,
v); v);
} else { } else {
v = PyTuple_GetItem( v = PyTuple_GET_ITEM(
co->co_freevars, co->co_freevars,
oparg - f->f_ncells); oparg - PyTuple_GET_SIZE(co->co_cellvars));
format_exc_check_arg( format_exc_check_arg(
PyExc_NameError, PyExc_NameError,
UNBOUNDFREE_ERROR_MSG, UNBOUNDFREE_ERROR_MSG,
@ -2610,7 +2610,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
return NULL; return NULL;
fastlocals = f->f_localsplus; fastlocals = f->f_localsplus;
freevars = f->f_localsplus + f->f_nlocals; freevars = f->f_localsplus + co->co_nlocals;
if (co->co_argcount > 0 || if (co->co_argcount > 0 ||
co->co_flags & (CO_VARARGS | CO_VARKEYWORDS)) { 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 /* Allocate and initialize storage for cell vars, and copy free
vars into frame. This isn't too efficient right now. */ 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; int i = 0, j = 0, nargs, found;
char *cellname, *argname; char *cellname, *argname;
PyObject *c; PyObject *c;
@ -2764,7 +2764,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
that are arguments at the beginning of the cellvars that are arguments at the beginning of the cellvars
list so that we can march over it more efficiently? 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( cellname = PyString_AS_STRING(
PyTuple_GET_ITEM(co->co_cellvars, i)); PyTuple_GET_ITEM(co->co_cellvars, i));
found = 0; found = 0;
@ -2775,7 +2775,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
c = PyCell_New(GETLOCAL(j)); c = PyCell_New(GETLOCAL(j));
if (c == NULL) if (c == NULL)
goto fail; goto fail;
GETLOCAL(f->f_nlocals + i) = c; GETLOCAL(co->co_nlocals + i) = c;
found = 1; found = 1;
break; break;
} }
@ -2784,16 +2784,16 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
c = PyCell_New(NULL); c = PyCell_New(NULL);
if (c == NULL) if (c == NULL)
goto fail; 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; 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); PyObject *o = PyTuple_GET_ITEM(closure, i);
Py_INCREF(o); 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: 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()]; PyObject *c = freevars[PEEKARG()];
if (PyCell_GET(c) == v) if (PyCell_GET(c) == v)
PyCell_Set(c, NULL); PyCell_Set(c, NULL);