Mercurial > cpython-lru_cache-weakref
diff Python/ceval.c @ 1262:f820e6917f07 legacy-trunk
Changes to speed up local variables enormously, by avoiding dictionary
lookup (opcode.h, ceval.[ch], compile.c, frameobject.[ch],
pythonrun.c, import.c). The .pyc MAGIC number is changed again.
Added get_menu_text to flmodule.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Tue, 30 Mar 1993 13:18:41 +0000 |
| parents | 1cabc2b6c970 |
| children | 65a1e4e9cd54 |
line wrap: on
line diff
--- a/Python/ceval.c Mon Mar 29 11:39:45 1993 +0000 +++ b/Python/ceval.c Tue Mar 30 13:18:41 1993 +0000 @@ -81,6 +81,7 @@ static object *cmp_outcome PROTO((int, object *, object *)); static int import_from PROTO((object *, object *, object *)); static object *build_class PROTO((object *, object *)); +static void locals_2_fast PROTO((frameobject *, int)); /* Pointer to current frame, used to link new frames to */ @@ -994,19 +995,51 @@ break; case RESERVE_FAST: - if (oparg > 0) { - XDECREF(fastlocals); - x = newlistobject(oparg); - fastlocals = (listobject *) x; + x = GETCONST(oparg); + if (x == None) + break; + if (x == NULL || !is_dictobject(x)) { + fatal("bad RESERVE_FAST"); + err_setstr(SystemError, "bad RESERVE_FAST"); + x = NULL; + break; } + XDECREF(f->f_fastlocals); + XDECREF(f->f_localmap); + INCREF(x); + f->f_localmap = x; + f->f_fastlocals = x = newlistobject( + x->ob_type->tp_as_mapping->mp_length(x)); + fastlocals = (listobject *) x; break; case LOAD_FAST: - /* NYI */ + x = GETLISTITEM(fastlocals, oparg); + if (x == NULL) { + err_setstr(NameError, + "undefined local variable"); + break; + } + INCREF(x); + PUSH(x); break; case STORE_FAST: - /* NYI */ + w = GETLISTITEM(fastlocals, oparg); + XDECREF(w); + w = POP(); + GETLISTITEM(fastlocals, oparg) = w; + break; + + case DELETE_FAST: + x = GETLISTITEM(fastlocals, oparg); + if (x == NULL) { + err_setstr(NameError, + "undefined local variable"); + break; + } + DECREF(x); + GETLISTITEM(fastlocals, oparg) = NULL; break; case BUILD_TUPLE: @@ -1068,6 +1101,7 @@ w = GETNAMEV(oparg); v = TOP(); err = import_from(f->f_locals, v, w); + locals_2_fast(f, 0); break; case JUMP_FORWARD: @@ -1299,8 +1333,6 @@ current_frame = f->f_back; DECREF(f); - - XDECREF(fastlocals); return retval; } @@ -1418,10 +1450,92 @@ object * getlocals() { - if (current_frame == NULL) + /* Merge f->f_fastlocals into f->f_locals, then return the latter */ + frameobject *f; + object *locals, *fast, *map; + int i; + f = current_frame; + if (f == NULL) return NULL; - else - return current_frame->f_locals; + locals = f->f_locals; + fast = f->f_fastlocals; + map = f->f_localmap; + if (locals == NULL || fast == NULL || map == NULL) + return locals; + if (!is_dictobject(locals) || !is_listobject(fast) || + !is_dictobject(map)) + return locals; + i = getdictsize(map); + while (--i >= 0) { + object *key; + object *value; + int j; + key = getdict2key(map, i); + if (key == NULL) + continue; + value = dict2lookup(map, key); + if (value == NULL || !is_intobject(value)) + continue; + j = getintvalue(value); + value = getlistitem(fast, j); + if (value == NULL) { + err_clear(); + if (dict2remove(locals, key) != 0) + err_clear(); + } + else { + if (dict2insert(locals, key, value) != 0) + err_clear(); + } + } + return locals; +} + +static void +locals_2_fast(f, clear) + frameobject *f; + int clear; +{ + /* Merge f->f_locals into f->f_fastlocals */ + object *locals, *fast, *map; + int i; + if (f == NULL) + return; + locals = f->f_locals; + fast = f->f_fastlocals; + map = f->f_localmap; + if (locals == NULL || fast == NULL || map == NULL) + return; + if (!is_dictobject(locals) || !is_listobject(fast) || + !is_dictobject(map)) + return; + i = getdictsize(map); + while (--i >= 0) { + object *key; + object *value; + int j; + key = getdict2key(map, i); + if (key == NULL) + continue; + value = dict2lookup(map, key); + if (value == NULL || !is_intobject(value)) + continue; + j = getintvalue(value); + value = dict2lookup(locals, key); + if (value == NULL) + err_clear(); + else + INCREF(value); + if (value != NULL || clear) + if (setlistitem(fast, j, value) != 0) + err_clear(); + } +} + +void +mergelocals() +{ + locals_2_fast(current_frame, 1); } object *
