Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

JIT: Different behaviors when JIT is enabled. #144681

Copy link
Copy link
@nevercodecorrect

Description

@nevercodecorrect
Issue body actions

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

Linked PRs

Reactions are currently unavailable

Metadata

Metadata

Assignees

No one assigned

    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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.