Skip to content

Commit 4aeb4ab

Browse files
massive refactoring of the struct
1 parent 46c079a commit 4aeb4ab

File tree

7 files changed

+49
-48
lines changed

7 files changed

+49
-48
lines changed

Include/internal/pycore_interp_structs.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -758,24 +758,26 @@ struct _Py_unique_id_pool {
758758
typedef _Py_CODEUNIT *(*_PyJitEntryFuncPtr)(struct _PyExecutorObject *exec, _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate);
759759

760760
typedef struct _PyJitTracerState {
761+
struct {
762+
int stack_depth;
763+
int chain_depth;
764+
struct _PyExitData *exit;
765+
PyCodeObject *code; // Strong
766+
PyFunctionObject *func; // Strong
767+
_Py_CODEUNIT *start_instr;
768+
_Py_CODEUNIT *close_loop_instr;
769+
_Py_CODEUNIT *jump_backward_instr;
770+
} initial_state;
761771
bool dependencies_still_valid;
762772
bool prev_instr_is_super;
763773
int code_max_size;
764774
int code_curr_size;
765-
int initial_stack_depth;
766-
int initial_chain_depth;
767775
int prev_instr_oparg;
768776
int prev_instr_stacklevel;
769777
int specialize_counter;
770778
_PyUOpInstruction *code_buffer;
771-
_Py_CODEUNIT *start_instr;
772-
_Py_CODEUNIT *close_loop_instr;
773-
_Py_CODEUNIT *jump_backward_instr;
774-
PyCodeObject *initial_code; // Strong
775-
PyFunctionObject *initial_func; // Strong
776779
_Py_CODEUNIT *prev_instr;
777780
PyCodeObject *prev_instr_code; // Strong
778-
struct _PyExitData *prev_exit;
779781
_PyInterpreterFrame *prev_instr_frame;
780782
_PyBloomFilter dependencies;
781783
} _PyJitTracerState;

Include/internal/pycore_optimizer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ PyAPI_FUNC(void) _Py_Executors_InvalidateCold(PyInterpreterState *interp);
9191
#define TRACE_STACK_SIZE 5
9292

9393
int _Py_uop_analyze_and_optimize(
94-
PyFunctionObject *initial_func,
94+
PyFunctionObject *func,
9595
_PyUOpInstruction *trace, int trace_len, int curr_stackentries,
9696
_PyBloomFilter *dependencies);
9797

Lib/test/test_ast/test_ast.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3047,8 +3047,8 @@ def test_source_segment_missing_info(self):
30473047

30483048
class NodeTransformerTests(ASTTestMixin, unittest.TestCase):
30493049
def assertASTTransformation(self, transformer_class,
3050-
initial_code, expected_code):
3051-
initial_ast = ast.parse(dedent(initial_code))
3050+
code, expected_code):
3051+
initial_ast = ast.parse(dedent(code))
30523052
expected_ast = ast.parse(dedent(expected_code))
30533053

30543054
transformer = transformer_class()

