]> granicus.if.org Git - python/commitdiff
Changes that appear to give another 12% speedup.
authorGuido van Rossum <guido@python.org>
Mon, 20 Jan 1997 04:20:52 +0000 (04:20 +0000)
committerGuido van Rossum <guido@python.org>
Mon, 20 Jan 1997 04:20:52 +0000 (04:20 +0000)
Rather than allocating a list object for the fast locals and another
(extensible one) for the value stack and allocating the block stack
dynamically, allocate the block stack with a fixed size (CO_MAXBLOCKS
from compile.h), and stick the locals and value stack at the end of
the object (this is now possible since the stack size is known
beforehand).  Get rid of the owner field and the nvalues argument --
it is available in the code object, like nlocals.

This requires small changes in ceval.c only.

Objects/frameobject.c

index 546f1e8d722bc104e72a563d3a4e0afd6da757b1..281445558b2e7e18a50d68bb4f794fa4a465a4a9 100644 (file)
@@ -47,10 +47,6 @@ static struct memberlist frame_memberlist[] = {
        {"f_builtins",  T_OBJECT,       OFF(f_builtins),RO},
        {"f_globals",   T_OBJECT,       OFF(f_globals), RO},
        {"f_locals",    T_OBJECT,       OFF(f_locals),  RO},
-       {"f_owner",     T_OBJECT,       OFF(f_owner),   RO},
-#if 0
-       {"f_fastlocals",T_OBJECT,       OFF(f_fastlocals),RO}, /* XXX Unsafe */
-#endif
        {"f_lasti",     T_INT,          OFF(f_lasti),   RO},
        {"f_lineno",    T_INT,          OFF(f_lineno),  RO},
        {"f_restricted",T_INT,          OFF(f_restricted),RO},
@@ -84,10 +80,8 @@ frame_setattr(f, name, value)
    is on the free list, only the following members have a meaning:
        ob_type         == &Frametype
        f_back          next item on free list, or NULL
-       f_nvalues       size of f_valuestack
-       f_valuestack    array of (f_nvalues+1) object pointers, or NULL
-       f_nblocks       size of f_blockstack
-       f_blockstack    array of (f_nblocks+1) blocks, or NULL
+       f_nlocals       number of locals
+       f_stacksize     size of value stack
    Note that the value and block stacks are preserved -- this can save
    another malloc() call or two (and two free() calls as well!).
    Also note that, unlike for integers, each frame object is a
@@ -109,8 +103,6 @@ frame_dealloc(f)
        XDECREF(f->f_builtins);
        XDECREF(f->f_globals);
        XDECREF(f->f_locals);
-       XDECREF(f->f_owner);
-       XDECREF(f->f_fastlocals);
        XDECREF(f->f_trace);
        f->f_back = free_list;
        free_list = f;
@@ -134,28 +126,26 @@ typeobject Frametype = {
 };
 
 frameobject *
-newframeobject(back, code, globals, locals, owner, nvalues, nblocks)
+newframeobject(back, code, globals, locals)
        frameobject *back;
        codeobject *code;
        object *globals;
        object *locals;
-       object *owner;
-       int nvalues;
-       int nblocks;
 {
        static object *builtin_object;
        frameobject *f;
        object *builtins;
+       int extras = code->co_stacksize + code->co_nlocals;
+
        if (builtin_object == NULL) {
                builtin_object = PyString_InternFromString("__builtins__");
                if (builtin_object == NULL)
                        return NULL;
        }
        if ((back != NULL && !is_frameobject(back)) ||
-               code == NULL || !is_codeobject(code) ||
-               globals == NULL || !is_dictobject(globals) ||
-               (locals != NULL && !is_dictobject(locals)) ||
-               nvalues < 0 || nblocks < 0) {
+           code == NULL || !is_codeobject(code) ||
+           globals == NULL || !is_dictobject(globals) ||
+           (locals != NULL && !is_dictobject(locals))) {
                err_badcall();
                return NULL;
        }
@@ -167,16 +157,21 @@ newframeobject(back, code, globals, locals, owner, nvalues, nblocks)
                return NULL;
        }
        if (free_list == NULL) {
-               f = NEWOBJ(frameobject, &Frametype);
+               f = (frameobject *)
+                       malloc(sizeof(frameobject) + extras*sizeof(object *));
                if (f == NULL)
-                       return NULL;
-               f->f_nvalues = f->f_nblocks = 0;
-               f->f_valuestack = NULL;
-               f->f_blockstack = NULL;
+                       return (PyFrameObject *)err_nomem();
+               f->ob_type = &Frametype;
+               NEWREF(f);
        }
        else {
                f = free_list;
                free_list = free_list->f_back;
+               if (f->f_nlocals + f->f_stacksize < extras) {
+                       f = realloc(f, sizeof(frameobject) + extras*sizeof(object *));
+                       if (f == NULL)
+                               return (PyFrameObject *)err_nomem();
+               }
                f->ob_type = &Frametype;
                NEWREF(f);
        }
@@ -205,57 +200,22 @@ newframeobject(back, code, globals, locals, owner, nvalues, nblocks)
                INCREF(locals);
        }
        f->f_locals = locals;
