// Must be larger than ADAPTIVE_COOLDOWN_VALUE, otherwise when JIT code is
// invalidated we may construct a new trace before the bytecode has properly
// re-specialized:
-#define JUMP_BACKWARD_INITIAL_VALUE 4095
-#define JUMP_BACKWARD_INITIAL_BACKOFF 12
+// Note: this should be a prime number-1. This increases the likelihood of
+// finding a "good" loop iteration to trace.
+// For example, 4095 does not work for the nqueens benchmark on pyperformanc
+// as we always end up tracing the loop iteration's
+// exhaustion iteration. Which aborts our current tracer.
+#define JUMP_BACKWARD_INITIAL_VALUE 4000
+#define JUMP_BACKWARD_INITIAL_BACKOFF 14
static inline _Py_BackoffCounter
initial_jump_backoff_counter(void)
{
* Must be larger than ADAPTIVE_COOLDOWN_VALUE,
* otherwise when a side exit warms up we may construct
* a new trace before the Tier 1 code has properly re-specialized. */
-#define SIDE_EXIT_INITIAL_VALUE 4095
+#define SIDE_EXIT_INITIAL_VALUE 4000
#define SIDE_EXIT_INITIAL_BACKOFF 12
static inline _Py_BackoffCounter
// Strange control-flow, unsupported opcode, etc.
if (tstate->interp->jit_state.dynamic_jump_taken) {
+ DPRINTF(2, "Unsupported: dynamic jump taken\n");
goto unsupported;
}
// This happens when a recursive call happens that we can't trace. Such as Python -> C -> Python calls
// If we haven't guarded the IP, then it's untraceable.
if (frame != tstate->interp->jit_state.prev_instr_frame && !needs_guard_ip) {
+ DPRINTF(2, "Unsupported: unguardable jump taken\n");
goto unsupported;
}
if (oparg > 0xFFFF) {
+ DPRINTF(2, "Unsupported: oparg too large\n");
goto unsupported;
}
}
if (opcode == WITH_EXCEPT_START || opcode == RERAISE || opcode == CLEANUP_THROW || opcode == PUSH_EXC_INFO) {
+ DPRINTF(2, "Unsupported: strange control-flow\n");
goto unsupported;
}
if (frame->owner >= FRAME_OWNED_BY_INTERPRETER) {
+ DPRINTF(2, "Unsupported: frame owned by interpreter\n");
unsupported:
{
// Rewind to previous instruction and replace with _EXIT_TRACE.