]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Normalize jumps in compiler. All forward jumps to use JUMP_FORWARD. (GH-28755)
authorMark Shannon <mark@hotpy.org>
Wed, 6 Oct 2021 12:05:45 +0000 (13:05 +0100)
committerGitHub <noreply@github.com>
Wed, 6 Oct 2021 12:05:45 +0000 (13:05 +0100)
Lib/test/test_dis.py
Python/ceval.c
Python/compile.c

index 0899db66d82410ee98b9a4d7b71c422e4fb8c346..4755e3f3a172476e1743fee0cb740963bc87eb62 100644 (file)
@@ -1046,7 +1046,7 @@ expected_opinfo_jumpy = [
   Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=34, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=21, argval=42, argrepr='to 42', offset=36, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=38, starts_line=8, is_jump_target=False, positions=None),
-  Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=26, argval=52, argrepr='to 52', offset=40, starts_line=None, is_jump_target=False, positions=None),
+  Instruction(opname='JUMP_FORWARD', opcode=110, arg=5, argval=52, argrepr='to 52', offset=40, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=4, argval=8, argrepr='to 8', offset=42, starts_line=7, is_jump_target=True, positions=None),
   Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=44, starts_line=10, is_jump_target=True, positions=None),
   Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=46, starts_line=None, is_jump_target=False, positions=None),
@@ -1071,7 +1071,7 @@ expected_opinfo_jumpy = [
   Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=84, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=86, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=46, argval=92, argrepr='to 92', offset=88, starts_line=None, is_jump_target=False, positions=None),
-  Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=52, argval=104, argrepr='to 104', offset=90, starts_line=17, is_jump_target=False, positions=None),
+  Instruction(opname='JUMP_FORWARD', opcode=110, arg=6, argval=104, argrepr='to 104', offset=90, starts_line=17, is_jump_target=False, positions=None),
   Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=92, starts_line=11, is_jump_target=True, positions=None),
   Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=28, argval=56, argrepr='to 56', offset=94, starts_line=None, is_jump_target=False, positions=None),
   Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=96, starts_line=19, is_jump_target=True, positions=None),
index 2dbc291897c033d2f7e5287879759b6192806527..a3a173dfb701337f2a600dc343645f4ce9d92c12 100644 (file)
@@ -4051,19 +4051,18 @@ check_eval_breaker:
 
         TARGET(JUMP_ABSOLUTE) {
             PREDICTED(JUMP_ABSOLUTE);
-            if (oparg < INSTR_OFFSET()) {
-                /* Increment the warmup counter and quicken if warm enough
-                * _Py_Quicken is idempotent so we don't worry about overflow */
-                if (!PyCodeObject_IsWarmedUp(co)) {
-                    PyCodeObject_IncrementWarmup(co);
-                    if (PyCodeObject_IsWarmedUp(co)) {
-                        if (_Py_Quicken(co)) {
-                            goto error;
-                        }
-                        int nexti = INSTR_OFFSET();
-                        first_instr = co->co_firstinstr;
-                        next_instr = first_instr + nexti;
+            assert(oparg < INSTR_OFFSET());
+            /* Increment the warmup counter and quicken if warm enough
+            * _Py_Quicken is idempotent so we don't worry about overflow */
+            if (!PyCodeObject_IsWarmedUp(co)) {
+                PyCodeObject_IncrementWarmup(co);
+                if (PyCodeObject_IsWarmedUp(co)) {
+                    if (_Py_Quicken(co)) {
+                        goto error;
                     }
+                    int nexti = INSTR_OFFSET();
+                    first_instr = co->co_firstinstr;
+                    next_instr = first_instr + nexti;
                 }
             }
             JUMPTO(oparg);
@@ -4072,6 +4071,7 @@ check_eval_breaker:
         }
 
         TARGET(JUMP_ABSOLUTE_QUICK) {
+            assert(oparg < INSTR_OFFSET());
             JUMPTO(oparg);
             CHECK_EVAL_BREAKER();
             DISPATCH();
index 694da29b771d07b65e0ded8686d781ca8d9a4dcd..2d82d6a1e5a91818b02d990ae8904ac14a335c77 100644 (file)
@@ -7220,6 +7220,26 @@ assemble_emit(struct assembler *a, struct instr *i)
     return 1;
 }
 
+static void
+normalize_jumps(struct assembler *a)
+{
+    for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) {
+        b->b_visited = 0;
+    }
+    for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) {
+        b->b_visited = 1;
+        if (b->b_iused == 0) {
+            continue;
+        }
+        struct instr *last = &b->b_instr[b->b_iused-1];
+        if (last->i_opcode == JUMP_ABSOLUTE &&
+            last->i_target->b_visited == 0
+        ) {
+            last->i_opcode = JUMP_FORWARD;
+        }
+    }
+}
+
 static void
 assemble_jump_offsets(struct assembler *a, struct compiler *c)
 {
@@ -7897,6 +7917,9 @@ assemble(struct compiler *c, int addNone)
         clean_basic_block(b);
     }
 
+    /* Order of basic blocks must have been determined by now */
+    normalize_jumps(&a);
+
     /* Can't modify the bytecode after computing jump offsets. */
     assemble_jump_offsets(&a, c);