diff options
author | Mark Shannon <mark@hotpy.org> | 2021-06-04 00:03:54 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-04 00:03:54 (GMT) |
commit | b2bf2bc1ece673d387341e06c8d3c2bc6e259747 (patch) | |
tree | 29217a2927ed27e71e6324876f279946219a25a9 /Python/compile.c | |
parent | 35002aa8f62dda1f79035e9904abdf476683e9be (diff) | |
download | cpython-b2bf2bc1ece673d387341e06c8d3c2bc6e259747.zip cpython-b2bf2bc1ece673d387341e06c8d3c2bc6e259747.tar.gz cpython-b2bf2bc1ece673d387341e06c8d3c2bc6e259747.tar.bz2 |
bpo-43693: Compute deref offsets in compiler (gh-25152)
Merges locals and cells into a single array.
Saves a pointer in the interpreter and means that we don't need the LOAD_CLOSURE opcode any more
https://bugs.python.org/issue43693
Diffstat (limited to 'Python/compile.c')
-rw-r--r-- | Python/compile.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/Python/compile.c b/Python/compile.c index b0c9f3c..1104250 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -7435,6 +7435,24 @@ guarantee_lineno_for_exits(struct assembler *a, int firstlineno) { } } +static void +offset_derefs(basicblock *entryblock, int nlocals) +{ + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (int i = 0; i < b->b_iused; i++) { + struct instr *inst = &b->b_instr[i]; + switch(inst->i_opcode) { + case LOAD_CLOSURE: + case LOAD_DEREF: + case STORE_DEREF: + case DELETE_DEREF: + case LOAD_CLASSDEREF: + inst->i_oparg += nlocals; + } + } + } +} + static PyCodeObject * assemble(struct compiler *c, int addNone) { @@ -7490,6 +7508,9 @@ assemble(struct compiler *c, int addNone) a.a_entry = entryblock; a.a_nblocks = nblocks; + assert(PyDict_GET_SIZE(c->u->u_varnames) < INT_MAX); + offset_derefs(entryblock, (int)PyDict_GET_SIZE(c->u->u_varnames)); + consts = consts_dict_keys_inorder(c->u->u_consts); if (consts == NULL) { goto error; |