Skip to content

Commit f0d4c57

Browse files
Re-enable the JIT
1 parent 1e5713d commit f0d4c57

File tree

12 files changed

+132
-52
lines changed

12 files changed

+132
-52
lines changed

Include/internal/pycore_opcode_metadata.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_optimizer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ PyAPI_FUNC(void) _Py_Executor_DependsOn(_PyExecutorObject *executor, void *obj);
7878

7979
#ifdef _Py_TIER2
8080
PyAPI_FUNC(void) _Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj, int is_invalidation);
81+
PyAPI_FUNC(void) _Py_Executors_InvalidateDependencyLockHeld(PyInterpreterState *interp, void *obj, int is_invalidation);
8182
PyAPI_FUNC(void) _Py_Executors_InvalidateAll(PyInterpreterState *interp, int is_invalidation);
83+
PyAPI_FUNC(void) _Py_Executors_InvalidateAllLockHeld(PyInterpreterState *interp, int is_invalidation);
8284
PyAPI_FUNC(void) _Py_Executors_InvalidateCold(PyThreadState *tstate);
8385
PyAPI_FUNC(void) _Py_Executors_ClearExecutorList(PyObject *invalidate, int is_invalidation);
8486
#else

Include/internal/pycore_tstate.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ typedef struct _PyJitTracerState {
5454
} _PyJitTracerState;
5555

5656
typedef struct _PyJitExecutorState {
57-
bool jit;
58-
bool compiling;
57+
char jit;
5958
struct _PyExecutorObject *executor_list_head;
6059
struct _PyExecutorObject *executor_deletion_list_head;
6160
struct _PyExecutorObject *cold_executor;

Lib/test/test_capi/test_opt.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ def get_opnames(ex):
5050
return list(iter_opnames(ex))
5151

5252

53-
@requires_specialization
54-
@unittest.skipIf(Py_GIL_DISABLED, "optimizer not yet supported in free-threaded builds")
5553
@requires_jit_enabled
5654
class TestExecutorInvalidation(unittest.TestCase):
5755

@@ -115,12 +113,8 @@ def f():
115113
self.assertTrue(exe.is_valid())
116114
sys._clear_internal_caches()
117115
self.assertFalse(exe.is_valid())
118-
exe = get_first_executor(f)
119-
self.assertIsNone(exe)
120116

121117

122-
@requires_specialization
123-
@unittest.skipIf(Py_GIL_DISABLED, "optimizer not yet supported in free-threaded builds")
124118
@requires_jit_enabled
125119
@unittest.skipIf(os.getenv("PYTHON_UOPS_OPTIMIZE") == "0", "Needs uop optimizer to run.")
126120
class TestUops(unittest.TestCase):

Objects/codeobject.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2441,7 +2441,9 @@ code_dealloc(PyObject *self)
24412441
#ifdef _Py_TIER2
24422442
_Py_Executors_InvalidateDependency(tstate->interp, self, 1);
24432443
if (co->co_executors != NULL) {
2444+
Py_BEGIN_CRITICAL_SECTION(co);
24442445
clear_executors(co);
2446+
Py_END_CRITICAL_SECTION();
24452447
}
24462448
#endif
24472449

@@ -3370,8 +3372,12 @@ deopt_code_unit(PyCodeObject *code, int i)
33703372
inst.op.code = _PyOpcode_Deopt[opcode];
33713373
assert(inst.op.code < MIN_SPECIALIZED_OPCODE);
33723374
}
3373-
// JIT should not be enabled with free-threading
3374-
assert(inst.op.code != ENTER_EXECUTOR);
3375+
if (inst.op.code == ENTER_EXECUTOR) {
3376+
_PyExecutorObject *exec = code->co_executors->executors[inst.op.arg];
3377+
assert(exec != NULL);
3378+
inst.op.code = exec->vm_data.opcode;
3379+
inst.op.arg = exec->vm_data.oparg;
3380+
}
33753381
return inst;
33763382
}
33773383

Python/bytecodes.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2939,9 +2939,9 @@ dummy_func(
29392939
};
29402940

