#if _Py_TAIL_CALL_INTERP || USE_COMPUTED_GOTOS
# define IS_JIT_TRACING() (DISPATCH_TABLE_VAR == TRACING_DISPATCH_TABLE)
+// tstate->interp->jit_state.last_specialized_instr != this_instr is required to not get stuck in infinite
+// specialization loops due to specialization failure.
+# define IS_JIT_TRACING_MAKING_PROGRESS() (IS_JIT_TRACING() && tstate->interp->jit_state.last_specialized_instr != this_instr)
# define ENTER_TRACING() \
DISPATCH_TABLE_VAR = TRACING_DISPATCH_TABLE;
# define LEAVE_TRACING() \
DISPATCH_GOTO(); \
}
+#define TRACING_SPECIALIZE_DISPATCH_SAME_OPARG() \
+{ \
+ tstate->interp->jit_state.last_specialized_instr = this_instr; \
+ opcode = next_instr->op.code; \
+ PRE_DISPATCH_GOTO(); \
+ DISPATCH_GOTO(); \
+}
+
#define DISPATCH_INLINED(NEW_FRAME) \
do { \
assert(tstate->interp->eval_frame == NULL); \
} while (0)
#define TRACING_DISPATCH_INLINED(NEW_FRAME) \
+ tstate->interp->jit_state.last_specialized_instr = this_instr; \
RECORD_TRACE_NO_DISPATCH(); \
DISPATCH_INLINED(NEW_FRAME);
#define TRACING_DISPATCH() \
{ \
+ tstate->interp->jit_state.last_specialized_instr = this_instr; \
assert(frame->stackpointer == NULL); \
RECORD_TRACE_NO_DISPATCH(); \
NEXTOPARG(); \
/* This takes a uint16_t instead of a _Py_BackoffCounter,
* because it is used directly on the cache entry in generated code,
* which is always an integral type. */
+#if _Py_TIER2
+// Force re-specialization when tracing a side exit to get good side exits.
+#define ADAPTIVE_COUNTER_TRIGGERS(COUNTER) \
+ backoff_counter_triggers(forge_backoff_counter((COUNTER))) || IS_JIT_TRACING_MAKING_PROGRESS()
+#else
#define ADAPTIVE_COUNTER_TRIGGERS(COUNTER) \
backoff_counter_triggers(forge_backoff_counter((COUNTER)))
-
+#endif
#define ADVANCE_ADAPTIVE_COUNTER(COUNTER) \
do { \
(COUNTER) = advance_backoff_counter((COUNTER)); \
_PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_BinaryOp(lhs, rhs, next_instr, oparg, LOCALS_ARRAY);
stack_pointer = _PyFrame_GetStackPointer(frame);
- DISPATCH_SAME_OPARG();
+ TRACING_SPECIALIZE_DISPATCH_SAME_OPARG()
}
OPCODE_DEFERRED_INC(BINARY_OP);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
_PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_Call(callable, next_instr, oparg + !PyStackRef_IsNull(self_or_null));
stack_pointer = _PyFrame_GetStackPointer(frame);
- DISPATCH_SAME_OPARG();
+ TRACING_SPECIALIZE_DISPATCH_SAME_OPARG()
}
OPCODE_DEFERRED_INC(CALL);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
_PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_CallKw(callable, next_instr, oparg + !PyStackRef_IsNull(self_or_null));
stack_pointer = _PyFrame_GetStackPointer(frame);
- DISPATCH_SAME_OPARG();
+ TRACING_SPECIALIZE_DISPATCH_SAME_OPARG()
}
OPCODE_DEFERRED_INC(CALL_KW);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
_PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_CompareOp(left, right, next_instr, oparg);
stack_pointer = _PyFrame_GetStackPointer(frame);
- DISPATCH_SAME_OPARG();
+ TRACING_SPECIALIZE_DISPATCH_SAME_OPARG()
}
OPCODE_DEFERRED_INC(COMPARE_OP);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
_PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_ContainsOp(right, next_instr);
stack_pointer = _PyFrame_GetStackPointer(frame);
- DISPATCH_SAME_OPARG();
+ TRACING_SPECIALIZE_DISPATCH_SAME_OPARG()
}
OPCODE_DEFERRED_INC(CONTAINS_OP);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
_PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_ForIter(iter, null_or_index, next_instr, oparg);
stack_pointer = _PyFrame_GetStackPointer(frame);
- DISPATCH_SAME_OPARG();
+ TRACING_SPECIALIZE_DISPATCH_SAME_OPARG()
}
OPCODE_DEFERRED_INC(FOR_ITER);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
uint8_t desired = tstate->interp->jit ? JUMP_BACKWARD_JIT : JUMP_BACKWARD_NO_JIT;
FT_ATOMIC_STORE_UINT8_RELAXED(this_instr->op.code, desired);
next_instr = this_instr;
- DISPATCH_SAME_OPARG();
+ DISPATCH_SAME_OPARG()
}
#endif
}
_PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_LoadAttr(owner, next_instr, name);
stack_pointer = _PyFrame_GetStackPointer(frame);
- DISPATCH_SAME_OPARG();
+ TRACING_SPECIALIZE_DISPATCH_SAME_OPARG()
}
OPCODE_DEFERRED_INC(LOAD_ATTR);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
_PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name);
stack_pointer = _PyFrame_GetStackPointer(frame);
- DISPATCH_SAME_OPARG();
+ TRACING_SPECIALIZE_DISPATCH_SAME_OPARG()
}
OPCODE_DEFERRED_INC(LOAD_GLOBAL);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
_PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_LoadSuperAttr(global_super_st, class_st, next_instr, load_method);
stack_pointer = _PyFrame_GetStackPointer(frame);
- DISPATCH_SAME_OPARG();
+ TRACING_SPECIALIZE_DISPATCH_SAME_OPARG()
}
OPCODE_DEFERRED_INC(LOAD_SUPER_ATTR);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
_PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_Send(receiver, next_instr);
stack_pointer = _PyFrame_GetStackPointer(frame);
- DISPATCH_SAME_OPARG();
+ TRACING_SPECIALIZE_DISPATCH_SAME_OPARG()
}
OPCODE_DEFERRED_INC(SEND);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
_PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_StoreAttr(owner, next_instr, name);
stack_pointer = _PyFrame_GetStackPointer(frame);
- DISPATCH_SAME_OPARG();
+ TRACING_SPECIALIZE_DISPATCH_SAME_OPARG()
}
OPCODE_DEFERRED_INC(STORE_ATTR);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
_PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_StoreSubscr(container, sub, next_instr);
stack_pointer = _PyFrame_GetStackPointer(frame);
- DISPATCH_SAME_OPARG();
+ TRACING_SPECIALIZE_DISPATCH_SAME_OPARG()
}
OPCODE_DEFERRED_INC(STORE_SUBSCR);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
_PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_ToBool(value, next_instr);
stack_pointer = _PyFrame_GetStackPointer(frame);
- DISPATCH_SAME_OPARG();
+ TRACING_SPECIALIZE_DISPATCH_SAME_OPARG()
}
OPCODE_DEFERRED_INC(TO_BOOL);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
_PyFrame_SetStackPointer(frame, stack_pointer);
_Py_Specialize_UnpackSequence(seq, next_instr, oparg);
stack_pointer = _PyFrame_GetStackPointer(frame);
- DISPATCH_SAME_OPARG();
+ TRACING_SPECIALIZE_DISPATCH_SAME_OPARG()
}
OPCODE_DEFERRED_INC(UNPACK_SEQUENCE);
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);