Kaydet (Commit) cebbefc9 authored tarafından Richard Jones's avatar Richard Jones

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

üst 69c34765
...@@ -36,10 +36,6 @@ typedef struct _frame { ...@@ -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;
......
...@@ -12,6 +12,11 @@ What's New in Python 2.5 alpha 3? ...@@ -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.
......
...@@ -377,7 +377,6 @@ static PyGetSetDef frame_getsetlist[] = { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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,21 +816,18 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear) ...@@ -815,21 +816,18 @@ 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, clear);
PyTuple_GET_SIZE(f->f_code->co_freevars),
locals, fast + f->f_nlocals + f->f_ncells, 1,
clear);
} }
PyErr_Restore(error_type, error_value, error_traceback); PyErr_Restore(error_type, error_value, error_traceback);
} }
......
...@@ -654,11 +654,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment