diff options
author | Mark Shannon <mark@hotpy.org> | 2024-01-15 11:41:06 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-15 11:41:06 (GMT) |
commit | ac10947ba79a15bfdaa3ca92c6864214648ab364 (patch) | |
tree | 1853aea09cbd74fdaf1d4d3b999ba250f43ff6ae /Python | |
parent | 2010d45327128594aed332befa687c8aead010bc (diff) | |
download | cpython-ac10947ba79a15bfdaa3ca92c6864214648ab364.zip cpython-ac10947ba79a15bfdaa3ca92c6864214648ab364.tar.gz cpython-ac10947ba79a15bfdaa3ca92c6864214648ab364.tar.bz2 |
GH-112354: `_GUARD_IS_TRUE_POP` side-exits to target the next instruction, not themselves. (GH-114078)
Diffstat (limited to 'Python')
-rw-r--r-- | Python/bytecodes.c | 19 | ||||
-rw-r--r-- | Python/executor_cases.c.h | 15 | ||||
-rw-r--r-- | Python/optimizer.c | 7 |
3 files changed, 27 insertions, 14 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 6df99d6..c48f0a1 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -805,7 +805,8 @@ dummy_func( #if TIER_ONE assert(frame != &entry_frame); #endif - STORE_SP(); + SYNC_SP(); + _PyFrame_SetStackPointer(frame, stack_pointer); assert(EMPTY()); _Py_LeaveRecursiveCallPy(tstate); // GH-99729: We need to unlink the frame *before* clearing it: @@ -3154,7 +3155,8 @@ dummy_func( // Write it out explicitly because it's subtly different. // Eventually this should be the only occurrence of this code. assert(tstate->interp->eval_frame == NULL); - STORE_SP(); + SYNC_SP(); + _PyFrame_SetStackPointer(frame, stack_pointer); new_frame->previous = frame; CALL_STAT_INC(inlined_py_calls); frame = tstate->current_frame = new_frame; @@ -4013,20 +4015,27 @@ dummy_func( ///////// Tier-2 only opcodes ///////// op (_GUARD_IS_TRUE_POP, (flag -- )) { - DEOPT_IF(Py_IsFalse(flag)); + SYNC_SP(); + DEOPT_IF(!Py_IsTrue(flag)); assert(Py_IsTrue(flag)); } op (_GUARD_IS_FALSE_POP, (flag -- )) { - DEOPT_IF(Py_IsTrue(flag)); + SYNC_SP(); + DEOPT_IF(!Py_IsFalse(flag)); assert(Py_IsFalse(flag)); } op (_GUARD_IS_NONE_POP, (val -- )) { - DEOPT_IF(!Py_IsNone(val)); + SYNC_SP(); + if (!Py_IsNone(val)) { + Py_DECREF(val); + DEOPT_IF(1); + } } op (_GUARD_IS_NOT_NONE_POP, (val -- )) { + SYNC_SP(); DEOPT_IF(Py_IsNone(val)); Py_DECREF(val); } diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 6060beb..2b4399b 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -3318,35 +3318,38 @@ case _GUARD_IS_TRUE_POP: { PyObject *flag; flag = stack_pointer[-1]; - if (Py_IsFalse(flag)) goto deoptimize; - assert(Py_IsTrue(flag)); stack_pointer += -1; + if (!Py_IsTrue(flag)) goto deoptimize; + assert(Py_IsTrue(flag)); break; } case _GUARD_IS_FALSE_POP: { PyObject *flag; flag = stack_pointer[-1]; - if (Py_IsTrue(flag)) goto deoptimize; - assert(Py_IsFalse(flag)); stack_pointer += -1; + if (!Py_IsFalse(flag)) goto deoptimize; + assert(Py_IsFalse(flag)); break; } case _GUARD_IS_NONE_POP: { PyObject *val; val = stack_pointer[-1]; - if (!Py_IsNone(val)) goto deoptimize; stack_pointer += -1; + if (!Py_IsNone(val)) { + Py_DECREF(val); + if (1) goto deoptimize; + } break; } case _GUARD_IS_NOT_NONE_POP: { PyObject *val; val = stack_pointer[-1]; + stack_pointer += -1; if (Py_IsNone(val)) goto deoptimize; Py_DECREF(val); - stack_pointer += -1; break; } diff --git a/Python/optimizer.c b/Python/optimizer.c index 236ae26..1551a5e 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -481,18 +481,19 @@ top: // Jump here after _PUSH_FRAME or likely branches goto done; } uint32_t uopcode = BRANCH_TO_GUARD[opcode - POP_JUMP_IF_FALSE][jump_likely]; - _Py_CODEUNIT *next_instr = instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]]; DPRINTF(2, "%s(%d): counter=%x, bitcount=%d, likely=%d, confidence=%d, uopcode=%s\n", _PyOpcode_OpName[opcode], oparg, counter, bitcount, jump_likely, confidence, _PyUOpName(uopcode)); - ADD_TO_TRACE(uopcode, max_length, 0, target); + _Py_CODEUNIT *next_instr = instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]]; + _Py_CODEUNIT *target_instr = next_instr + oparg; if (jump_likely) { - _Py_CODEUNIT *target_instr = next_instr + oparg; DPRINTF(2, "Jump likely (%x = %d bits), continue at byte offset %d\n", instr[1].cache, bitcount, 2 * INSTR_IP(target_instr, code)); instr = target_instr; + ADD_TO_TRACE(uopcode, max_length, 0, INSTR_IP(next_instr, code)); goto top; } + ADD_TO_TRACE(uopcode, max_length, 0, INSTR_IP(target_instr, code)); break; } |