-       XINCREF(owner);
-       f->f_owner = owner;
-       f->f_fastlocals = NULL;
-       if (code->co_nlocals > 0) {
-               f->f_fastlocals = newlistobject(code->co_nlocals);
-               if (f->f_fastlocals == NULL) {
-                       DECREF(f);
-                       return NULL;
-               }
-       }
-       if (nvalues > f->f_nvalues || f->f_valuestack == NULL) {
-               XDEL(f->f_valuestack);
-               f->f_valuestack = NEW(object *, nvalues+1);
-               f->f_nvalues = nvalues;
-       }
-       if (nblocks > f->f_nblocks || f->f_blockstack == NULL) {
-               XDEL(f->f_blockstack);
-               f->f_blockstack = NEW(block, nblocks+1);
-               f->f_nblocks = nblocks;
-       }
-       f->f_iblock = 0;
+       f->f_trace = NULL;
+
        f->f_lasti = 0;
        f->f_lineno = -1;
        f->f_restricted = (builtins != getbuiltindict());
-       f->f_trace = NULL;
-       if (f->f_valuestack == NULL || f->f_blockstack == NULL) {
-               err_nomem();
-               DECREF(f);
-               return NULL;
-       }
-       return f;
-}
+       f->f_iblock = 0;
+       f->f_nlocals = code->co_nlocals;
+       f->f_stacksize = code->co_stacksize;
 
-#if 0
-object **
-extend_stack(f, level, incr)
-       frameobject *f;
-       int level;
-       int incr;
-{
-       f->f_nvalues = level + incr + 10;
-       f->f_valuestack =
-               (object **) realloc((ANY *)f->f_valuestack,
-                                   sizeof(object *) * (f->f_nvalues + 1));
-       if (f->f_valuestack == NULL) {
-               err_nomem();
-               return NULL;
-       }
-       return f->f_valuestack + level;
+       while (--extras >= 0)
+               f->f_localsplus[extras] = NULL;
+
+       f->f_valuestack = f->f_localsplus + f->f_nlocals;
+
+       return f;
 }
-#endif
 
 /* Block management */
 
@@ -267,7 +227,7 @@ setup_block(f, type, handler, level)
        int level;
 {
        block *b;
-       if (f->f_iblock >= f->f_nblocks)
+       if (f->f_iblock >= CO_MAXBLOCKS)
                fatal("XXX block stack overflow");
        b = &f->f_blockstack[f->f_iblock++];
        b->b_type = type;
@@ -292,8 +252,9 @@ void
 fast_2_locals(f)
        frameobject *f;
 {
-       /* Merge f->f_fastlocals into f->f_locals */
-       object *locals, *fast, *map;
+       /* Merge fast locals into f->f_locals */
+       object *locals, *map;
+       object **fast;
        object *error_type, *error_value, *error_traceback;
        int j;
        if (f == NULL)
@@ -306,17 +267,19 @@ fast_2_locals(f)
                        return;
                }
        }
-       fast = f->f_fastlocals;
-       if (fast == NULL || f->f_code->co_nlocals == 0)
+       if (f->f_nlocals == 0)
                return;
        map = f->f_code->co_varnames;
-       if (!is_dictobject(locals) || !is_listobject(fast) ||
-           !is_tupleobject(map))
+       if (!is_dictobject(locals) || !is_tupleobject(map))
                return;
        err_fetch(&error_type, &error_value, &error_traceback);
-       for (j = gettuplesize(map); --j >= 0; ) {
+       fast = f->f_localsplus;
+       j = gettuplesize(map);
+       if (j > f->f_nlocals)
+               j = f->f_nlocals;
+       for (; --j >= 0; ) {
                object *key = gettupleitem(map, j);
-               object *value = getlistitem(fast, j);
+               object *value = fast[j];
                if (value == NULL) {
                        err_clear();
                        if (dict2remove(locals, key) != 0)
@@ -335,31 +298,36 @@ locals_2_fast(f, clear)
        frameobject *f;
        int clear;
 {
-       /* Merge f->f_locals into f->f_fastlocals */
-       object *locals, *fast, *map;
+       /* Merge f->f_locals into fast locals */
+       object *locals, *map;
+       object **fast;
        object *error_type, *error_value, *error_traceback;
        int j;
        if (f == NULL)
                return;
        locals = f->f_locals;
-       fast = f->f_fastlocals;
        map = f->f_code->co_varnames;
        if (locals == NULL || fast == NULL || f->f_code->co_nlocals == 0)
                return;
-       if (!is_dictobject(locals) || !is_listobject(fast) ||
-           !is_tupleobject(map))
+       if (!is_dictobject(locals) || !is_tupleobject(map))
                return;
        err_fetch(&error_type, &error_value, &error_traceback);
-       for (j = gettuplesize(map); --j >= 0; ) {
+       fast = f->f_localsplus;
+       j = gettuplesize(map);
+       if (j > f->f_nlocals)
+               j = f->f_nlocals;
+       for (; --j >= 0; ) {
                object *key = gettupleitem(map, j);
                object *value = dict2lookup(locals, key);
                if (value == NULL)
                        err_clear();
                else
                        INCREF(value);
-               if (value != NULL || clear)
-                       if (setlistitem(fast, j, value) != 0)
-                               err_clear();
+               if (value != NULL || clear) {
+                       XDECREF(fast[j]);
+                       XINCREF(value);
+                       fast[j] = value;
+               }
        }
        err_restore(error_type, error_value, error_traceback);
 }