https://github.com/python/cpython/commit/441af3a93426c5e7e3c056fee27e6f4505988584
commit: 441af3a93426c5e7e3c056fee27e6f4505988584
branch: main
author: Hai Zhu <[email protected]>
committer: markshannon <[email protected]>
date: 2026-05-21T15:57:31+01:00
summary:
gh-149335: Avoid JIT trace buffer asserts with overhead above `FITNESS_INITIAL`
(GH-149633)
files:
M Include/internal/pycore_optimizer.h
M Include/internal/pycore_uop.h
M Lib/test/test_capi/test_opt.py
M Python/pystate.c
diff --git a/Include/internal/pycore_optimizer.h
b/Include/internal/pycore_optimizer.h
index 69f913ec9c3038..8c35c4416fe3c8 100644
--- a/Include/internal/pycore_optimizer.h
+++ b/Include/internal/pycore_optimizer.h
@@ -31,9 +31,8 @@ extern "C" {
* 4. A push followed by a matching return is net-zero on frame-specific
* fitness, excluding per-slot costs.
*/
-#define MAX_TARGET_LENGTH (UOP_MAX_TRACE_LENGTH / 2)
#define OPTIMIZER_EFFECTIVENESS 2
-#define FITNESS_INITIAL (MAX_TARGET_LENGTH *
OPTIMIZER_EFFECTIVENESS)
+#define MAX_TARGET_LENGTH (FITNESS_INITIAL / OPTIMIZER_EFFECTIVENESS)
/* Exit quality thresholds: trace stops when fitness < exit_quality.
* Higher = trace is more willing to stop here. */
diff --git a/Include/internal/pycore_uop.h b/Include/internal/pycore_uop.h
index 320508e8b7a95e..e7f0d2c214a764 100644
--- a/Include/internal/pycore_uop.h
+++ b/Include/internal/pycore_uop.h
@@ -36,14 +36,18 @@ typedef struct _PyUOpInstruction{
#endif
} _PyUOpInstruction;
-// This is the length of the trace we translate initially.
+// Fitness is the target length of the trace we translate initially. The uop
+// buffer has a small amount of extra space for entry/loop-closing overhead.
#if defined(Py_DEBUG) && defined(_Py_JIT)
// With asserts, the stencils are a lot larger
-#define UOP_MAX_TRACE_LENGTH 1000
+#define FITNESS_INITIAL 1000
#else
-#define UOP_MAX_TRACE_LENGTH 2500
+#define FITNESS_INITIAL 2500
#endif
+#define UOP_TRACE_BUFFER_OVERHEAD 10
+#define UOP_MAX_TRACE_LENGTH (FITNESS_INITIAL + UOP_TRACE_BUFFER_OVERHEAD)
+
/* Bloom filter with m = 256
* https://en.wikipedia.org/wiki/Bloom_filter */
#ifdef HAVE_GCC_UINT128_T
diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py
index 790e965d6e5ff2..2248920c266aef 100644
--- a/Lib/test/test_capi/test_opt.py
+++ b/Lib/test/test_capi/test_opt.py
@@ -5924,6 +5924,44 @@ def __next__(self):
"""), PYTHON_JIT="1", PYTHON_JIT_STRESS="1")
self.assertEqual(result[0].rc, 0, result)
+ def test_149335_trace_buffer_guard(self):
+ # https://github.com/python/cpython/issues/149335
+
+ result = script_helper.run_python_until_end('-c', textwrap.dedent("""
+ import sys
+
+ def f1():
+ for i_3178 in 0, 2, 10:
+ mv162 = 162
+
+ mv3 = mv1 = mv_165 = mv16 = \
+ mv167 = mv168 = \
+ mv169 = \
+ mv_1403_170 = \
+ 169
+
+ mv_1403_170
+
+ mv_172 = mv_3 = mv_4 = mv175 = mv176 = mv17 = mv178 = mv179 = mv0
= mv1 = mv182 = (
+ mv3
+ ) = mv4 = mv185 = mv186 = mv187 = mv18 = mv189 = mv0 = mv1 = mv192
= mv3 = mv4 = (
+ mv195
+ ) = mv196 = mv197 = mv_198 = mv19 = mv0 = mv1 = mv2 = mv3 = mv4 =
mv05 = mv06 = (
+ mv07
+ ) = mv08 = mv09 = mv0 = mv1 = mv2 = mv3 = mv4 = mv15 = mv16 = mv17
= mv18 = mv19 = (
+ mv0
+ ) = mv1 = mv_2 = mv3 = mv4 = mv_25 = mv_26 = mv_27 = mv_28 = mv_29
= mv0 = mv1 = (
+ mv2
+ ) = mv_1403 = mv4 = mv35 = mv36 = mv37 = mv38 = mv39 = mv0 =
-sys.maxsize / 3
+
+ mv1 = mv_12 = mv3 = mv_14 = mv45 = sys.float_info.epsilon
+ mv46 = sys.float_info.epsilon
+
+ for i in range(15000):
+ f1()
+ """), PYTHON_JIT="1")
+ self.assertEqual(result[0].rc, 0, result)
+
def test_144068_daemon_thread_jit_cleanup(self):
result = script_helper.run_python_until_end('-c', textwrap.dedent("""
import threading
diff --git a/Python/pystate.c b/Python/pystate.c
index ff712019affbf9..530bd567b770be 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -634,7 +634,7 @@ init_interpreter(PyInterpreterState *interp,
// Trace fitness configuration
init_policy(&interp->opt_config.fitness_initial,
"PYTHON_JIT_FITNESS_INITIAL",
- FITNESS_INITIAL, EXIT_QUALITY_CLOSE_LOOP, UOP_MAX_TRACE_LENGTH
- 1);
+ FITNESS_INITIAL, EXIT_QUALITY_CLOSE_LOOP, FITNESS_INITIAL);
interp->opt_config.specialization_enabled =
!is_env_enabled("PYTHON_SPECIALIZATION_OFF");
interp->opt_config.uops_optimize_enabled =
!is_env_disabled("PYTHON_UOPS_OPTIMIZE");
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]