7373#define TAIL_CALL_PARAMS _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate, _Py_CODEUNIT *next_instr, int oparg
7474#define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, oparg
7575
76+ // 1st version looks like this where we load directly
77+ // next_op_f = INSTRUCTION_TABLE[next_instr->op.code];
78+ // 2nd version is like NEXTOPARG which does this atomic thing
7679#ifdef Py_TAIL_CALL_INTERP
7780# define LOAD_NEXT_OP_F () \
7881 do { \
79- next_op_f = INSTRUCTION_TABLE[next_instr->op.code]; \
82+ _Py_CODEUNIT word = {.cache = FT_ATOMIC_LOAD_UINT16_RELAXED(*(uint16_t*)next_instr)}; \
83+ next_op_f = INSTRUCTION_TABLE[word.op.code]; \
8084 } while (0)
8185 // Note: [[clang::musttail]] works for GCC 15, but not __attribute__((musttail)) at the moment.
8286# define Py_MUSTTAIL [[clang::musttail]]
8690# define TARGET (op ) Py_PRESERVE_NONE_CC PyObject *_TAIL_CALL_##op(TAIL_CALL_PARAMS)
8791# define DISPATCH_GOTO () \
8892 do { \
93+ assert(next_op_f == INSTRUCTION_TABLE[opcode]); \
8994 Py_MUSTTAIL return next_op_f(TAIL_CALL_ARGS); \
9095 } while (0)
9196# define JUMP_TO_LABEL (name ) \
@@ -148,9 +153,11 @@ do { \
148153 DISPATCH_GOTO(); \
149154 }
150155
156+ // TODO better
151157#define DISPATCH_SAME_OPARG () \
152158 { \
153159 opcode = next_instr->op.code; \
160+ next_op_f = INSTRUCTION_TABLE[opcode]; \
154161 PRE_DISPATCH_GOTO(); \
155162 DISPATCH_GOTO(); \
156163 }
@@ -347,13 +354,13 @@ do { \
347354 } else { \
348355 _PyFrame_SetStackPointer(frame, stack_pointer); \
349356 next_instr = _Py_call_instrumentation_jump(this_instr, tstate, event, frame, src, dest); \
350- LOAD_NEXT_OP_F(); \
351357 stack_pointer = _PyFrame_GetStackPointer(frame); \
352358 if (next_instr == NULL) { \
353359 next_instr = (dest)+1; \
354360 JUMP_TO_LABEL(error); \
355361 } \
356362 } \
363+ LOAD_NEXT_OP_F(); \
357364} while (0);
358365
359366
@@ -373,7 +380,7 @@ static inline void _Py_LeaveRecursiveCallPy(PyThreadState *tstate) {
373380
374381#define LOAD_IP (OFFSET ) do { \
375382 next_instr = frame->instr_ptr + (OFFSET); \
376- LOAD_NEXT_OP_F(); \
383+ LOAD_NEXT_OP_F(); \
377384 } while (0)
378385
379386/* There's no STORE_IP(), it's inlined by the code generator. */
0 commit comments