-
-
Notifications
You must be signed in to change notification settings - Fork 34.1k
Open
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)topic-JITtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
Bug report
Bug description:
Below is the example I triggered. i am in commit 3dadc22a2796af7718f1aec02e30f100ac6553bd of the main branch.
The CPython is compiled with --with-pydebug --enable-experimental-jit. OS is ubuntu24.04.
With PYTHON_JIT=0 python ./test.py we successfully get we finished.
However with PYTHON_JIT=1 python ./test.py,
We get
python: Python/optimizer.c:804: _PyJit_translate_single_bytecode_to_trace: Assertion `jump_happened == (target_instr[1].cache & 1)' failed.
Aborted (core dumped)
Code is below
import random
fuzzer_rng = random.Random(1070)
from random import random
from sys import stderr
def uop_harness_f1():
import gc
gc.set_threshold(1)
class _SurferA:
def __init__(self, val):
self.val = val
def __bool__(self):
self.__class__ = _SurferB
return True
def __int__(self):
self.__class__ = _SurferB
return int(self.val)
def __index__(self):
self.__class__ = _SurferB
return int(self.val)
def __add__(self, other):
self.__class__ = _SurferB
return self.val + other
class _SurferB:
def __init__(self, val):
self.val = val
def __bool__(self):
self.__class__ = _SurferA
return False
def __int__(self):
self.__class__ = _SurferA
return int(self.val)
def __index__(self):
self.__class__ = _SurferA
return int(self.val)
def __add__(self, other):
self.__class__ = _SurferA
return self.val + other
class ChaoticIterator_comp_8805:
def __init__(self, items):
self._items = list(items)
self._index = 0
def __iter__(self):
return self
def __next__(self):
if fuzzer_rng.random() < 0.05:
self._items.clear()
if fuzzer_rng.random() < 0.05:
self._items.extend([999, 'chaos', None])
if fuzzer_rng.random() >= 0.1:
return 'unexpected_type_from_iterator'
if self._index >= len(self._items):
raise StopIteration
item = self._items[self._index]
self._index += 1
return item
evil_iter_comp_8805 = ChaoticIterator_comp_8805(range(200))
try:
_ = [x + y for x in evil_iter_comp_8805 for y in evil_iter_comp_8805 if evil_iter_comp_8805._items.append(x) or True]
except Exception:
pass
for i_f1 in range(300):
try:
final_harness_locals = uop_harness_f1()
except Exception as e:
print(f'EXCEPTION: {e.__class__.__name__}: {e}', file=stderr)
pass
print("we finished")Below is the diff i used to trigger JIT easier
diff --git a/Include/internal/pycore_backoff.h b/Include/internal/pycore_backoff.h
index ee907ae0534..7fd2c960cc4 100644
--- a/Include/internal/pycore_backoff.h
+++ b/Include/internal/pycore_backoff.h
@@ -125,7 +125,7 @@ trigger_backoff_counter(void)
// For example, 4095 does not work for the nqueens benchmark on pyperformance
// 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_VALUE 63
#define JUMP_BACKWARD_INITIAL_BACKOFF 6
static inline _Py_BackoffCounter
initial_jump_backoff_counter(_PyOptimizationConfig *opt_config)
@@ -139,7 +139,7 @@ initial_jump_backoff_counter(_PyOptimizationConfig *opt_config)
* 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 4000
+#define SIDE_EXIT_INITIAL_VALUE 63
#define SIDE_EXIT_INITIAL_BACKOFF 6
static inline _Py_BackoffCounter
diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h
index 79a2d60eb78..ac7d9205e74 100644
--- a/Include/internal/pycore_optimizer.h
+++ b/Include/internal/pycore_optimizer.h
@@ -173,7 +173,7 @@ PyAPI_FUNC(void) _Py_Executors_InvalidateCold(PyInterpreterState *interp);
// Used as the threshold to trigger executor invalidation when
// executor_creation_counter is greater than this value.
// This value is arbitrary and was not optimized.
-#define JIT_CLEANUP_THRESHOLD 1000
+#define JIT_CLEANUP_THRESHOLD 10000
int _Py_uop_analyze_and_optimize(
_PyThreadStateImpl *tstate,
diff --git a/Include/internal/pycore_optimizer_types.h b/Include/internal/pycore_optimizer_types.h
index 57c0c828c2a..afe2804eaba 100644
--- a/Include/internal/pycore_optimizer_types.h
+++ b/Include/internal/pycore_optimizer_types.h
@@ -12,7 +12,7 @@ extern "C" {
#include "pycore_uop.h" // UOP_MAX_TRACE_LENGTH
// Holds locals, stack, locals, stack ... (in that order)
-#define MAX_ABSTRACT_INTERP_SIZE 512
+#define MAX_ABSTRACT_INTERP_SIZE 8192
#define TY_ARENA_SIZE (UOP_MAX_TRACE_LENGTH * 5)
@@ -23,7 +23,7 @@ extern "C" {
// progress (and inserting a new ENTER_EXECUTOR instruction). In practice, this
// is the "maximum amount of polymorphism" that an isolated trace tree can
// handle before rejoining the rest of the program.
-#define MAX_CHAIN_DEPTH 4
+#define MAX_CHAIN_DEPTH 16
/* Symbols */
/* See explanation in optimizer_symbols.c */
diff --git a/Python/optimizer.c b/Python/optimizer.c
index bf5d8a28264..acad398ec35 100644
--- a/Python/optimizer.c
+++ b/Python/optimizer.c
@@ -534,7 +534,7 @@ guard_ip_uop[MAX_UOP_ID + 1] = {
#define CONFIDENCE_RANGE 1000
-#define CONFIDENCE_CUTOFF 333
+#define CONFIDENCE_CUTOFF 100
#ifdef Py_DEBUG
#define DPRINTF(level, ...) \
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)topic-JITtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error