Skip to content

Commit aaf6873

Browse files
Move to thread state
1 parent 3c80446 commit aaf6873

File tree

9 files changed

+187
-179
lines changed

9 files changed

+187
-179
lines changed

Include/internal/pycore_interp_structs.h

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ extern "C" {
1414
#include "pycore_structs.h" // PyHamtObject
1515
#include "pycore_tstate.h" // _PyThreadStateImpl
1616
#include "pycore_typedefs.h" // _PyRuntimeState
17-
#include "pycore_uop.h" // struct _PyUOpInstruction
18-
1917

2018
#define CODE_MAX_WATCHERS 8
2119
#define CONTEXT_MAX_WATCHERS 8
@@ -757,36 +755,6 @@ struct _Py_unique_id_pool {
757755

758756
typedef _Py_CODEUNIT *(*_PyJitEntryFuncPtr)(struct _PyExecutorObject *exec, _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate);
759757

760-
typedef struct _PyJitTracerInitialState {
761-
int stack_depth;
762-
int chain_depth;
763-
struct _PyExitData *exit;
764-
PyCodeObject *code; // Strong
765-
PyFunctionObject *func; // Strong
766-
_Py_CODEUNIT *start_instr;
767-
_Py_CODEUNIT *close_loop_instr;
768-
_Py_CODEUNIT *jump_backward_instr;
769-
} _PyJitTracerInitialState;
770-
771-
typedef struct _PyJitTracerPreviousState {
772-
bool dependencies_still_valid;
773-
bool instr_is_super;
774-
int code_max_size;
775-
int code_curr_size;
776-
int instr_oparg;
777-
int instr_stacklevel;
778-
int specialize_counter;
779-
_Py_CODEUNIT *instr;
780-
PyCodeObject *instr_code; // Strong
781-
_PyInterpreterFrame *instr_frame;
782-
_PyBloomFilter dependencies;
783-
} _PyJitTracerPreviousState;
784-
785-
typedef struct _PyJitTracerState {
786-
_PyUOpInstruction *code_buffer;
787-
_PyJitTracerInitialState initial_state;
788-
_PyJitTracerPreviousState prev_state;
789-
} _PyJitTracerState;
790758

791759
/* PyInterpreterState holds the global state for one of the runtime's
792760
interpreters. Typically the initial (main) interpreter is the only one.
@@ -963,7 +931,6 @@ struct _is {
963931
struct types_state types;
964932
struct callable_cache callable_cache;
965933
PyObject *common_consts[NUM_COMMON_CONSTANTS];
966-
_PyJitTracerState jit_state;
967934
bool jit;
968935
bool compiling;
969936
struct _PyExecutorObject *executor_list_head;

Include/internal/pycore_tstate.h

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ extern "C" {
1212
#include "pycore_freelist_state.h" // struct _Py_freelists
1313
#include "pycore_mimalloc.h" // struct _mimalloc_thread_state
1414
#include "pycore_qsbr.h" // struct qsbr
15-
15+
#include "pycore_uop.h" // struct _PyUOpInstruction
16+
#include "pycore_structs.h"
1617

1718
#ifdef Py_GIL_DISABLED
1819
struct _gc_thread_state {
@@ -21,6 +22,39 @@ struct _gc_thread_state {
2122
};
2223
#endif
2324

25+
#if _Py_TIER2
26+
typedef struct _PyJitTracerInitialState {
27+
int stack_depth;
28+
int chain_depth;
29+
struct _PyExitData *exit;
30+
PyCodeObject *code; // Strong
31+
PyFunctionObject *func; // Strong
32+
_Py_CODEUNIT *start_instr;
33+
_Py_CODEUNIT *close_loop_instr;
34+
_Py_CODEUNIT *jump_backward_instr;
35+
} _PyJitTracerInitialState;
36+
37+
typedef struct _PyJitTracerPreviousState {
38+
bool dependencies_still_valid;
39+
bool instr_is_super;
40+
int code_max_size;
41+
int code_curr_size;
42+
int instr_oparg;
43+
int instr_stacklevel;
44+
int specialize_counter;
45+
_Py_CODEUNIT *instr;
46+
PyCodeObject *instr_code; // Strong
47+
struct _PyInterpreterFrame *instr_frame;
48+
_PyBloomFilter dependencies;
49+
} _PyJitTracerPreviousState;
50+
51+
typedef struct _PyJitTracerState {
52+
_PyUOpInstruction *code_buffer;
53+
_PyJitTracerInitialState initial_state;
54+
_PyJitTracerPreviousState prev_state;
55+
} _PyJitTracerState;
56+
#endif
57+
2458
// Every PyThreadState is actually allocated as a _PyThreadStateImpl. The
2559
// PyThreadState fields are exposed as part of the C API, although most fields
2660
// are intended to be private. The _PyThreadStateImpl fields not exposed.
@@ -75,7 +109,9 @@ typedef struct _PyThreadStateImpl {
75109
#if defined(Py_REF_DEBUG) && defined(Py_GIL_DISABLED)
76110
Py_ssize_t reftotal; // this thread's total refcount operations
77111
#endif
78-
112+
#if _Py_TIER2
113+
_PyJitTracerState jit_state;
114+
#endif
79115
} _PyThreadStateImpl;
80116

81117
#ifdef __cplusplus

Python/bytecodes.c

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2970,13 +2970,6 @@ dummy_func(
29702970
if (!IS_JIT_TRACING() && backoff_counter_triggers(counter) &&
29712971
this_instr->op.code == JUMP_BACKWARD_JIT &&
29722972
next_instr->op.code != ENTER_EXECUTOR) {
2973-
if (tstate->interp->jit_state.code_buffer == NULL) {
2974-
tstate->interp->jit_state.code_buffer = (_PyUOpInstruction *)_PyObject_VirtualAlloc(UOP_BUFFER_SIZE);
2975-
if (tstate->interp->jit_state.code_buffer == NULL) {
2976-
// Don't error, just go to next instruction.
2977-
DISPATCH();
2978-
}
2979-
}
29802973
/* Back up over EXTENDED_ARGs so executor is inserted at the correct place */
29812974
_Py_CODEUNIT *insert_exec_at = this_instr;
29822975
while (oparg > 255) {
@@ -5673,24 +5666,25 @@ dummy_func(
56735666
}
56745667
// Super instructions. Instruction deopted. There's a mismatch in what the stack expects
56755668
// in the optimizer. So we have to reflect in the trace correctly.
5676-
if ((tstate->interp->jit_state.prev_state.instr->op.code == CALL_LIST_APPEND &&
5669+
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
5670+
if ((_tstate->jit_state.prev_state.instr->op.code == CALL_LIST_APPEND &&
56775671
opcode == POP_TOP) ||
5678-
(tstate->interp->jit_state.prev_state.instr->op.code == BINARY_OP_INPLACE_ADD_UNICODE &&
5672+
(_tstate->jit_state.prev_state.instr->op.code == BINARY_OP_INPLACE_ADD_UNICODE &&
56795673
opcode == STORE_FAST)) {
5680-
tstate->interp->jit_state.prev_state.instr_is_super = true;
5674+
_tstate->jit_state.prev_state.instr_is_super = true;
56815675
}
56825676
else {
5683-
tstate->interp->jit_state.prev_state.instr = next_instr;
5677+
_tstate->jit_state.prev_state.instr = next_instr;
56845678
}
5685-
tstate->interp->jit_state.prev_state.specialize_counter = 0;
5679+
_tstate->jit_state.prev_state.specialize_counter = 0;
56865680
PyCodeObject *prev_code = (PyCodeObject *)Py_NewRef(PyStackRef_AsPyObjectBorrow(frame->f_executable));
5687-
if (tstate->interp->jit_state.prev_state.instr_code != prev_code) {
5688-
Py_SETREF(tstate->interp->jit_state.prev_state.instr_code, prev_code);
5681+
if (_tstate->jit_state.prev_state.instr_code != prev_code) {
5682+
Py_SETREF(_tstate->jit_state.prev_state.instr_code, prev_code);
56895683
}
56905684

5691-
tstate->interp->jit_state.prev_state.instr_frame = frame;
5692-
tstate->interp->jit_state.prev_state.instr_oparg = oparg;
5693-
tstate->interp->jit_state.prev_state.instr_stacklevel = PyStackRef_IsNone(frame->f_executable) ? 2 : STACK_LEVEL();
5685+
_tstate->jit_state.prev_state.instr_frame = frame;
5686+
_tstate->jit_state.prev_state.instr_oparg = oparg;
5687+
_tstate->jit_state.prev_state.instr_stacklevel = PyStackRef_IsNone(frame->f_executable) ? 2 : STACK_LEVEL();
56945688
DISPATCH_GOTO_NON_TRACING();
56955689
#else
56965690
Py_FatalError("JIT label executed in non-jit build.");

Python/ceval.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,24 +1000,25 @@ bail_tracing_and_jit(PyThreadState *tstate, _PyInterpreterFrame *frame)
10001000
if (!_PyErr_Occurred(tstate) && !_is_sys_tracing) {
10011001
err = _PyOptimizer_Optimize(frame, tstate);
10021002
}
1003+
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
10031004
// Deal with backoffs
1004-
_PyExitData *exit = tstate->interp->jit_state.initial_state.exit;
1005+
_PyExitData *exit = _tstate->jit_state.initial_state.exit;
10051006
if (exit == NULL) {
10061007
// We hold a strong reference to the code object, so the instruction won't be freed.
10071008
if (err <= 0) {
1008-
_Py_BackoffCounter counter = tstate->interp->jit_state.initial_state.jump_backward_instr[1].counter;
1009-
tstate->interp->jit_state.initial_state.jump_backward_instr[1].counter = restart_backoff_counter(counter);
1009+
_Py_BackoffCounter counter = _tstate->jit_state.initial_state.jump_backward_instr[1].counter;
1010+
_tstate->jit_state.initial_state.jump_backward_instr[1].counter = restart_backoff_counter(counter);
10101011
}
10111012
else {
1012-
tstate->interp->jit_state.initial_state.jump_backward_instr[1].counter = initial_jump_backoff_counter();
1013+
_tstate->jit_state.initial_state.jump_backward_instr[1].counter = initial_jump_backoff_counter();
10131014
}
10141015
}
10151016
else {
10161017
// Likewise, we hold a strong reference to the executor containing this exit, so the exit is guaranteed
10171018
// to be valid to access.
10181019
if (err <= 0) {
10191020
// Some opcodes will forever be unchanged. Don't ever bother specializing for them ever again.
1020-
if (tstate->interp->jit_state.prev_state.instr->op.code == INTERPRETER_EXIT) {
1021+
if (_tstate->jit_state.prev_state.instr->op.code == INTERPRETER_EXIT) {
10211022
exit->temperature = initial_unreachable_backoff_counter();
10221023
}
10231024
else {

Python/ceval_macros.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@
134134

135135
#if (_Py_TAIL_CALL_INTERP || USE_COMPUTED_GOTOS) && _Py_TIER2
136136
# define IS_JIT_TRACING() (DISPATCH_TABLE_VAR == TRACING_DISPATCH_TABLE)
137-
# define IS_JIT_TRACING_MAKING_PROGRESS() (IS_JIT_TRACING() && tstate->interp->jit_state.prev_state.specialize_counter < MAX_SPECIALIZATION_TRIES)
137+
# define IS_JIT_TRACING_MAKING_PROGRESS() (IS_JIT_TRACING() && ((_PyThreadStateImpl *)tstate)->jit_state.prev_state.specialize_counter < MAX_SPECIALIZATION_TRIES)
138138
# define ENTER_TRACING() \
139139
DISPATCH_TABLE_VAR = TRACING_DISPATCH_TABLE;
140140
# define LEAVE_TRACING() \
@@ -402,7 +402,7 @@ do { \
402402
JUMP_TO_LABEL(error); \
403403
} \
404404
if (keep_tracing_bit) { \
405-
assert(tstate->interp->jit_state.prev_state.code_curr_size == 2); \
405+
assert(((_PyThreadStateImpl *)tstate)->jit_state.prev_state.code_curr_size == 2); \
406406
ENTER_TRACING(); \
407407
DISPATCH_NON_TRACING(); \
408408
} \

0 commit comments

Comments
 (0)