summaryrefslogtreecommitdiffstats
path: root/Python/compile.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2021-06-04 00:03:54 (GMT)
committerGitHub <noreply@github.com>2021-06-04 00:03:54 (GMT)
commitb2bf2bc1ece673d387341e06c8d3c2bc6e259747 (patch)
tree29217a2927ed27e71e6324876f279946219a25a9 /Python/compile.c
parent35002aa8f62dda1f79035e9904abdf476683e9be (diff)
downloadcpython-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.c21
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;