@@ -143,6 +143,18 @@ incorrect_keys(PyObject *obj, uint32_t version)
143143#define STACK_LEVEL () ((int)(stack_pointer - ctx->frame->stack))
144144#define STACK_SIZE () ((int)(ctx->frame->stack_len))
145145
146+ static inline int
147+ is_terminator_uop (const _PyUOpInstruction * uop )
148+ {
149+ int opcode = uop -> opcode ;
150+ return (
151+ opcode == _EXIT_TRACE ||
152+ opcode == _JUMP_TO_TOP ||
153+ opcode == _DYNAMIC_EXIT ||
154+ opcode == _DEOPT
155+ );
156+ }
157+
146158#define CURRENT_FRAME_IS_INIT_SHIM () (ctx->frame->code == ((PyCodeObject *)&_Py_InitCleanup))
147159
148160#define GETLOCAL (idx ) ((ctx->frame->locals[idx]))
@@ -152,15 +164,21 @@ incorrect_keys(PyObject *obj, uint32_t version)
152164 (INST)->oparg = ARG; \
153165 (INST)->operand0 = OPERAND;
154166
155- #define ADD_OP (OP , ARG , OPERAND ) ( \
156- ctx->out_buffer[ctx->out_len].opcode = (OP), \
157- ctx->out_buffer[ctx->out_len].format = this_instr->format, \
158- ctx->out_buffer[ctx->out_len].oparg = (ARG), \
159- ctx->out_buffer[ctx->out_len].target = this_instr->target, \
160- ctx->out_buffer[ctx->out_len].operand0 = (OPERAND), \
161- ctx->out_buffer[ctx->out_len].operand1 = this_instr->operand1, \
162- ctx->out_len++ \
163- )
167+ #define ADD_OP (OP , ARG , OPERAND ) add_op(ctx, this_instr, (OP), (ARG), (OPERAND))
168+
169+ static inline void
170+ add_op (JitOptContext * ctx , _PyUOpInstruction * this_instr ,
171+ uint16_t opcode , uint16_t oparg , uintptr_t operand0 )
172+ {
173+ _PyUOpInstruction * out = & ctx -> tracer -> out_buffer [ctx -> tracer -> out_len ];
174+ out -> opcode = (opcode );
175+ out -> format = this_instr -> format ;
176+ out -> oparg = (oparg );
177+ out -> target = this_instr -> target ;
178+ out -> operand0 = (operand0 );
179+ out -> operand1 = this_instr -> operand1 ;
180+ ctx -> tracer -> out_len ++ ;
181+ }
164182
165183/* Shortened forms for convenience, used in optimizer_bytecodes.c */
166184#define sym_is_not_null _Py_uop_sym_is_not_null
@@ -359,6 +377,8 @@ optimize_uops(
359377 JitOptContext * ctx = & tstate -> jit_tracer_state -> opt_context ;
360378 uint32_t opcode = UINT16_MAX ;
361379
380+ ctx -> tracer = tstate -> jit_tracer_state ;
381+
362382 // Make sure that watchers are set up
363383 PyInterpreterState * interp = _PyInterpreterState_GET ();
364384 if (interp -> dict_state .watchers [GLOBALS_WATCHER_ID ] == NULL ) {
@@ -374,7 +394,7 @@ optimize_uops(
374394 frame -> func = func ;
375395 ctx -> curr_frame_depth ++ ;
376396 ctx -> frame = frame ;
377- ctx -> out_len = 0 ;
397+ ctx -> tracer -> out_len = 0 ;
378398
379399 _PyUOpInstruction * this_instr = NULL ;
380400 JitOptRef * stack_pointer = ctx -> frame -> stack_pointer ;
@@ -398,7 +418,7 @@ optimize_uops(
398418 }
399419#endif
400420
401- int out_len_before = ctx -> out_len ;
421+ int out_len_before = ctx -> tracer -> out_len ;
402422 switch (opcode ) {
403423
404424#include "optimizer_cases.c.h"
@@ -408,8 +428,8 @@ optimize_uops(
408428 Py_UNREACHABLE ();
409429 }
410430 // If no ADD_OP was called during this iteration, copy the original instruction
411- if (ctx -> out_len == out_len_before ) {
412- ctx -> out_buffer [ctx -> out_len ++ ] = * this_instr ;
431+ if (ctx -> tracer -> out_len == out_len_before ) {
432+ ctx -> tracer -> out_buffer [ctx -> tracer -> out_len ++ ] = * this_instr ;
413433 }
414434 assert (ctx -> frame != NULL );
415435 if (!CURRENT_FRAME_IS_INIT_SHIM ()) {
@@ -440,17 +460,13 @@ optimize_uops(
440460 * would be no benefit in retrying later */
441461 _Py_uop_abstractcontext_fini (ctx );
442462 // Check that the trace ends with a proper terminator
443- if (ctx -> out_len > 0 ) {
444- int last_opcode = ctx -> out_buffer [ctx -> out_len - 1 ].opcode ;
445- if (last_opcode != _EXIT_TRACE &&
446- last_opcode != _JUMP_TO_TOP &&
447- last_opcode != _DYNAMIC_EXIT &&
448- last_opcode != _DEOPT ) {
463+ if (ctx -> tracer -> out_len > 0 ) {
464+ if (!is_terminator_uop (& ctx -> tracer -> out_buffer [ctx -> tracer -> out_len - 1 ])) {
449465 return 0 ;
450466 }
451467 }
452468
453- return ctx -> out_len ;
469+ return ctx -> tracer -> out_len ;
454470
455471error :
456472 DPRINTF (3 , "\n" );
@@ -611,7 +627,6 @@ _Py_uop_analyze_and_optimize(
611627)
612628{
613629 OPT_STAT_INC (optimizer_attempts );
614- JitOptContext * ctx = & tstate -> jit_tracer_state -> opt_context ;
615630
616631 length = optimize_uops (
617632 tstate , buffer ,
@@ -623,7 +638,7 @@ _Py_uop_analyze_and_optimize(
623638
624639 assert (length > 0 );
625640
626- length = remove_unneeded_uops (ctx -> out_buffer , length );
641+ length = remove_unneeded_uops (tstate -> jit_tracer_state -> out_buffer , length );
627642 assert (length > 0 );
628643
629644 OPT_STAT_INC (optimizer_successes );
0 commit comments