diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index fa4cbd9ed31c01..fa9dda87acdd6e 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1206,7 +1206,7 @@ extern const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SI #ifdef NEED_OPCODE_METADATA const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = { [NOP] = { true, INSTR_FMT_IX, 0 }, - [RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG }, + [RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, [INSTRUMENTED_RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG }, [LOAD_CLOSURE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG }, [LOAD_FAST_CHECK] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG }, @@ -1466,9 +1466,9 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = { [_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, [_POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, [JUMP_TO_TOP] = { true, INSTR_FMT_IX, HAS_EVAL_BREAK_FLAG }, - [SAVE_IP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, + [SAVE_IP] = { true, INSTR_FMT_IX, 0 }, [SAVE_CURRENT_IP] = { true, INSTR_FMT_IX, 0 }, - [EXIT_TRACE] = { true, INSTR_FMT_IX, 0 }, + [EXIT_TRACE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG }, [INSERT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, }; #endif // NEED_OPCODE_METADATA diff --git a/Python/bytecodes.c b/Python/bytecodes.c index fae1da31875d66..b855430560d367 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -3006,6 +3006,7 @@ dummy_func( tstate->py_recursion_remaining--; LOAD_SP(); LOAD_IP(); + frame->prev_instr = _PyCode_CODE(_PyFrame_GetCode(frame)); #if LLTRACE && TIER_ONE lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); if (lltrace < 0) { @@ -3794,7 +3795,7 @@ dummy_func( } op(SAVE_IP, (--)) { - frame->prev_instr = ip_offset + oparg; + frame->prev_instr = (_Py_CODEUNIT *)(uintptr_t)operand; } op(SAVE_CURRENT_IP, (--)) { @@ -3808,10 +3809,7 @@ dummy_func( } op(EXIT_TRACE, (--)) { - frame->prev_instr--; // Back up to just before destination - _PyFrame_SetStackPointer(frame, stack_pointer); - Py_DECREF(self); - return frame; + goto deoptimize; } op(INSERT, (unused[oparg], top -- top, unused[oparg])) { diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index 4b7c4448e0ea25..cebd8216d1fdde 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -396,7 +396,7 @@ stack_pointer = _PyFrame_GetStackPointer(frame); #if TIER_TWO #define LOAD_IP() \ -do { ip_offset = (_Py_CODEUNIT *)_PyFrame_GetCode(frame)->co_code_adaptive; } while (0) +do {} while (0) #define STORE_SP() \ _PyFrame_SetStackPointer(frame, stack_pointer) diff --git a/Python/executor.c b/Python/executor.c index ac9104223da8ff..c2221c925b7f7d 100644 --- a/Python/executor.c +++ b/Python/executor.c @@ -63,7 +63,6 @@ _PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject CHECK_EVAL_BREAKER(); OBJECT_STAT_INC(optimization_traces_executed); - _Py_CODEUNIT *ip_offset = (_Py_CODEUNIT *)_PyFrame_GetCode(frame)->co_code_adaptive; int pc = 0; int opcode; int oparg; diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 0d5606f5a44efe..5e8e78ed157e4a 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -2289,6 +2289,7 @@ tstate->py_recursion_remaining--; LOAD_SP(); LOAD_IP(); + frame->prev_instr = _PyCode_CODE(_PyFrame_GetCode(frame)); #if LLTRACE && TIER_ONE lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); if (lltrace < 0) { @@ -2865,7 +2866,7 @@ } case SAVE_IP: { - frame->prev_instr = ip_offset + oparg; + frame->prev_instr = (_Py_CODEUNIT *)(uintptr_t)operand; break; } @@ -2881,10 +2882,7 @@ } case EXIT_TRACE: { - frame->prev_instr--; // Back up to just before destination - _PyFrame_SetStackPointer(frame, stack_pointer); - Py_DECREF(self); - return frame; + goto deoptimize; break; } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 34cea84245f591..6e6f42a503ee0a 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -3886,6 +3886,7 @@ tstate->py_recursion_remaining--; LOAD_SP(); LOAD_IP(); + frame->prev_instr = _PyCode_CODE(_PyFrame_GetCode(frame)); #if LLTRACE && TIER_ONE lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); if (lltrace < 0) { @@ -3965,6 +3966,7 @@ tstate->py_recursion_remaining--; LOAD_SP(); LOAD_IP(); + frame->prev_instr = _PyCode_CODE(_PyFrame_GetCode(frame)); #if LLTRACE && TIER_ONE lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); if (lltrace < 0) { diff --git a/Python/optimizer.c b/Python/optimizer.c index 7472f52c50b766..27da702e7e2c43 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -479,7 +479,6 @@ translate_bytecode_to_trace( #define TRACE_STACK_PUSH() \ if (trace_stack_depth >= TRACE_STACK_SIZE) { \ DPRINTF(2, "Trace stack overflow\n"); \ - ADD_TO_TRACE(SAVE_IP, 0, 0); \ goto done; \ } \ trace_stack[trace_stack_depth].code = code; \ @@ -503,7 +502,7 @@ translate_bytecode_to_trace( top: // Jump here after _PUSH_FRAME for (;;) { RESERVE_RAW(2, "epilogue"); // Always need space for SAVE_IP and EXIT_TRACE - ADD_TO_TRACE(SAVE_IP, INSTR_IP(instr, code), 0); + ADD_TO_TRACE(SAVE_IP, 0, (uintptr_t)instr); uint32_t opcode = instr->op.code; uint32_t oparg = instr->op.arg; @@ -554,7 +553,7 @@ translate_bytecode_to_trace( uint32_t uopcode = opcode == POP_JUMP_IF_TRUE ? _POP_JUMP_IF_TRUE : _POP_JUMP_IF_FALSE; ADD_TO_TRACE(uopcode, max_length, 0); - ADD_TO_STUB(max_length, SAVE_IP, INSTR_IP(target_instr, code), 0); + ADD_TO_STUB(max_length, SAVE_IP, 0, (uintptr_t)target_instr); ADD_TO_STUB(max_length + 1, EXIT_TRACE, 0, 0); break; } @@ -614,7 +613,7 @@ translate_bytecode_to_trace( ADD_TO_TRACE(next_op, 0, 0); ADD_TO_STUB(max_length + 0, POP_TOP, 0, 0); - ADD_TO_STUB(max_length + 1, SAVE_IP, INSTR_IP(target_instr, code), 0); + ADD_TO_STUB(max_length + 1, SAVE_IP, 0, (uintptr_t)target_instr); ADD_TO_STUB(max_length + 2, EXIT_TRACE, 0, 0); break; } @@ -668,7 +667,7 @@ translate_bytecode_to_trace( oparg = orig_oparg & 0xF; break; case OPARG_SAVE_IP: // op==SAVE_IP; oparg=next instr - oparg = INSTR_IP(instr + offset, code); + operand = (uintptr_t)(instr + offset); break; default: @@ -707,7 +706,6 @@ translate_bytecode_to_trace( PyUnicode_AsUTF8(new_code->co_qualname), PyUnicode_AsUTF8(new_code->co_filename), new_code->co_firstlineno); - ADD_TO_TRACE(SAVE_IP, 0, 0); goto done; } if (new_code->co_version != func_version) { @@ -715,7 +713,6 @@ translate_bytecode_to_trace( // Perhaps it may happen again, so don't bother tracing. // TODO: Reason about this -- is it better to bail or not? DPRINTF(2, "Bailing because co_version != func_version\n"); - ADD_TO_TRACE(SAVE_IP, 0, 0); goto done; } // Increment IP to the return address @@ -731,7 +728,6 @@ translate_bytecode_to_trace( 2 * INSTR_IP(instr, code)); goto top; } - ADD_TO_TRACE(SAVE_IP, 0, 0); goto done; } } diff --git a/Tools/cases_generator/flags.py b/Tools/cases_generator/flags.py index 5241331bb97cdb..257f0531529b3f 100644 --- a/Tools/cases_generator/flags.py +++ b/Tools/cases_generator/flags.py @@ -42,7 +42,10 @@ def fromInstruction(instr: parsing.Node) -> "InstructionFlags": ) and not has_free, HAS_EVAL_BREAK_FLAG=variable_used(instr, "CHECK_EVAL_BREAKER"), - HAS_DEOPT_FLAG=variable_used(instr, "DEOPT_IF"), + HAS_DEOPT_FLAG=( + variable_used(instr, "DEOPT_IF") + or variable_used(instr, "deoptimize") + ), HAS_ERROR_FLAG=( variable_used(instr, "ERROR_IF") or variable_used(instr, "error")