Skip to content

Commit 8b38039

Browse files
committed
move JitOptContext to _PyThreadStateImpl
1 parent f11f5eb commit 8b38039

File tree

5 files changed

+23
-3
lines changed

5 files changed

+23
-3
lines changed

Include/internal/pycore_optimizer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ PyAPI_FUNC(void) _Py_Executors_InvalidateCold(PyInterpreterState *interp);
8484
#define JIT_CLEANUP_THRESHOLD 1000
8585

8686
int _Py_uop_analyze_and_optimize(
87+
struct _PyThreadStateImpl *tstate,
8788
PyFunctionObject *func,
8889
_PyUOpInstruction *trace, int trace_len, int curr_stackentries,
8990
_PyBloomFilter *dependencies);

Include/internal/pycore_tstate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ typedef struct _PyJitTracerTranslatorState {
5353

5454
typedef struct _PyJitTracerState {
5555
_PyUOpInstruction *code_buffer;
56+
struct _JitOptContext *opt_context;
5657
_PyJitTracerInitialState initial_state;
5758
_PyJitTracerPreviousState prev_state;
5859
_PyJitTracerTranslatorState translator_state;

Python/optimizer.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,6 +1484,7 @@ uop_optimize(
14841484
OPT_STAT_INC(traces_created);
14851485
if (!is_noopt) {
14861486
length = _Py_uop_analyze_and_optimize(
1487+
_tstate,
14871488
_tstate->jit_tracer_state.initial_state.func,
14881489
buffer,length,
14891490
curr_stackentries, dependencies);

Python/optimizer_analysis.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "pycore_opcode_metadata.h"
1919
#include "pycore_opcode_utils.h"
2020
#include "pycore_pystate.h" // _PyInterpreterState_GET()
21+
#include "pycore_tstate.h" // _PyThreadStateImpl
2122
#include "pycore_uop_metadata.h"
2223
#include "pycore_long.h"
2324
#include "pycore_interpframe.h" // _PyFrame_GetCode
@@ -334,6 +335,7 @@ _Py_opt_assert_within_stack_bounds(
334335
/* >0 (length) for success, 0 for not ready, clears all possible errors. */
335336
static int
336337
optimize_uops(
338+
_PyThreadStateImpl *tstate,
337339
PyFunctionObject *func,
338340
_PyUOpInstruction *trace,
339341
int trace_len,
@@ -343,8 +345,15 @@ optimize_uops(
343345
{
344346
assert(!PyErr_Occurred());
345347

346-
JitOptContext context;
347-
JitOptContext *ctx = &context;
348+
// Use thread-local JitOptContext to avoid stack overflow
349+
JitOptContext *ctx = tstate->jit_tracer_state.opt_context;
350+
if (ctx == NULL) {
351+
ctx = (JitOptContext *)PyMem_RawMalloc(sizeof(JitOptContext));
352+
if (ctx == NULL) {
353+
return 0;
354+
}
355+
tstate->jit_tracer_state.opt_context = ctx;
356+
}
348357
uint32_t opcode = UINT16_MAX;
349358

350359
// Make sure that watchers are set up
@@ -574,6 +583,7 @@ remove_unneeded_uops(_PyUOpInstruction *buffer, int buffer_size)
574583
// > 0 - length of optimized trace
575584
int
576585
_Py_uop_analyze_and_optimize(
586+
_PyThreadStateImpl *tstate,
577587
PyFunctionObject *func,
578588
_PyUOpInstruction *buffer,
579589
int length,
@@ -584,7 +594,7 @@ _Py_uop_analyze_and_optimize(
584594
OPT_STAT_INC(optimizer_attempts);
585595

586596
length = optimize_uops(
587-
func, buffer,
597+
tstate, func, buffer,
588598
length, curr_stacklen, dependencies);
589599

590600
if (length == 0) {

Python/pystate.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,6 +1554,7 @@ init_threadstate(_PyThreadStateImpl *_tstate,
15541554
"PYTHON_JIT_SIDE_EXIT_INITIAL_BACKOFF",
15551555
SIDE_EXIT_INITIAL_BACKOFF, 0, MAX_BACKOFF);
15561556
_tstate->jit_tracer_state.code_buffer = NULL;
1557+
_tstate->jit_tracer_state.opt_context = NULL;
15571558
#endif
15581559
tstate->delete_later = NULL;
15591560

@@ -1874,6 +1875,12 @@ tstate_delete_common(PyThreadState *tstate, int release_gil)
18741875
_PyObject_VirtualFree(_tstate->jit_tracer_state.code_buffer, UOP_BUFFER_SIZE);
18751876
_tstate->jit_tracer_state.code_buffer = NULL;
18761877
}
1878+
if (_tstate->jit_tracer_state.opt_context != NULL) {
1879+
// Ensure any resources in opt_context are cleaned up
1880+
_Py_uop_abstractcontext_fini(_tstate->jit_tracer_state.opt_context);
1881+
PyMem_RawFree(_tstate->jit_tracer_state.opt_context);
1882+
_tstate->jit_tracer_state.opt_context = NULL;
1883+
}
18771884
#endif
18781885

18791886
HEAD_UNLOCK(runtime);

0 commit comments

Comments
 (0)