8484# define Py_PRESERVE_NONE_CC __attribute__((preserve_none))
8585 Py_PRESERVE_NONE_CC typedef PyObject * (* py_tail_call_funcptr )(TAIL_CALL_PARAMS );
8686
87- # define DISPATCH_TABLE_VAR instruction_funcptr_table
88- # define DISPATCH_TABLE instruction_funcptr_handler_table
89- # define TRACING_DISPATCH_TABLE instruction_funcptr_tracing_table
90- # define TARGET (op ) Py_PRESERVE_NONE_CC PyObject *_TAIL_CALL_##op(TAIL_CALL_PARAMS)
91- # define TRACING_TARGET (op ) Py_PRESERVE_NONE_CC PyObject *_TAIL_CALL_TRACING_##op(TAIL_CALL_PARAMS)
92-
9387# define DISPATCH_GOTO () \
9488 do { \
9589 Py_MUSTTAIL return (((py_tail_call_funcptr *)instruction_funcptr_table)[opcode])(TAIL_CALL_ARGS); \
111105# endif
112106# define LABEL (name ) TARGET(name)
113107#elif USE_COMPUTED_GOTOS
114- # define DISPATCH_TABLE_VAR opcode_targets
115- # define DISPATCH_TABLE opcode_targets_table
116108# define TRACING_DISPATCH_TABLE opcode_tracing_targets_table
117109# define TARGET (op ) TARGET_##op:
118110# define TRACING_TARGET (op ) TARGET_TRACING_##op:
129121# define LABEL (name ) name:
130122#endif
131123
132- #define TRACING_JUMP_TO_LABEL (label ) \
133- RECORD_DYNAMIC_JUMP_TAKEN() \
134- RECORD_TRACE_NO_DISPATCH() \
135- assert(!IS_JIT_TRACING()); \
136- JUMP_TO_LABEL(label);
137124
138- #if _Py_TAIL_CALL_INTERP || USE_COMPUTED_GOTOS
125+ #if _Py_TIER2
126+ #if _Py_TAIL_CALL_INTERP
127+ # define DISPATCH_TABLE_VAR instruction_funcptr_table
128+ # define DISPATCH_TABLE instruction_funcptr_handler_table
129+ # define TRACING_DISPATCH_TABLE instruction_funcptr_tracing_table
130+ # define ENTER_TRACING () DISPATCH_TABLE_VAR = TRACING_DISPATCH_TABLE
131+ # define TARGET (op ) Py_PRESERVE_NONE_CC PyObject *_TAIL_CALL_##op(TAIL_CALL_PARAMS)
132+ # define TRACING_TARGET (op ) Py_PRESERVE_NONE_CC PyObject *_TAIL_CALL_TRACING_##op(TAIL_CALL_PARAMS)
133+
139134# define IS_JIT_TRACING () (DISPATCH_TABLE_VAR == TRACING_DISPATCH_TABLE)
140135// tstate->interp->jit_state.last_specialized_instr != this_instr is required to not get stuck in infinite
141136// specialization loops due to specialization failure.
142137# define IS_JIT_TRACING_MAKING_PROGRESS () (IS_JIT_TRACING() && tstate->interp->jit_state.last_specialized_instr != this_instr)
143- # define ENTER_TRACING () \
144- DISPATCH_TABLE_VAR = TRACING_DISPATCH_TABLE;
145- # define LEAVE_TRACING () \
146- DISPATCH_TABLE_VAR = DISPATCH_TABLE;
138+ # define LEAVE_TRACING () DISPATCH_TABLE_VAR = DISPATCH_TABLE;
147139# define RECORD_TRACE_NO_DISPATCH () do { \
148140 int err = 0; \
149141 _PyFrame_SetStackPointer(frame, stack_pointer); \
158150 stack_pointer = _PyFrame_GetStackPointer (frame ); \
159151 if (err < 0 ) { JUMP_TO_LABEL (error ); } \
160152 } while (0 );
161- #endif
153+ #define TRACING_JUMP_TO_LABEL (label ) \
154+ RECORD_DYNAMIC_JUMP_TAKEN() \
155+ RECORD_TRACE_NO_DISPATCH() \
156+ assert(!IS_JIT_TRACING()); \
157+ JUMP_TO_LABEL(label);
162158
159+ #else
160+ // Note: computed gotos interpreter slows down a lot with tracing.
161+ // So we can't use the same dispatch table technique the tail calling
162+ // interpreter uses.
163+ # define ENTER_TRACING ()
164+ # define IS_JIT_TRACING () (is_tracing_flag)
165+ # define IS_JIT_TRACING_MAKING_PROGRESS () (IS_JIT_TRACING() && tstate->interp->jit_state.last_specialized_instr != this_instr)
166+ # define RECORD_TRACE_NO_ERR_CHECK () \
167+ _PyFrame_SetStackPointer(frame, stack_pointer); \
168+ _PyJitTracerReturnValue jit_status = record_trace(tstate, frame, old_code, old_func, _old_stack_level, this_instr, next_instr, opcode, oparg, _jump_taken); \
169+ stack_pointer = _PyFrame_GetStackPointer(frame);
170+ # define RECORD_TRACE_NO_DISPATCH () \
171+ RECORD_TRACE_NO_ERR_CHECK(); \
172+ if (jit_status.status != CEVAL_LABEL_JIT_CONTINUE_TRACING) { return jit_status; }
173+ #define TRACING_JUMP_TO_LABEL (label ) \
174+ RECORD_DYNAMIC_JUMP_TAKEN(); \
175+ RECORD_TRACE_NO_ERR_CHECK(); \
176+ (void)(jit_status); \
177+ return ((_PyJitTracerReturnValue){CEVAL_LABEL_##label, next_instr});
178+ #endif
179+ #endif
163180
164181/* PRE_DISPATCH_GOTO() does lltrace if enabled. Normally a no-op */
165182#ifdef Py_DEBUG
@@ -204,14 +221,6 @@ do { \
204221 DISPATCH_GOTO(); \
205222 }
206223
207- #define TRACING_SPECIALIZE_DISPATCH_SAME_OPARG () \
208- { \
209- tstate->interp->jit_state.last_specialized_instr = this_instr; \
210- opcode = next_instr->op.code; \
211- PRE_DISPATCH_GOTO(); \
212- DISPATCH_GOTO(); \
213- }
214-
215224#define DISPATCH_INLINED (NEW_FRAME ) \
216225 do { \
217226 assert(tstate->interp->eval_frame == NULL); \
@@ -222,6 +231,14 @@ do { \
222231 JUMP_TO_LABEL(start_frame); \
223232 } while (0)
224233
234+ #define TRACING_SPECIALIZE_DISPATCH_SAME_OPARG () \
235+ { \
236+ tstate->interp->jit_state.last_specialized_instr = this_instr; \
237+ opcode = next_instr->op.code; \
238+ PRE_DISPATCH_GOTO(); \
239+ DISPATCH_GOTO(); \
240+ }
241+
225242#define TRACING_DISPATCH_INLINED (NEW_FRAME ) \
226243 tstate->interp->jit_state.last_specialized_instr = this_instr; \
227244 RECORD_TRACE_NO_DISPATCH(); \
0 commit comments