]> granicus.if.org Git - python/commitdiff
Applied patch 1337051 by Neal Norwitz, saving 4 ints on frame objects.
authorRichard Jones <richard@commonground.com.au>
Tue, 23 May 2006 18:28:17 +0000 (18:28 +0000)
committerRichard Jones <richard@commonground.com.au>
Tue, 23 May 2006 18:28:17 +0000 (18:28 +0000)
Include/frameobject.h
Misc/NEWS
Objects/frameobject.c
Python/ceval.c

index 7dc14e32040e4dbfba7f7055bfd069e0881a38a0..1e3a01e168388d2180ceb3143b08237841511e49 100644 (file)
@@ -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;
 
index cfb1d15a70407cc4955593e0d910baa79169f146..0cccec9a46f361a6e11228e46c28a446d67ab1d7 100644 (file)
--- 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.
 
index 9a65c8fa2289d1594e1ee1d3b45d007e8471b7c3..08039574a7341b6ff8d1ca3845c9d1d5b29debcc 100644 (file)
@@ -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);
 }
index 43dcdd035a51681ef6d4ccf648241bccaa92a536..b59f718404196fe5cccac2f5a8774d4964a2a2b1 100644 (file)
@@ -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);