diff --git a/Include/cpython/code.h b/Include/cpython/code.h index 1be47e42ed62bfb..db98cc5a9274bbf 100644 --- a/Include/cpython/code.h +++ b/Include/cpython/code.h @@ -15,12 +15,7 @@ typedef struct { PyObject *_co_freevars; } _PyCoCached; -typedef struct { - int size; - int capacity; - struct _PyExecutorObject *executors[1]; -} _PyExecutorArray; - +typedef struct _PyExecutorArray _PyExecutorArray; #ifdef Py_GIL_DISABLED diff --git a/Include/internal/pycore_interp_structs.h b/Include/internal/pycore_interp_structs.h index d3efac906aeb933..0ffba89be755d48 100644 --- a/Include/internal/pycore_interp_structs.h +++ b/Include/internal/pycore_interp_structs.h @@ -834,6 +834,8 @@ struct _Py_unique_id_pool { #endif +struct _PyExecutorObject; + typedef _Py_CODEUNIT *(*_PyJitEntryFuncPtr)(struct _PyExecutorObject *exec, _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate); #define _PyInterpreterGuard_GUARDS_NOT_ALLOWED UINTPTR_MAX diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h index 3d60638649dcb5a..ad4d2edffa138d9 100644 --- a/Include/internal/pycore_optimizer.h +++ b/Include/internal/pycore_optimizer.h @@ -180,6 +180,8 @@ typedef struct { PyCodeObject *code; // Weak (NULL if no corresponding ENTER_EXECUTOR). } _PyVMData; +typedef struct _PyExecutorHandle _PyExecutorHandle; + typedef struct _PyExitData { uint32_t target; uint16_t index:12; @@ -187,7 +189,7 @@ typedef struct _PyExitData { uint16_t is_dynamic:1; uint16_t is_control_flow:1; _Py_BackoffCounter temperature; - struct _PyExecutorObject *executor; + _PyExecutorHandle *executor; } _PyExitData; typedef struct _PyExecutorObject { @@ -202,12 +204,48 @@ typedef struct _PyExecutorObject { _PyExitData exits[1]; } _PyExecutorObject; +static inline _PyExecutorObject * +_PyExecutor_FromHandle(_PyExecutorHandle *executor) +{ + return (_PyExecutorObject *)executor; +} + +static inline _PyExecutorHandle * +_PyExecutor_AsHandle(_PyExecutorObject *executor) +{ + return (_PyExecutorHandle *)executor; +} + +typedef struct _PyExecutorArrayInternal { + int size; + int capacity; + _PyExecutorObject *executors[1]; +} _PyExecutorArrayInternal; + +static inline _PyExecutorArrayInternal * +_PyExecutorArray_CAST(_PyExecutorArray *executors) +{ + return (_PyExecutorArrayInternal *)executors; +} + +static inline int +_PyExecutorArray_SIZE(_PyExecutorArray *executors) +{ + return _PyExecutorArray_CAST(executors)->size; +} + +static inline _PyExecutorObject ** +_PyExecutorArray_EXECUTORS(_PyExecutorArray *executors) +{ + return _PyExecutorArray_CAST(executors)->executors; +} + // Export for '_opcode' shared extension (JIT compiler). -PyAPI_FUNC(_PyExecutorObject*) _Py_GetExecutor(PyCodeObject *code, int offset); +PyAPI_FUNC(_PyExecutorHandle*) _Py_GetExecutor(PyCodeObject *code, int offset); int _Py_ExecutorInit(_PyExecutorObject *, const _PyBloomFilter *); void _Py_ExecutorDetach(_PyExecutorObject *); -PyAPI_FUNC(void) _Py_Executor_DependsOn(_PyExecutorObject *executor, void *obj); +PyAPI_FUNC(void) _Py_Executor_DependsOn(_PyExecutorHandle *executor, void *obj); /* We use a bloomfilter with k = 6, m = 256 * The choice of k and the following constants @@ -519,7 +557,7 @@ PyAPI_FUNC(int) _PyJit_TryInitializeTracing(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *curr_instr, _Py_CODEUNIT *start_instr, _Py_CODEUNIT *close_loop_instr, _PyStackRef *stack_pointer, int chain_depth, _PyExitData *exit, - int oparg, _PyExecutorObject *current_executor); + int oparg, _PyExecutorHandle *current_executor); PyAPI_FUNC(void) _PyJit_FinalizeTracing(PyThreadState *tstate, int err); PyAPI_FUNC(bool) _PyJit_EnterExecutorShouldStopTracing(int og_opcode); diff --git a/Modules/_opcode.c b/Modules/_opcode.c index 2a34559fd1f4378..b26d3727d7e6ade 100644 --- a/Modules/_opcode.c +++ b/Modules/_opcode.c @@ -390,7 +390,8 @@ _opcode_get_executor_impl(PyObject *module, PyObject *code, int offset) return NULL; } #ifdef _Py_TIER2 - return (PyObject *)_Py_GetExecutor((PyCodeObject *)code, offset); + return (PyObject *)_PyExecutor_FromHandle( + _Py_GetExecutor((PyCodeObject *)code, offset)); #else PyErr_Format(PyExc_RuntimeError, "Executors are not available in this build"); diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index ea3ad2b81c28668..e7be76e97ba5688 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -1788,7 +1788,7 @@ add_executor_dependency(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "OO", &exec, &obj)) { return NULL; } - _Py_Executor_DependsOn((_PyExecutorObject *)exec, obj); + _Py_Executor_DependsOn(_PyExecutor_AsHandle((_PyExecutorObject *)exec), obj); Py_RETURN_NONE; } @@ -1821,7 +1821,7 @@ get_exit_executor(PyObject *self, PyObject *arg) return NULL; } _PyExitData *exit = (_PyExitData *)ptr; - return Py_NewRef(exit->executor); + return Py_NewRef(_PyExecutor_FromHandle(exit->executor)); } #endif diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index a17648a33d4fe4a..95a7cee9ea8fadb 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -6154,7 +6154,7 @@ opcode = ENTER_EXECUTOR; #ifdef _Py_TIER2 PyCodeObject *code = _PyFrame_GetCode(frame); - _PyExecutorObject *executor = code->co_executors->executors[oparg & 255]; + _PyExecutorObject *executor = ((_PyExecutorArrayInternal *)code->co_executors)->executors[oparg & 255]; if (IS_JIT_TRACING()) { int og_opcode = executor->vm_data.opcode; int og_oparg = (oparg & ~255) | executor->vm_data.oparg; diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 03036020b1cb1ae..f0b8a4bf21a7552 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -2180,10 +2180,10 @@ static void clear_executors(PyCodeObject *co) { assert(co->co_executors); - for (int i = 0; i < co->co_executors->size; i++) { - if (co->co_executors->executors[i]) { - _Py_ExecutorDetach(co->co_executors->executors[i]); - assert(co->co_executors->executors[i] == NULL); + for (int i = 0; i < _PyExecutorArray_SIZE(co->co_executors); i++) { + if (_PyExecutorArray_EXECUTORS(co->co_executors)[i]) { + _Py_ExecutorDetach(_PyExecutorArray_EXECUTORS(co->co_executors)[i]); + assert(_PyExecutorArray_EXECUTORS(co->co_executors)[i] == NULL); } } PyMem_Free(co->co_executors); diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 4d7b338e2dbd4c3..e6de91778dca5b0 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -3585,7 +3585,7 @@ dummy_func( tier1 inst(ENTER_EXECUTOR, (--)) { #ifdef _Py_TIER2 PyCodeObject *code = _PyFrame_GetCode(frame); - _PyExecutorObject *executor = code->co_executors->executors[oparg & 255]; + _PyExecutorObject *executor = ((_PyExecutorArrayInternal *)code->co_executors)->executors[oparg & 255]; if (IS_JIT_TRACING()) { int og_opcode = executor->vm_data.opcode; int og_oparg = (oparg & ~255) | executor->vm_data.oparg; @@ -6151,7 +6151,7 @@ dummy_func( } #endif tstate->jit_exit = exit; - TIER2_TO_TIER2(exit->executor); + TIER2_TO_TIER2((_PyExecutorObject *)exit->executor); } tier2 op(_DYNAMIC_EXIT, (exit_p/4 --)) { @@ -6196,10 +6196,10 @@ dummy_func( #ifndef _Py_JIT assert(current_executor == (_PyExecutorObject*)executor); #endif - assert(tstate->jit_exit == NULL || tstate->jit_exit->executor == current_executor); + assert(tstate->jit_exit == NULL || (_PyExecutorObject *)tstate->jit_exit->executor == current_executor); tstate->current_executor = (PyObject *)current_executor; if (!current_executor->vm_data.valid) { - assert(tstate->jit_exit->executor == current_executor); + assert((_PyExecutorObject *)tstate->jit_exit->executor == current_executor); assert(tstate->current_executor == executor); _PyExecutor_ClearExit(tstate->jit_exit); DEOPT_IF(true); @@ -6261,11 +6261,11 @@ dummy_func( _PyExecutorObject *executor; if (target->op.code == ENTER_EXECUTOR) { PyCodeObject *code = _PyFrame_GetCode(frame); - executor = code->co_executors->executors[target->op.arg]; + executor = ((_PyExecutorArrayInternal *)code->co_executors)->executors[target->op.arg]; Py_INCREF(executor); assert(tstate->jit_exit == exit); - exit->executor = executor; - TIER2_TO_TIER2(exit->executor); + exit->executor = (_PyExecutorHandle *)executor; + TIER2_TO_TIER2((_PyExecutorObject *)exit->executor); } else { SYNC_SP(); @@ -6281,7 +6281,7 @@ dummy_func( // Note: it's safe to use target->op.arg here instead of the oparg given by EXTENDED_ARG. // The invariant in the optimizer is the deopt target always points back to the first EXTENDED_ARG. // So setting it to anything else is wrong. - int succ = _PyJit_TryInitializeTracing(tstate, frame, target, target, target, stack_pointer, chain_depth, exit, target->op.arg, previous_executor); + int succ = _PyJit_TryInitializeTracing(tstate, frame, target, target, target, stack_pointer, chain_depth, exit, target->op.arg, (_PyExecutorHandle *)previous_executor); exit->temperature = restart_backoff_counter(exit->temperature); if (succ) { GOTO_TIER_ONE_CONTINUE_TRACING(target); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index e45bbd7cceb295f..ce5da26c1c23f78 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -22707,7 +22707,7 @@ #endif tstate->jit_exit = exit; SET_CURRENT_CACHED_VALUES(0); - TIER2_TO_TIER2(exit->executor); + TIER2_TO_TIER2((_PyExecutorObject *)exit->executor); } case _EXIT_TRACE_r10: { @@ -22748,7 +22748,7 @@ stack_pointer[0] = _stack_item_0; stack_pointer += 1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - TIER2_TO_TIER2(exit->executor); + TIER2_TO_TIER2((_PyExecutorObject *)exit->executor); } case _EXIT_TRACE_r20: { @@ -22792,7 +22792,7 @@ stack_pointer[1] = _stack_item_1; stack_pointer += 2; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - TIER2_TO_TIER2(exit->executor); + TIER2_TO_TIER2((_PyExecutorObject *)exit->executor); } case _EXIT_TRACE_r30: { @@ -22839,7 +22839,7 @@ stack_pointer[2] = _stack_item_2; stack_pointer += 3; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - TIER2_TO_TIER2(exit->executor); + TIER2_TO_TIER2((_PyExecutorObject *)exit->executor); } case _DYNAMIC_EXIT_r00: { @@ -23252,10 +23252,10 @@ #ifndef _Py_JIT assert(current_executor == (_PyExecutorObject*)executor); #endif - assert(tstate->jit_exit == NULL || tstate->jit_exit->executor == current_executor); + assert(tstate->jit_exit == NULL || (_PyExecutorObject *)tstate->jit_exit->executor == current_executor); tstate->current_executor = (PyObject *)current_executor; if (!current_executor->vm_data.valid) { - assert(tstate->jit_exit->executor == current_executor); + assert((_PyExecutorObject *)tstate->jit_exit->executor == current_executor); assert(tstate->current_executor == executor); _PyFrame_SetStackPointer(frame, stack_pointer); _PyFrame_StackPointerValidate(frame); @@ -23788,12 +23788,12 @@ _PyExecutorObject *executor; if (target->op.code == ENTER_EXECUTOR) { PyCodeObject *code = _PyFrame_GetCode(frame); - executor = code->co_executors->executors[target->op.arg]; + executor = ((_PyExecutorArrayInternal *)code->co_executors)->executors[target->op.arg]; Py_INCREF(executor); assert(tstate->jit_exit == exit); - exit->executor = executor; + exit->executor = (_PyExecutorHandle *)executor; SET_CURRENT_CACHED_VALUES(0); - TIER2_TO_TIER2(exit->executor); + TIER2_TO_TIER2((_PyExecutorObject *)exit->executor); } else { if (!backoff_counter_triggers(temperature)) { @@ -23804,7 +23804,7 @@ _PyExecutorObject *previous_executor = _PyExecutor_FromExit(exit); assert(tstate->current_executor == (PyObject *)previous_executor); int chain_depth = previous_executor->vm_data.chain_depth + !exit->is_control_flow; - int succ = _PyJit_TryInitializeTracing(tstate, frame, target, target, target, stack_pointer, chain_depth, exit, target->op.arg, previous_executor); + int succ = _PyJit_TryInitializeTracing(tstate, frame, target, target, target, stack_pointer, chain_depth, exit, target->op.arg, (_PyExecutorHandle *)previous_executor); exit->temperature = restart_backoff_counter(exit->temperature); if (succ) { GOTO_TIER_ONE_CONTINUE_TRACING(target); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 6178dc70c1b80e7..af416ff14911b49 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -6154,7 +6154,7 @@ opcode = ENTER_EXECUTOR; #ifdef _Py_TIER2 PyCodeObject *code = _PyFrame_GetCode(frame); - _PyExecutorObject *executor = code->co_executors->executors[oparg & 255]; + _PyExecutorObject *executor = ((_PyExecutorArrayInternal *)code->co_executors)->executors[oparg & 255]; if (IS_JIT_TRACING()) { int og_opcode = executor->vm_data.opcode; int og_oparg = (oparg & ~255) | executor->vm_data.oparg; diff --git a/Python/instrumentation.c b/Python/instrumentation.c index 0af2070b5cd983a..7bb25e57b969e94 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -647,7 +647,7 @@ _Py_GetBaseCodeUnit(PyCodeObject *code, int i) return inst; } if (opcode == ENTER_EXECUTOR) { - _PyExecutorObject *exec = code->co_executors->executors[inst.op.arg]; + _PyExecutorObject *exec = _PyExecutorArray_EXECUTORS(code->co_executors)[inst.op.arg]; opcode = _PyOpcode_Deopt[exec->vm_data.opcode]; inst.op.code = opcode; inst.op.arg = exec->vm_data.oparg; diff --git a/Python/optimizer.c b/Python/optimizer.c index c9f6ebdb62f07b2..bf3c7a771c2a2b9 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -1,5 +1,7 @@ #include "Python.h" +struct _PyExecutorObject; + #ifdef _Py_TIER2 #include "opcode.h" @@ -53,7 +55,7 @@ has_space_for_executor(PyCodeObject *code, _Py_CODEUNIT *instr) if (code->co_executors == NULL) { return true; } - return code->co_executors->size < MAX_EXECUTORS_SIZE; + return _PyExecutorArray_SIZE(code->co_executors) < MAX_EXECUTORS_SIZE; } static int32_t @@ -62,7 +64,7 @@ get_index_for_executor(PyCodeObject *code, _Py_CODEUNIT *instr) if (instr->op.code == ENTER_EXECUTOR) { return instr->op.arg; } - _PyExecutorArray *old = code->co_executors; + _PyExecutorArrayInternal *old = _PyExecutorArray_CAST(code->co_executors); int size = 0; int capacity = 0; if (old != NULL) { @@ -74,18 +76,18 @@ get_index_for_executor(PyCodeObject *code, _Py_CODEUNIT *instr) if (size == capacity) { /* Array is full. Grow array */ int new_capacity = capacity ? capacity * 2 : 4; - _PyExecutorArray *new = PyMem_Realloc( + _PyExecutorArrayInternal *new = PyMem_Realloc( old, - offsetof(_PyExecutorArray, executors) + + offsetof(_PyExecutorArrayInternal, executors) + new_capacity * sizeof(_PyExecutorObject *)); if (new == NULL) { return -1; } new->capacity = new_capacity; new->size = size; - code->co_executors = new; + code->co_executors = (_PyExecutorArray *)new; } - assert(size < code->co_executors->capacity); + assert(size < _PyExecutorArray_CAST(code->co_executors)->capacity); return size; } @@ -95,18 +97,18 @@ insert_executor(PyCodeObject *code, _Py_CODEUNIT *instr, int index, _PyExecutorO Py_INCREF(executor); if (instr->op.code == ENTER_EXECUTOR) { assert(index == instr->op.arg); - _Py_ExecutorDetach(code->co_executors->executors[index]); + _Py_ExecutorDetach(_PyExecutorArray_EXECUTORS(code->co_executors)[index]); } else { - assert(code->co_executors->size == index); - assert(code->co_executors->capacity > index); - code->co_executors->size++; + assert(_PyExecutorArray_SIZE(code->co_executors) == index); + assert(_PyExecutorArray_CAST(code->co_executors)->capacity > index); + _PyExecutorArray_CAST(code->co_executors)->size++; } executor->vm_data.opcode = instr->op.code; executor->vm_data.oparg = instr->op.arg; executor->vm_data.code = code; executor->vm_data.index = (int)(instr - _PyCode_CODE(code)); - code->co_executors->executors[index] = executor; + _PyExecutorArray_EXECUTORS(code->co_executors)[index] = executor; assert(index < MAX_EXECUTORS_SIZE); instr->op.code = ENTER_EXECUTOR; instr->op.arg = index; @@ -188,7 +190,7 @@ _PyOptimizer_Optimize( assert(executor->vm_data.valid); _PyExitData *exit = _tstate->jit_tracer_state->initial_state.exit; if (exit != NULL && !progress_needed) { - exit->executor = executor; + exit->executor = _PyExecutor_AsHandle(executor); } else { // An executor inserted into the code object now has a strong reference @@ -209,7 +211,7 @@ get_executor_lock_held(PyCodeObject *code, int offset) for (int i = 0 ; i < code_len;) { if (_PyCode_CODE(code)[i].op.code == ENTER_EXECUTOR && i*2 == offset) { int oparg = _PyCode_CODE(code)[i].op.arg; - _PyExecutorObject *res = code->co_executors->executors[oparg]; + _PyExecutorObject *res = _PyExecutorArray_EXECUTORS(code->co_executors)[oparg]; Py_INCREF(res); return res; } @@ -219,14 +221,14 @@ get_executor_lock_held(PyCodeObject *code, int offset) return NULL; } -_PyExecutorObject * +_PyExecutorHandle * _Py_GetExecutor(PyCodeObject *code, int offset) { _PyExecutorObject *executor; Py_BEGIN_CRITICAL_SECTION(code); executor = get_executor_lock_held(code, offset); Py_END_CRITICAL_SECTION(); - return executor; + return _PyExecutor_AsHandle(executor); } static PyObject * @@ -270,8 +272,8 @@ executor_clear_exits(_PyExecutorObject *executor) for (uint32_t i = 0; i < executor->exit_count; i++) { _PyExitData *exit = &executor->exits[i]; exit->temperature = initial_unreachable_backoff_counter(); - _PyExecutorObject *old = executor->exits[i].executor; - exit->executor = exit->is_dynamic ? cold_dynamic : cold; + _PyExecutorObject *old = _PyExecutor_FromHandle(executor->exits[i].executor); + exit->executor = _PyExecutor_AsHandle(exit->is_dynamic ? cold_dynamic : cold); Py_DECREF(old); } } @@ -706,7 +708,7 @@ _PyJit_translate_single_bytecode_to_trace( } if (opcode == ENTER_EXECUTOR) { - _PyExecutorObject *executor = old_code->co_executors->executors[oparg & 255]; + _PyExecutorObject *executor = _PyExecutorArray_EXECUTORS(old_code->co_executors)[oparg & 255]; opcode = executor->vm_data.opcode; oparg = (oparg & ~255) | executor->vm_data.oparg; } @@ -1117,8 +1119,9 @@ Py_NO_INLINE int _PyJit_TryInitializeTracing( PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *curr_instr, _Py_CODEUNIT *start_instr, _Py_CODEUNIT *close_loop_instr, _PyStackRef *stack_pointer, int chain_depth, - _PyExitData *exit, int oparg, _PyExecutorObject *current_executor) + _PyExitData *exit, int oparg, _PyExecutorHandle *current_executor_handle) { + _PyExecutorObject *current_executor = _PyExecutor_FromHandle(current_executor_handle); _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; if (_tstate->jit_tracer_state == NULL) { _tstate->jit_tracer_state = (_PyJitTracerState *)_PyObject_VirtualAlloc(sizeof(_PyJitTracerState)); @@ -1532,7 +1535,7 @@ make_executor_from_uops(_PyThreadStateImpl *tstate, _PyUOpInstruction *buffer, i _PyExitData *exit = &executor->exits[next_exit]; exit->target = buffer[i].target; dest->operand0 = (uint64_t)exit; - exit->executor = base_opcode == _EXIT_TRACE ? cold : cold_dynamic; + exit->executor = _PyExecutor_AsHandle(base_opcode == _EXIT_TRACE ? cold : cold_dynamic); exit->is_dynamic = (char)(base_opcode == _DYNAMIC_EXIT); exit->is_control_flow = (char)buffer[i].operand1; next_exit--; @@ -1838,12 +1841,12 @@ _PyExecutor_ClearExit(_PyExitData *exit) if (exit == NULL) { return; } - _PyExecutorObject *old = exit->executor; + _PyExecutorObject *old = _PyExecutor_FromHandle(exit->executor); if (exit->is_dynamic) { - exit->executor = _PyExecutor_GetColdDynamicExecutor(); + exit->executor = _PyExecutor_AsHandle(_PyExecutor_GetColdDynamicExecutor()); } else { - exit->executor = _PyExecutor_GetColdExecutor(); + exit->executor = _PyExecutor_AsHandle(_PyExecutor_GetColdExecutor()); } Py_DECREF(old); } @@ -1860,11 +1863,11 @@ _Py_ExecutorDetach(_PyExecutorObject *executor) _Py_CODEUNIT *instruction = &_PyCode_CODE(code)[executor->vm_data.index]; assert(instruction->op.code == ENTER_EXECUTOR); int index = instruction->op.arg; - assert(code->co_executors->executors[index] == executor); + assert(_PyExecutorArray_EXECUTORS(code->co_executors)[index] == executor); instruction->op.code = _PyOpcode_Deopt[executor->vm_data.opcode]; instruction->op.arg = executor->vm_data.oparg; executor->vm_data.code = NULL; - code->co_executors->executors[index] = NULL; + _PyExecutorArray_EXECUTORS(code->co_executors)[index] = NULL; Py_DECREF(executor); } @@ -1894,8 +1897,9 @@ executor_clear(PyObject *op) } void -_Py_Executor_DependsOn(_PyExecutorObject *executor, void *obj) +_Py_Executor_DependsOn(_PyExecutorHandle *executor_handle, void *obj) { + _PyExecutorObject *executor = _PyExecutor_FromHandle(executor_handle); assert(executor->vm_data.valid); PyInterpreterState *interp = _PyInterpreterState_GET(); int32_t idx = executor->vm_data.bloom_array_idx; @@ -2053,7 +2057,7 @@ find_line_number(PyCodeObject *code, _PyExecutorObject *executor) _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; int opcode = instr->op.code; if (opcode == ENTER_EXECUTOR) { - _PyExecutorObject *exec = code->co_executors->executors[instr->op.arg]; + _PyExecutorObject *exec = _PyExecutorArray_EXECUTORS(code->co_executors)[instr->op.arg]; if (exec == executor) { return PyCode_Addr2Line(code, i*2); } @@ -2201,7 +2205,7 @@ executor_to_gv(_PyExecutorObject *executor, FILE *out) exit = (_PyExitData *)exit_inst->operand0; } if (exit != NULL) { - if (exit->executor == cold || exit->executor == cold_dynamic) { + if (_PyExecutor_FromHandle(exit->executor) == cold || _PyExecutor_FromHandle(exit->executor) == cold_dynamic) { #ifdef Py_STATS /* Only mark as have cold exit if it has actually exited */ uint64_t diff = inst->execution_count - executor->trace[i+1].execution_count; @@ -2212,7 +2216,7 @@ executor_to_gv(_PyExecutorObject *executor, FILE *out) #endif } else { - fprintf(out, "executor_%p:i%d -> executor_%p:start\n", executor, i, exit->executor); + fprintf(out, "executor_%p:i%d -> executor_%p:start\n", executor, i, _PyExecutor_FromHandle(exit->executor)); } } if (is_stop(inst)) {