29412941
specializing tier1 op(_SPECIALIZE_JUMP_BACKWARD, (--)) {
2942-
#if ENABLE_SPECIALIZATION
2942+
#if ENABLE_SPECIALIZATION_FT
29432943
if (this_instr->op.code == JUMP_BACKWARD) {
2944-
uint8_t desired = ((_PyThreadStateImpl*)tstate)->jit_executor_state.jit ? JUMP_BACKWARD_JIT : JUMP_BACKWARD_NO_JIT;
2944+
uint8_t desired = FT_ATOMIC_LOAD_CHAR_RELAXED(((_PyThreadStateImpl*)tstate)->jit_executor_state.jit) ? JUMP_BACKWARD_JIT : JUMP_BACKWARD_NO_JIT;
29452945
FT_ATOMIC_STORE_UINT8_RELAXED(this_instr->op.code, desired);
29462946
// Need to re-dispatch so the warmup counter isn't off by one:
29472947
next_instr = this_instr;
@@ -3018,11 +3018,25 @@ dummy_func(
30183018
goto stop_tracing;
30193019
}
30203020
PyCodeObject *code = _PyFrame_GetCode(frame);
3021+
#ifdef Py_GIL_DISABLED
3022+
LOCK_OBJECT_SLOW(code);
3023+
_PyExecutorObject *executor = code->co_executors->executors[oparg & 255];
3024+
// On FT, we are responsible for cleaning up after ourselves.
3025+
if (!_Py_atomic_load_uint8_relaxed(&executor->vm_data.valid)) {
3026+
opcode = executor->vm_data.opcode;
3027+
oparg = (oparg & ~255) | executor->vm_data.oparg;
3028+
next_instr = this_instr;
3029+
_Py_ExecutorDetach(executor);
3030+
UNLOCK_OBJECT_SLOW(code);
3031+
DISPATCH_GOTO();
3032+
}
3033+
#else
30213034
_PyExecutorObject *executor = code->co_executors->executors[oparg & 255];
3022-
assert(executor->vm_data.index == INSTR_OFFSET() - 1);
3023-
assert(executor->vm_data.code == code);
30243035
assert(executor->vm_data.valid);
3036+
#endif
30253037
assert(tstate->current_executor == NULL);
3038+
assert(executor->vm_data.index == INSTR_OFFSET() - 1);
3039+
assert(executor->vm_data.code == code);
30263040
/* If the eval breaker is set then stay in tier 1.
30273041
* This avoids any potentially infinite loops
30283042
* involving _RESUME_CHECK */
@@ -3033,10 +3047,15 @@ dummy_func(
30333047
if (_PyOpcode_Caches[_PyOpcode_Deopt[opcode]]) {
30343048
PAUSE_ADAPTIVE_COUNTER(this_instr[1].counter);
30353049
}
3050+
#ifdef Py_GIL_DISABLED
3051+
UNLOCK_OBJECT_SLOW(code);
3052+
#endif
30363053
DISPATCH_GOTO();
30373054
}
30383055
assert(executor != ((_PyThreadStateImpl *)tstate)->jit_executor_state.cold_executor);
30393056
tstate->jit_exit = NULL;
3057+
Py_INCREF(executor);
3058+
UNLOCK_OBJECT_SLOW(code);
30403059
TIER1_TO_TIER2(executor);
30413060
#else
30423061
Py_FatalError("ENTER_EXECUTOR is not supported in this build");

Python/ceval_macros.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,13 @@ GETITEM(PyObject *v, Py_ssize_t i) {
294294
#ifdef Py_GIL_DISABLED
295295
# define LOCK_OBJECT(op) PyMutex_LockFast(&(_PyObject_CAST(op))->ob_mutex)
296296
# define UNLOCK_OBJECT(op) PyMutex_Unlock(&(_PyObject_CAST(op))->ob_mutex)
297+
# define LOCK_OBJECT_SLOW(op) PyMutex_LockFast(&(_PyObject_CAST(op))->ob_mutex)
298+
# define UNLOCK_OBJECT_SLOW(op) PyMutex_Unlock(&(_PyObject_CAST(op))->ob_mutex)
297299
#else
298300
# define LOCK_OBJECT(op) (1)
299301
# define UNLOCK_OBJECT(op) ((void)0)
302+
# define LOCK_OBJECT_SLOW(op) ((void)0)
303+
# define UNLOCK_OBJECT_SLOW(op) ((void)0)
300304
#endif
301305

302306
#define GLOBALS() frame->f_globals

Python/generated_cases.c.h

Lines changed: 24 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/instrumentation.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,7 @@ force_instrument_lock_held(PyCodeObject *code, PyInterpreterState *interp)
17851785
if (code->co_executors != NULL) {
17861786
_PyCode_Clear_Executors(code);
17871787
}
1788-
_Py_Executors_InvalidateDependency(_PyInterpreterState_GET(), code, 1);
1788+
_Py_Executors_InvalidateDependencyLockHeld(_PyInterpreterState_GET(), code, 1);
17891789
#endif
17901790
int code_len = (int)Py_SIZE(code);
17911791
/* Exit early to avoid creating instrumentation
@@ -2028,7 +2028,7 @@ _PyMonitoring_SetEvents(int tool_id, _PyMonitoringEventSet events)
20282028
}
20292029
set_global_version(tstate, new_version);
20302030
#ifdef _Py_TIER2
2031-
_Py_Executors_InvalidateAll(interp, 1);
2031+
_Py_Executors_InvalidateAllLockHeld(interp, 1);
20322032
#endif
20332033
return instrument_all_executing_code_objects(interp);
20342034
}

0 commit comments

Comments
 (0)