]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-106581: Honor 'always_exits' in write_components() (#109338)
authorGuido van Rossum <guido@python.org>
Tue, 12 Sep 2023 17:58:40 +0000 (10:58 -0700)
committerGitHub <noreply@github.com>
Tue, 12 Sep 2023 17:58:40 +0000 (17:58 +0000)
I must have overlooked this when refactoring the code generator.
The Tier 1 interpreter contained a few silly things like
```
            goto resume_frame;
            STACK_SHRINK(1);
```
(and other variations, some where the unconditional `goto` was hidden in a macro).

Python/generated_cases.c.h
Tools/cases_generator/stacking.py

index b86e35f84fda097e01151dee1a04e11f0a193bd2..9742c95c407554900c43790aff84a22cb6c72a2d 100644 (file)
             SKIP_OVER(INLINE_CACHE_ENTRIES_BINARY_SUBSCR);
             frame->return_offset = 0;
             DISPATCH_INLINED(new_frame);
-            STACK_SHRINK(1);
         }
 
         TARGET(LIST_APPEND) {
                 break;
             }
             if (true) { STACK_SHRINK(oparg); goto error; }
-            STACK_SHRINK(oparg);
         }
 
         TARGET(INTERPRETER_EXIT) {
             assert(!_PyErr_Occurred(tstate));
             tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS;
             return retval;
-            STACK_SHRINK(1);
         }
 
         TARGET(RETURN_VALUE) {
             frame->prev_instr += frame->return_offset;
             _PyFrame_StackPush(frame, retval);
             goto resume_frame;
-            STACK_SHRINK(1);
         }
 
         TARGET(RETURN_CONST) {
             _PyErr_SetRaisedException(tstate, exc);
             monitor_reraise(tstate, frame, next_instr-1);
             goto exception_unwind;
-            STACK_SHRINK(1);
         }
 
         TARGET(END_ASYNC_FOR) {
             // don't want to specialize instrumented instructions
             INCREMENT_ADAPTIVE_COUNTER(cache->counter);
             GO_TO_INSTRUCTION(LOAD_SUPER_ATTR);
-            STACK_SHRINK(2);
-            STACK_GROW(((oparg & 1) ? 1 : 0));
         }
 
         TARGET(LOAD_SUPER_ATTR) {
                    next_instr[oparg].op.code == INSTRUMENTED_END_FOR);
             frame->return_offset = oparg;
             DISPATCH_INLINED(gen_frame);
-            STACK_GROW(1);
         }
 
         TARGET(BEFORE_ASYNC_WITH) {
             SKIP_OVER(INLINE_CACHE_ENTRIES_CALL);
             frame->return_offset = 0;
             DISPATCH_INLINED(new_frame);
-            STACK_SHRINK(oparg);
-            STACK_SHRINK(1);
         }
 
         TARGET(CALL_NO_KW_TYPE_1) {
              * as it will be checked after start_frame */
             tstate->py_recursion_remaining--;
             goto start_frame;
-            STACK_SHRINK(oparg);
-            STACK_SHRINK(1);
         }
 
         TARGET(EXIT_INIT_CHECK) {
             SKIP_OVER(INLINE_CACHE_ENTRIES_CALL + 1);
             assert(next_instr[-1].op.code == POP_TOP);
             DISPATCH();
-            STACK_SHRINK(oparg);
-            STACK_SHRINK(1);
         }
 
         TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_O) {
index 026f0392eff1d7e2da79dd0afba9df08fdfeef84..9cf9ad1a6c9e6d552cd1104b2617e409f03bcf0c 100644 (file)
@@ -457,7 +457,7 @@ def write_components(
             with out.block(""):
                 mgr.instr.write_body(out, -4, mgr.active_caches, tier)
 
-        if mgr is managers[-1] and not next_instr_is_set:
+        if mgr is managers[-1] and not next_instr_is_set and not mgr.instr.always_exits:
             # Adjust the stack to its final depth, *then* write the
             # pokes for all preceding uops.
             # Note that for array output effects we may still write