#define SPECIAL___AEXIT__ 3
#define SPECIAL_MAX 3
-struct _PyCode12 _PyCode_DEF(12);
-PyAPI_DATA(const struct _PyCode12) _PyEntryFrameCode;
+PyAPI_DATA(const _Py_CODEUNIT *) _Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS_PTR;
#ifdef __cplusplus
}
#define USE_COMPUTED_GOTOS 0
#include "ceval_macros.h"
+#include "../Include/internal/pycore_stackref.h"
/* Flow control macros */
op(_QUICKEN_RESUME, (--)) {
#if ENABLE_SPECIALIZATION_FT
- PyCodeObject *code = _PyFrame_GetCode(frame);
if (tstate->tracing == 0 && this_instr->op.code == RESUME) {
FT_ATOMIC_STORE_UINT8_RELAXED(this_instr->op.code, RESUME_CHECK);
}
tier2 op(_EXIT_TRACE, (exit_p/4 --)) {
_PyExitData *exit = (_PyExitData *)exit_p;
#if defined(Py_DEBUG) && !defined(_Py_JIT)
- _Py_CODEUNIT *target = _PyFrame_GetBytecode(frame) + exit->target;
+ const _Py_CODEUNIT *target = ((frame->owner >= FRAME_OWNED_BY_INTERPRETER)
+ ? _Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS_PTR : _PyFrame_GetBytecode(frame))
+ + exit->target;
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
if (frame->lltrace >= 2) {
printf("SIDE EXIT: [UOp ");
tier2 op(_COLD_EXIT, ( -- )) {
_PyExitData *exit = tstate->jit_exit;
assert(exit != NULL);
- _Py_CODEUNIT *target = _PyFrame_GetBytecode(frame) + exit->target;
+ _Py_CODEUNIT *target = ((frame->owner >= FRAME_OWNED_BY_INTERPRETER)
+ ? (_Py_CODEUNIT *)_Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS_PTR : _PyFrame_GetBytecode(frame)) + exit->target;
_Py_BackoffCounter temperature = exit->temperature;
_PyExecutorObject *executor;
if (target->op.code == ENTER_EXECUTOR) {
Py_INCREF(executor);
}
else {
+ if (frame->owner >= FRAME_OWNED_BY_INTERPRETER) {
+ GOTO_TIER_ONE(target);
+ }
if (!backoff_counter_triggers(temperature)) {
exit->temperature = advance_backoff_counter(temperature);
GOTO_TIER_ONE(target);
tstate->interp->jit_state.prev_instr = next_instr;
}
tstate->interp->jit_state.specialize_counter = 0;
- PyCodeObject *prev_code = (PyCodeObject *)Py_NewRef(_PyFrame_GetCode(frame));
+ PyCodeObject *prev_code = (PyCodeObject *)Py_NewRef(PyStackRef_AsPyObjectBorrow(frame->f_executable));
if (tstate->interp->jit_state.prev_instr_code != prev_code) {
Py_SETREF(tstate->interp->jit_state.prev_instr_code, prev_code);
}
tstate->interp->jit_state.prev_instr_frame = frame;
tstate->interp->jit_state.prev_instr_oparg = oparg;
- tstate->interp->jit_state.prev_instr_stacklevel = STACK_LEVEL();
+ tstate->interp->jit_state.prev_instr_stacklevel = PyStackRef_IsNone(frame->f_executable) ? 2 : STACK_LEVEL();
DISPATCH_GOTO_NON_TRACING();
#else
Py_FatalError("JIT label executed in non-jit build.");
return 0;
}
-static const PyBytesObject no_location = {
- PyVarObject_HEAD_INIT(&PyBytes_Type, 1)
- .ob_sval = { NO_LOC_4 }
+static const _Py_CODEUNIT _Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS[] = {
+ /* Put a NOP at the start, so that the IP points into
+ * the code, rather than before it */
+ { .op.code = NOP, .op.arg = 0 },
+ { .op.code = INTERPRETER_EXIT, .op.arg = 0 }, /* reached on return */
+ { .op.code = NOP, .op.arg = 0 },
+ { .op.code = INTERPRETER_EXIT, .op.arg = 0 }, /* reached on yield */
+ { .op.code = RESUME, .op.arg = RESUME_OPARG_DEPTH1_MASK | RESUME_AT_FUNC_START }
};
-#ifdef Py_GIL_DISABLED
-static _PyCodeArray emtry_cleanup_tlbc = {
- .size = 1,
- .entries = {(char*) &_PyEntryFrameCode.co_code_adaptive},
-};
-#endif
-
-const struct _PyCode12 _PyEntryFrameCode = {
- _PyVarObject_HEAD_INIT(&PyCode_Type, 5),
- .co_consts = (PyObject *)&_Py_SINGLETON(tuple_empty),
- .co_names = (PyObject *)&_Py_SINGLETON(tuple_empty),
- .co_exceptiontable = (PyObject *)&_Py_SINGLETON(bytes_empty),
- .co_flags = CO_OPTIMIZED | CO_NO_MONITORING_EVENTS,
- .co_localsplusnames = (PyObject *)&_Py_SINGLETON(tuple_empty),
- .co_localspluskinds = (PyObject *)&_Py_SINGLETON(bytes_empty),
- .co_filename = &_Py_ID(_PyEval_EvalFrameDefault),
- .co_name = &_Py_ID(_PyEval_EvalFrameDefault),
- .co_qualname = &_Py_ID(_PyEval_EvalFrameDefault),
- .co_linetable = (PyObject *)&no_location,
- ._co_firsttraceable = 4,
- .co_stacksize = 2,
- .co_framesize = 2 + FRAME_SPECIALS_SIZE,
-#ifdef Py_GIL_DISABLED
- .co_tlbc = &emtry_cleanup_tlbc,
-#endif
- .co_code_adaptive = {
- NOP, 0,
- INTERPRETER_EXIT, 0, /* reached on return */
- NOP, 0,
- INTERPRETER_EXIT, 0, /* reached on yield */
- RESUME, RESUME_OPARG_DEPTH1_MASK | RESUME_AT_FUNC_START
- }
-};
+const _Py_CODEUNIT *_Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS_PTR = (_Py_CODEUNIT*)&_Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS;
#ifdef Py_DEBUG
extern void _PyUOpPrint(const _PyUOpInstruction *uop);
entry.frame.f_globals = (PyObject*)0xaaa3;
entry.frame.f_builtins = (PyObject*)0xaaa4;
#endif
- entry.frame.f_executable = PyStackRef_FromPyObjectBorrow((PyObject *)&_PyEntryFrameCode);
- entry.frame.instr_ptr = ((_Py_CODEUNIT *)_PyEntryFrameCode.co_code_adaptive) + 1;
+ entry.frame.f_executable = PyStackRef_None;
+ entry.frame.instr_ptr = (_Py_CODEUNIT *)_Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS + 1;
entry.frame.stackpointer = entry.stack;
entry.frame.owner = FRAME_OWNED_BY_INTERPRETER;
entry.frame.visited = 0;
PyObject *exit_p = (PyObject *)CURRENT_OPERAND0();
_PyExitData *exit = (_PyExitData *)exit_p;
#if defined(Py_DEBUG) && !defined(_Py_JIT)
- _Py_CODEUNIT *target = _PyFrame_GetBytecode(frame) + exit->target;
+ const _Py_CODEUNIT *target = ((frame->owner >= FRAME_OWNED_BY_INTERPRETER)
+ ? _Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS_PTR : _PyFrame_GetBytecode(frame))
+ + exit->target;
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
if (frame->lltrace >= 2) {
_PyFrame_SetStackPointer(frame, stack_pointer);
case _COLD_EXIT: {
_PyExitData *exit = tstate->jit_exit;
assert(exit != NULL);
- _Py_CODEUNIT *target = _PyFrame_GetBytecode(frame) + exit->target;
+ _Py_CODEUNIT *target = ((frame->owner >= FRAME_OWNED_BY_INTERPRETER)
+ ? (_Py_CODEUNIT *)_Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS_PTR : _PyFrame_GetBytecode(frame)) + exit->target;
_Py_BackoffCounter temperature = exit->temperature;
_PyExecutorObject *executor;
if (target->op.code == ENTER_EXECUTOR) {
Py_INCREF(executor);
}
else {
+ if (frame->owner >= FRAME_OWNED_BY_INTERPRETER) {
+ GOTO_TIER_ONE(target);
+ }
if (!backoff_counter_triggers(temperature)) {
exit->temperature = advance_backoff_counter(temperature);
GOTO_TIER_ONE(target);
// _QUICKEN_RESUME
{
#if ENABLE_SPECIALIZATION_FT
- PyCodeObject *code = _PyFrame_GetCode(frame);
if (tstate->tracing == 0 && this_instr->op.code == RESUME) {
FT_ATOMIC_STORE_UINT8_RELAXED(this_instr->op.code, RESUME_CHECK);
}
tstate->interp->jit_state.prev_instr = next_instr;
}
tstate->interp->jit_state.specialize_counter = 0;
- PyCodeObject *prev_code = (PyCodeObject *)Py_NewRef(_PyFrame_GetCode(frame));
+ PyCodeObject *prev_code = (PyCodeObject *)Py_NewRef(PyStackRef_AsPyObjectBorrow(frame->f_executable));
if (tstate->interp->jit_state.prev_instr_code != prev_code) {
_PyFrame_SetStackPointer(frame, stack_pointer);
Py_SETREF(tstate->interp->jit_state.prev_instr_code, prev_code);
}
tstate->interp->jit_state.prev_instr_frame = frame;
tstate->interp->jit_state.prev_instr_oparg = oparg;
- tstate->interp->jit_state.prev_instr_stacklevel = STACK_LEVEL();
+ tstate->interp->jit_state.prev_instr_stacklevel = PyStackRef_IsNone(frame->f_executable) ? 2 : STACK_LEVEL();
DISPATCH_GOTO_NON_TRACING();
#else
Py_FatalError("JIT label executed in non-jit build.");
static bool
has_space_for_executor(PyCodeObject *code, _Py_CODEUNIT *instr)
{
- if (code == (PyCodeObject *)&_Py_InitCleanup || code == (PyCodeObject *)&_PyEntryFrameCode) {
+ if (code == (PyCodeObject *)&_Py_InitCleanup) {
return false;
}
if (instr->op.code == ENTER_EXECUTOR) {
_Py_CODEUNIT *target_instr = this_instr;
uint32_t target = 0;
- target = INSTR_IP(target_instr, old_code);
+ target = Py_IsNone((PyObject *)old_code)
+ ? (int)(target_instr - _Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS_PTR)
+ : INSTR_IP(target_instr, old_code);
// Rewind EXTENDED_ARG so that we see the whole thing.
// We must point to the first EXTENDED_ARG when deopting.
DPRINTF(2, "Adding %p func to op\n", (void *)operand);
_Py_BloomFilter_Add(dependencies, new_func);
}
- else if (new_code != NULL) {
+ else if (new_code != NULL && !Py_IsNone((PyObject*)new_code)) {
operand = (uintptr_t)new_code | 1;
DPRINTF(2, "Adding %p code to op\n", (void *)operand);
_Py_BloomFilter_Add(dependencies, new_code);
operand = 0;
}
ADD_TO_TRACE(uop, oparg, operand, target);
- trace[trace_length - 1].operand1 = ((int)(frame->stackpointer - _PyFrame_Stackbase(frame)));
+ trace[trace_length - 1].operand1 = PyStackRef_IsNone(frame->f_executable) ? 2 : ((int)(frame->stackpointer - _PyFrame_Stackbase(frame)));
break;
}
if (uop == _BINARY_OP_INPLACE_ADD_UNICODE) {
JitOptRef temp = PyJitRef_StripReferenceInfo(retval);
DEAD(retval);
SAVE_STACK();
+ ctx->frame->stack_pointer = stack_pointer;
PyCodeObject *returning_code = get_code_with_logging(this_instr);
if (returning_code == NULL) {
ctx->done = true;
JitOptRef temp = PyJitRef_StripReferenceInfo(retval);
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
+ ctx->frame->stack_pointer = stack_pointer;
PyCodeObject *returning_code = get_code_with_logging(this_instr);
if (returning_code == NULL) {
ctx->done = true;