Python/ceval.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,15 +1001,15 @@ bail_tracing_and_jit(PyThreadState *tstate, _PyInterpreterFrame *frame)
10011001
err = _PyOptimizer_Optimize(frame, tstate);
10021002
}
10031003
// Deal with backoffs
1004-
_PyExitData *exit = tstate->interp->jit_state.prev_exit;
1004+
_PyExitData *exit = tstate->interp->jit_state.initial_state.exit;
10051005
if (exit == NULL) {
10061006
// We hold a strong reference to the code object, so the instruction won't be freed.
10071007
if (err <= 0) {
1008-
_Py_BackoffCounter counter = tstate->interp->jit_state.jump_backward_instr[1].counter;
1009-
tstate->interp->jit_state.jump_backward_instr[1].counter = restart_backoff_counter(counter);
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);
10101010
}
10111011
else {
1012-
tstate->interp->jit_state.jump_backward_instr[1].counter = initial_jump_backoff_counter();
1012+
tstate->interp->jit_state.initial_state.jump_backward_instr[1].counter = initial_jump_backoff_counter();
10131013
}
10141014
}
10151015
else {

Python/optimizer.c

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,13 @@ _PyOptimizer_Optimize(
119119
_PyInterpreterFrame *frame, PyThreadState *tstate)
120120
{
121121
PyInterpreterState *interp = _PyInterpreterState_GET();
122-
int chain_depth = tstate->interp->jit_state.initial_chain_depth;
122+
int chain_depth = tstate->interp->jit_state.initial_state.chain_depth;
123123
assert(interp->jit);
124124
assert(!interp->compiling);
125-
assert(tstate->interp->jit_state.initial_stack_depth >= 0);
125+
assert(tstate->interp->jit_state.initial_state.stack_depth >= 0);
126126
#ifndef Py_GIL_DISABLED
127127
// Trace got stomped on by another thread.
128-
if (tstate->interp->jit_state.initial_func == NULL) {
128+
if (tstate->interp->jit_state.initial_state.func == NULL) {
129129
return 0;
130130
}
131131
interp->compiling = true;
@@ -135,8 +135,8 @@ _PyOptimizer_Optimize(
135135
// this is true, since a deopt won't infinitely re-enter the executor:
136136
chain_depth %= MAX_CHAIN_DEPTH;
137137
bool progress_needed = chain_depth == 0;
138-
PyCodeObject *code = (PyCodeObject *)tstate->interp->jit_state.initial_code;
139-
_Py_CODEUNIT *start = tstate->interp->jit_state.start_instr;
138+
PyCodeObject *code = (PyCodeObject *)tstate->interp->jit_state.initial_state.code;
139+
_Py_CODEUNIT *start = tstate->interp->jit_state.initial_state.start_instr;
140140
if (progress_needed && !has_space_for_executor(code, start)) {
141141
interp->compiling = false;
142142
return 0;
@@ -171,9 +171,9 @@ _PyOptimizer_Optimize(
171171
else {
172172
executor->vm_data.code = NULL;
173173
}
174-
_PyExitData *prev_exit = tstate->interp->jit_state.prev_exit;
175-
if (prev_exit != NULL) {
176-
prev_exit->executor = executor;
174+
_PyExitData *exit = tstate->interp->jit_state.initial_state.exit;
175+
if (exit != NULL) {
176+
exit->executor = executor;
177177
}
178178
executor->vm_data.chain_depth = chain_depth;
179179
assert(executor->vm_data.valid);
@@ -569,7 +569,7 @@ _PyJit_translate_single_bytecode_to_trace(
569569
if (old_code == NULL) {
570570
return 0;
571571
}
572-
bool progress_needed = (tstate->interp->jit_state.initial_chain_depth % MAX_CHAIN_DEPTH) == 0;;
572+
bool progress_needed = (tstate->interp->jit_state.initial_state.chain_depth % MAX_CHAIN_DEPTH) == 0;
573573
_PyBloomFilter *dependencies = &tstate->interp->jit_state.dependencies;
574574
_Py_BloomFilter_Add(dependencies, old_code);
575575
int trace_length = tstate->interp->jit_state.code_curr_size;
@@ -748,8 +748,8 @@ _PyJit_translate_single_bytecode_to_trace(
748748
_Py_FALLTHROUGH;
749749
case JUMP_BACKWARD_NO_INTERRUPT:
750750
{
751-
if ((next_instr != tstate->interp->jit_state.close_loop_instr) &&
752-
(next_instr != tstate->interp->jit_state.start_instr) &&
751+
if ((next_instr != tstate->interp->jit_state.initial_state.close_loop_instr) &&
752+
(next_instr != tstate->interp->jit_state.initial_state.start_instr) &&
753753
tstate->interp->jit_state.code_curr_size > 5 &&
754754
// These are coroutines, and we want to unroll those usually.
755755
opcode != JUMP_BACKWARD_NO_INTERRUPT) {
@@ -760,7 +760,8 @@ _PyJit_translate_single_bytecode_to_trace(
760760
OPT_STAT_INC(inner_loop);
761761
ADD_TO_TRACE(_EXIT_TRACE, 0, 0, target);
762762
trace[trace_length-1].operand1 = true; // is_control_flow
763-
DPRINTF(2, "JUMP_BACKWARD not to top ends trace %p %p %p\n", next_instr, tstate->interp->jit_state.close_loop_instr, tstate->interp->jit_state.start_instr);
763+
DPRINTF(2, "JUMP_BACKWARD not to top ends trace %p %p %p\n", next_instr,
764+
tstate->interp->jit_state.initial_state.close_loop_instr, tstate->interp->jit_state.initial_state.start_instr);
764765
goto done;
765766
}
766767
break;
@@ -915,7 +916,8 @@ _PyJit_translate_single_bytecode_to_trace(
915916
}
916917
}
917918
// Loop back to the start
918-
int is_first_instr = tstate->interp->jit_state.close_loop_instr == next_instr || tstate->interp->jit_state.start_instr == next_instr;
919+
int is_first_instr = tstate->interp->jit_state.initial_state.close_loop_instr == next_instr ||
920+
tstate->interp->jit_state.initial_state.start_instr == next_instr;
919921
if (is_first_instr && tstate->interp->jit_state.code_curr_size > 5) {
920922
if (needs_guard_ip) {
921923
ADD_TO_TRACE(_SET_IP, 0, (uintptr_t)next_instr, 0);
@@ -985,13 +987,13 @@ _PyJit_TryInitializeTracing(
985987
tstate->interp->jit_state.code_curr_size = 2;
986988

987989
tstate->interp->jit_state.code_max_size = UOP_MAX_TRACE_LENGTH;
988-
tstate->interp->jit_state.start_instr = start_instr;
989-
tstate->interp->jit_state.close_loop_instr = close_loop_instr;
990-
tstate->interp->jit_state.initial_code = (PyCodeObject *)Py_NewRef(code);
991-
tstate->interp->jit_state.initial_func = (PyFunctionObject *)Py_XNewRef(PyStackRef_AsPyObjectBorrow(frame->f_funcobj));
992-
tstate->interp->jit_state.prev_exit = exit;
993-
tstate->interp->jit_state.initial_stack_depth = curr_stackdepth;
994-
tstate->interp->jit_state.initial_chain_depth = chain_depth;
990+
tstate->interp->jit_state.initial_state.start_instr = start_instr;
991+
tstate->interp->jit_state.initial_state.close_loop_instr = close_loop_instr;
992+
tstate->interp->jit_state.initial_state.code = (PyCodeObject *)Py_NewRef(code);
993+
tstate->interp->jit_state.initial_state.func = (PyFunctionObject *)Py_XNewRef(PyStackRef_AsPyObjectBorrow(frame->f_funcobj));
994+
tstate->interp->jit_state.initial_state.exit = exit;
995+
tstate->interp->jit_state.initial_state.stack_depth = curr_stackdepth;
996+
tstate->interp->jit_state.initial_state.chain_depth = chain_depth;
995997
tstate->interp->jit_state.prev_instr_frame = frame;
996998
tstate->interp->jit_state.dependencies_still_valid = true;
997999
tstate->interp->jit_state.specialize_counter = 0;
@@ -1002,7 +1004,7 @@ _PyJit_TryInitializeTracing(
10021004
tstate->interp->jit_state.prev_instr_stacklevel = curr_stackdepth;
10031005
tstate->interp->jit_state.prev_instr_is_super = false;
10041006
assert(curr_instr->op.code == JUMP_BACKWARD_JIT || (exit != NULL));
1005-
tstate->interp->jit_state.jump_backward_instr = curr_instr;
1007+
tstate->interp->jit_state.initial_state.jump_backward_instr = curr_instr;
10061008
assert(curr_instr->op.code == JUMP_BACKWARD_JIT || (exit != NULL));
10071009
_Py_BloomFilter_Init(&tstate->interp->jit_state.dependencies);
10081010
return 1;
@@ -1011,8 +1013,8 @@ _PyJit_TryInitializeTracing(
10111013
void
10121014
_PyJit_FinalizeTracing(PyThreadState *tstate)
10131015
{
1014-
Py_CLEAR(tstate->interp->jit_state.initial_code);
1015-
Py_CLEAR(tstate->interp->jit_state.initial_func);
1016+
Py_CLEAR(tstate->interp->jit_state.initial_state.code);
1017+
Py_CLEAR(tstate->interp->jit_state.initial_state.func);
10161018
Py_CLEAR(tstate->interp->jit_state.prev_instr_code);
10171019
tstate->interp->jit_state.code_curr_size = 2;
10181020
tstate->interp->jit_state.code_max_size = UOP_MAX_TRACE_LENGTH - 1;
@@ -1335,7 +1337,7 @@ uop_optimize(
13351337
// It is the optimizer's responsibility to add the dependencies it requires on its own.
13361338
_PyBloomFilter new_dependencies;
13371339
_Py_BloomFilter_Init(&new_dependencies);
1338-
_Py_BloomFilter_Add(&new_dependencies, tstate->interp->jit_state.initial_code);
1340+
_Py_BloomFilter_Add(&new_dependencies, tstate->interp->jit_state.initial_state.code);
13391341
PyInterpreterState *interp = _PyInterpreterState_GET();
13401342
_PyUOpInstruction *buffer = interp->jit_state.code_buffer;
13411343
OPT_STAT_INC(attempts);
@@ -1344,7 +1346,7 @@ uop_optimize(
13441346
if (env_var == NULL || *env_var == '\0' || *env_var > '0') {
13451347
is_noopt = false;
13461348
}
1347-
int curr_stackentries = tstate->interp->jit_state.initial_stack_depth;
1349+
int curr_stackentries = tstate->interp->jit_state.initial_state.stack_depth;
13481350
int length = interp->jit_state.code_curr_size;
13491351
// Trace too short, don't bother.
13501352
if (length <= 5) {
@@ -1354,7 +1356,7 @@ uop_optimize(
13541356
assert(length < UOP_MAX_TRACE_LENGTH);
13551357
OPT_STAT_INC(traces_created);
13561358
if (!is_noopt) {
1357-
length = _Py_uop_analyze_and_optimize(tstate->interp->jit_state.initial_func, buffer,
1359+
length = _Py_uop_analyze_and_optimize(tstate->interp->jit_state.initial_state.func, buffer,
13581360
length,
13591361
curr_stackentries, &new_dependencies);
13601362
if (length <= 0) {
@@ -1379,7 +1381,8 @@ uop_optimize(
13791381
OPT_HIST(effective_trace_length(buffer, length), optimized_trace_length_hist);
13801382
length = prepare_for_execution(buffer, length);
13811383
assert(length <= UOP_MAX_TRACE_LENGTH);
1382-
_PyExecutorObject *executor = make_executor_from_uops(buffer, length, &new_dependencies, tstate->interp->jit_state.initial_chain_depth);
1384+
_PyExecutorObject *executor = make_executor_from_uops(
1385+
buffer, length, &new_dependencies, tstate->interp->jit_state.initial_state.chain_depth);
13831386
if (executor == NULL) {
13841387
return -1;
13851388
}

Python/optimizer_analysis.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ remove_unneeded_uops(_PyUOpInstruction *buffer, int buffer_size)
511511
// > 0 - length of optimized trace
512512
int
513513
_Py_uop_analyze_and_optimize(
514-
PyFunctionObject *initial_func,
514+
PyFunctionObject *func,
515515
_PyUOpInstruction *buffer,
516516
int length,
517517
int curr_stacklen,
@@ -521,7 +521,7 @@ _Py_uop_analyze_and_optimize(
521521
OPT_STAT_INC(optimizer_attempts);
522522

523523
length = optimize_uops(
524-
initial_func, buffer,
524+
func, buffer,
525525
length, curr_stacklen, dependencies);
526526

527527
if (length == 0) {

Python/pystate.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -547,10 +547,6 @@ init_interpreter(PyInterpreterState *interp,
547547

548548
#ifdef _Py_TIER2
549549
interp->jit_state.code_buffer = NULL;
550-
interp->jit_state.initial_stack_depth = -1;
551-
interp->jit_state.initial_chain_depth = -1;
552-
interp->jit_state.initial_code = NULL;
553-
interp->jit_state.initial_func = NULL;
554550
#endif
555551
llist_init(&interp->mem_free_queue.head);
556552
llist_init(&interp->asyncio_tasks_head);

0 commit comments

Comments
 (0)