Skip to content

Commit 441af3a

Browse files
authored
gh-149335: Avoid JIT trace buffer asserts with overhead above FITNESS_INITIAL (GH-149633)
1 parent f2fa291 commit 441af3a

4 files changed

Lines changed: 47 additions & 6 deletions

File tree

Include/internal/pycore_optimizer.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,8 @@ extern "C" {
3131
* 4. A push followed by a matching return is net-zero on frame-specific
3232
* fitness, excluding per-slot costs.
3333
*/
34-
#define MAX_TARGET_LENGTH (UOP_MAX_TRACE_LENGTH / 2)
3534
#define OPTIMIZER_EFFECTIVENESS 2
36-
#define FITNESS_INITIAL (MAX_TARGET_LENGTH * OPTIMIZER_EFFECTIVENESS)
35+
#define MAX_TARGET_LENGTH (FITNESS_INITIAL / OPTIMIZER_EFFECTIVENESS)
3736

3837
/* Exit quality thresholds: trace stops when fitness < exit_quality.
3938
* Higher = trace is more willing to stop here. */

Include/internal/pycore_uop.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,18 @@ typedef struct _PyUOpInstruction{
3636
#endif
3737
} _PyUOpInstruction;
3838

39-
// This is the length of the trace we translate initially.
39+
// Fitness is the target length of the trace we translate initially. The uop
40+
// buffer has a small amount of extra space for entry/loop-closing overhead.
4041
#if defined(Py_DEBUG) && defined(_Py_JIT)
4142
// With asserts, the stencils are a lot larger
42-
#define UOP_MAX_TRACE_LENGTH 1000
43+
#define FITNESS_INITIAL 1000
4344
#else
44-
#define UOP_MAX_TRACE_LENGTH 2500
45+
#define FITNESS_INITIAL 2500
4546
#endif
4647

48+
#define UOP_TRACE_BUFFER_OVERHEAD 10
49+
#define UOP_MAX_TRACE_LENGTH (FITNESS_INITIAL + UOP_TRACE_BUFFER_OVERHEAD)
50+
4751
/* Bloom filter with m = 256
4852
* https://en.wikipedia.org/wiki/Bloom_filter */
4953
#ifdef HAVE_GCC_UINT128_T

Lib/test/test_capi/test_opt.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5924,6 +5924,44 @@ def __next__(self):
59245924
"""), PYTHON_JIT="1", PYTHON_JIT_STRESS="1")
59255925
self.assertEqual(result[0].rc, 0, result)
59265926

5927+
def test_149335_trace_buffer_guard(self):
5928+
# https://github.com/python/cpython/issues/149335
5929+
5930+
result = script_helper.run_python_until_end('-c', textwrap.dedent("""
5931+
import sys
5932+
5933+
def f1():
5934+
for i_3178 in 0, 2, 10:
5935+
mv162 = 162
5936+
5937+
mv3 = mv1 = mv_165 = mv16 = \
5938+
mv167 = mv168 = \
5939+
mv169 = \
5940+
mv_1403_170 = \
5941+
169
5942+
5943+
mv_1403_170
5944+
5945+
mv_172 = mv_3 = mv_4 = mv175 = mv176 = mv17 = mv178 = mv179 = mv0 = mv1 = mv182 = (
5946+
mv3
5947+
) = mv4 = mv185 = mv186 = mv187 = mv18 = mv189 = mv0 = mv1 = mv192 = mv3 = mv4 = (
5948+
mv195
5949+
) = mv196 = mv197 = mv_198 = mv19 = mv0 = mv1 = mv2 = mv3 = mv4 = mv05 = mv06 = (
5950+
mv07
5951+
) = mv08 = mv09 = mv0 = mv1 = mv2 = mv3 = mv4 = mv15 = mv16 = mv17 = mv18 = mv19 = (
5952+
mv0
5953+
) = mv1 = mv_2 = mv3 = mv4 = mv_25 = mv_26 = mv_27 = mv_28 = mv_29 = mv0 = mv1 = (
5954+
mv2
5955+
) = mv_1403 = mv4 = mv35 = mv36 = mv37 = mv38 = mv39 = mv0 = -sys.maxsize / 3
5956+
5957+
mv1 = mv_12 = mv3 = mv_14 = mv45 = sys.float_info.epsilon
5958+
mv46 = sys.float_info.epsilon
5959+
5960+
for i in range(15000):
5961+
f1()
5962+
"""), PYTHON_JIT="1")
5963+
self.assertEqual(result[0].rc, 0, result)
5964+
59275965
def test_144068_daemon_thread_jit_cleanup(self):
59285966
result = script_helper.run_python_until_end('-c', textwrap.dedent("""
59295967
import threading

Python/pystate.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ init_interpreter(PyInterpreterState *interp,
634634
// Trace fitness configuration
635635
init_policy(&interp->opt_config.fitness_initial,
636636
"PYTHON_JIT_FITNESS_INITIAL",
637-
FITNESS_INITIAL, EXIT_QUALITY_CLOSE_LOOP, UOP_MAX_TRACE_LENGTH - 1);
637+
FITNESS_INITIAL, EXIT_QUALITY_CLOSE_LOOP, FITNESS_INITIAL);
638638

639639
interp->opt_config.specialization_enabled = !is_env_enabled("PYTHON_SPECIALIZATION_OFF");
640640
interp->opt_config.uops_optimize_enabled = !is_env_disabled("PYTHON_UOPS_OPTIMIZE");

0 commit comments

Comments
 (0)