Applied patch 1337051 by Neal Norwitz, saving 4 ints on frame objects.
This commit is contained in:
parent
69c347655d
commit
cebbefc98d
|
@ -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?
|
||||||
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[] = {
|
||||||
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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue