From 2032b9c2f7311f966a580f27ff5f9614427393a3 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Thu, 9 Oct 2025 15:14:16 +0100 Subject: [PATCH] add back replaced, move jit tracing env var to --- Include/internal/pycore_interp_structs.h | 1 + Include/internal/pycore_opcode_metadata.h | 2 +- Include/internal/pycore_uop_metadata.h | 4 --- Python/bytecodes.c | 2 +- Python/ceval_macros.h | 23 ++++++-------- Python/executor_cases.c.h | 37 +---------------------- Python/generated_cases.c.h | 2 -- Python/optimizer_cases.c.h | 9 +----- 8 files changed, 15 insertions(+), 65 deletions(-) diff --git a/Include/internal/pycore_interp_structs.h b/Include/internal/pycore_interp_structs.h index 6296f09ab995..af715518c077 100644 --- a/Include/internal/pycore_interp_structs.h +++ b/Include/internal/pycore_interp_structs.h @@ -944,6 +944,7 @@ struct _is { struct callable_cache callable_cache; PyObject *common_consts[NUM_COMMON_CONSTANTS]; // JIT tracing state + bool jit_is_tracing; int jit_tracer_code_max_size; int jit_tracer_code_curr_size; _PyBloomFilter jit_tracer_dependencies; diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index 8f25a9b6336b..b96033eadf90 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1394,7 +1394,7 @@ _PyOpcode_macro_expansion[256] = { [FORMAT_WITH_SPEC] = { .nuops = 1, .uops = { { _FORMAT_WITH_SPEC, OPARG_SIMPLE, 0 } } }, [FOR_ITER] = { .nuops = 1, .uops = { { _FOR_ITER, OPARG_REPLACED, 0 } } }, [FOR_ITER_GEN] = { .nuops = 3, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _FOR_ITER_GEN_FRAME, OPARG_SIMPLE, 1 }, { _PUSH_FRAME, OPARG_SIMPLE, 1 } } }, - [FOR_ITER_LIST] = { .nuops = 3, .uops = { { _ITER_CHECK_LIST, OPARG_SIMPLE, 1 }, { _ITER_JUMP_LIST, OPARG_REPLACED, 1 }, { _ITER_NEXT_LIST, OPARG_SIMPLE, 1 } } }, + [FOR_ITER_LIST] = { .nuops = 3, .uops = { { _ITER_CHECK_LIST, OPARG_SIMPLE, 1 }, { _ITER_JUMP_LIST, OPARG_REPLACED, 1 }, { _ITER_NEXT_LIST, OPARG_REPLACED, 1 } } }, [FOR_ITER_RANGE] = { .nuops = 3, .uops = { { _ITER_CHECK_RANGE, OPARG_SIMPLE, 1 }, { _ITER_JUMP_RANGE, OPARG_REPLACED, 1 }, { _ITER_NEXT_RANGE, OPARG_SIMPLE, 1 } } }, [FOR_ITER_TUPLE] = { .nuops = 3, .uops = { { _ITER_CHECK_TUPLE, OPARG_SIMPLE, 1 }, { _ITER_JUMP_TUPLE, OPARG_REPLACED, 1 }, { _ITER_NEXT_TUPLE, OPARG_SIMPLE, 1 } } }, [GET_AITER] = { .nuops = 1, .uops = { { _GET_AITER, OPARG_SIMPLE, 0 } } }, diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 1b599091f781..79f0b7a68d1f 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -217,7 +217,6 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_FOR_ITER_TIER_TWO] = HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_ITER_CHECK_LIST] = HAS_EXIT_FLAG, [_GUARD_NOT_EXHAUSTED_LIST] = HAS_EXIT_FLAG, - [_ITER_NEXT_LIST] = HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG, [_ITER_NEXT_LIST_TIER_TWO] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG, [_ITER_CHECK_TUPLE] = HAS_EXIT_FLAG, [_GUARD_NOT_EXHAUSTED_TUPLE] = HAS_EXIT_FLAG, @@ -522,7 +521,6 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = { [_ITER_CHECK_LIST] = "_ITER_CHECK_LIST", [_ITER_CHECK_RANGE] = "_ITER_CHECK_RANGE", [_ITER_CHECK_TUPLE] = "_ITER_CHECK_TUPLE", - [_ITER_NEXT_LIST] = "_ITER_NEXT_LIST", [_ITER_NEXT_LIST_TIER_TWO] = "_ITER_NEXT_LIST_TIER_TWO", [_ITER_NEXT_RANGE] = "_ITER_NEXT_RANGE", [_ITER_NEXT_TUPLE] = "_ITER_NEXT_TUPLE", @@ -1073,8 +1071,6 @@ int _PyUop_num_popped(int opcode, int oparg) return 0; case _GUARD_NOT_EXHAUSTED_LIST: return 0; - case _ITER_NEXT_LIST: - return 0; case _ITER_NEXT_LIST_TIER_TWO: return 0; case _ITER_CHECK_TUPLE: diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 770805a98d61..64b56655de29 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -3310,7 +3310,7 @@ dummy_func( #endif } - op(_ITER_NEXT_LIST, (iter, null_or_index -- iter, null_or_index, next)) { + replaced op(_ITER_NEXT_LIST, (iter, null_or_index -- iter, null_or_index, next)) { PyObject *list_o = PyStackRef_AsPyObjectBorrow(iter); assert(PyList_CheckExact(list_o)); #ifdef Py_GIL_DISABLED diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index 313b062bcc22..d76609054c80 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -136,9 +136,15 @@ JUMP_TO_LABEL(label); #if _Py_TAIL_CALL_INTERP || USE_COMPUTED_GOTOS -# define IS_JIT_TRACING() (DISPATCH_TABLE_VAR == TRACING_DISPATCH_TABLE) -# define ENTER_TRACING() DISPATCH_TABLE_VAR = TRACING_DISPATCH_TABLE; -# define LEAVE_TRACING() DISPATCH_TABLE_VAR = DISPATCH_TABLE; +# define IS_JIT_TRACING() (tstate->interp->jit_is_tracing) +# define ENTER_TRACING() \ + assert(!IS_JIT_TRACING()); \ + DISPATCH_TABLE_VAR = TRACING_DISPATCH_TABLE; \ + tstate->interp->jit_is_tracing = true; +# define LEAVE_TRACING() \ + assert(IS_JIT_TRACING()); \ + DISPATCH_TABLE_VAR = DISPATCH_TABLE; \ + tstate->interp->jit_is_tracing = false; # define BAIL_TRACING_NO_DISPATCH() \ LEAVE_TRACING(); \ _PyFrame_SetStackPointer(frame, stack_pointer); \ @@ -148,14 +154,6 @@ if (_err < 0) { \ JUMP_TO_LABEL(error); \ } -# define BAIL_TRACING() \ - BAIL_TRACING_NO_DISPATCH() \ - DISPATCH(); -# define RECORD_TRACE() do { \ - if (add_to_code_trace(tstate, frame, old_code, old_func, this_instr, next_instr, opcode, oparg, _jump_taken)) { \ - BAIL_TRACING(); \ - } \ - } while (0); # define RECORD_TRACE_NO_DISPATCH() do { \ if (add_to_code_trace(tstate, frame, old_code, old_func, this_instr, next_instr, opcode, oparg, _jump_taken)) { \ BAIL_TRACING_NO_DISPATCH(); \ @@ -224,7 +222,7 @@ do { \ #define TRACING_DISPATCH() \ { \ assert(frame->stackpointer == NULL); \ - RECORD_TRACE(); \ + RECORD_TRACE_NO_DISPATCH(); \ NEXTOPARG(); \ PRE_DISPATCH_GOTO(); \ DISPATCH_GOTO(); \ @@ -414,7 +412,6 @@ _PyFrame_SetStackPointer(frame, stack_pointer) #define TIER1_TO_TIER2(EXECUTOR) \ do { \ - LEAVE_TRACING(); \ OPT_STAT_INC(traces_executed); \ next_instr = _Py_jit_entry((EXECUTOR), frame, stack_pointer, tstate); \ frame = tstate->current_frame; \ diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index b25fb61bd520..e9b607639f33 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -4463,42 +4463,7 @@ break; } - case _ITER_NEXT_LIST: { - _PyStackRef null_or_index; - _PyStackRef iter; - _PyStackRef next; - oparg = CURRENT_OPARG(); - null_or_index = stack_pointer[-1]; - iter = stack_pointer[-2]; - PyObject *list_o = PyStackRef_AsPyObjectBorrow(iter); - assert(PyList_CheckExact(list_o)); - #ifdef Py_GIL_DISABLED - assert(_Py_IsOwnedByCurrentThread(list_o) || - _PyObject_GC_IS_SHARED(list_o)); - STAT_INC(FOR_ITER, hit); - _PyFrame_SetStackPointer(frame, stack_pointer); - int result = _PyList_GetItemRefNoLock((PyListObject *)list_o, PyStackRef_UntagInt(null_or_index), &next); - stack_pointer = _PyFrame_GetStackPointer(frame); - if (result < 0) { - UOP_STAT_INC(uopcode, miss); - JUMP_TO_JUMP_TARGET(); - } - if (result == 0) { - null_or_index = PyStackRef_TagInt(-1); - stack_pointer[-1] = null_or_index; - TIER2_JUMPBY(oparg + 1); - break; - } - #else - next = PyStackRef_FromPyObjectNew(PyList_GET_ITEM(list_o, PyStackRef_UntagInt(null_or_index))); - #endif - null_or_index = PyStackRef_IncrementTaggedIntNoOverflow(null_or_index); - stack_pointer[-1] = null_or_index; - stack_pointer[0] = next; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); - break; - } + /* _ITER_NEXT_LIST is not a viable micro-op for tier 2 because it is replaced */ case _ITER_NEXT_LIST_TIER_TWO: { _PyStackRef null_or_index; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 9e855fb5afd5..e190f651fa4c 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -27372,7 +27372,6 @@ JUMP_TO_LABEL(error); LABEL(error) { - assert(!IS_JIT_TRACING()); #ifdef NDEBUG if (!_PyErr_Occurred(tstate)) { _PyFrame_SetStackPointer(frame, stack_pointer); @@ -27402,7 +27401,6 @@ JUMP_TO_LABEL(error); LABEL(exception_unwind) { - assert(!IS_JIT_TRACING()); int offset = INSTR_OFFSET()-1; int level, handler, lasti; int handled = get_exception_handler(_PyFrame_GetCode(frame), offset, &level, &handler, &lasti); diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 74091012568c..ef76374d244f 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -2223,14 +2223,7 @@ break; } - case _ITER_NEXT_LIST: { - JitOptRef next; - next = sym_new_not_null(ctx); - stack_pointer[0] = next; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); - break; - } + /* _ITER_NEXT_LIST is not a viable micro-op for tier 2 */ case _ITER_NEXT_LIST_TIER_TWO: { JitOptRef next; -- 2.47.3