From 8b1643ad0851913b2f5fd8f0e3c1ae759c4a9772 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Tue, 19 Sep 2023 22:27:10 +0100 Subject: [PATCH] WIP --- Include/internal/pycore_frame.h | 2 +- Python/bytecodes.c | 21 +++++++++++++++++---- Python/ceval.c | 19 +++++++++---------- Python/ceval_macros.h | 5 ++++- Python/executor_cases.c.h | 2 +- Python/generated_cases.c.h | 29 +++++++++++++++++++++-------- 6 files changed, 53 insertions(+), 25 deletions(-) diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h index 3d17421fe48417..596066b5d58476 100644 --- a/Include/internal/pycore_frame.h +++ b/Include/internal/pycore_frame.h @@ -86,7 +86,7 @@ typedef struct _PyInterpreterFrame { } _PyInterpreterFrame; #define NewPyInterpreterFrame_LASTI(IF) \ - ((int)(((IF)->instr_ptr - 1) - _PyCode_CODE(_PyFrame_GetCode(IF)))) + ((int)(((IF)->instr_ptr) - _PyCode_CODE(_PyFrame_GetCode(IF)))) #define _PyInterpreterFrame_LASTI(IF) \ ((int)((IF)->prev_instr - _PyCode_CODE(_PyFrame_GetCode(IF)))) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index c829c3adf3ad43..39b82e6c7ce6dc 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -3071,7 +3071,7 @@ if (VERBOSE) fprintf(stderr, "CALL-END: frame=%p frame->prev_instr=%p frame->ins STORE_SP(); new_frame->previous = frame; CALL_STAT_INC(inlined_py_calls); -if (VERBOSE) fprintf(stderr, "_PUSH_FRAME: frame=%p frame->prev_instr=%p frame->instr_ptr=%p\n", frame, frame->prev_instr, frame->instr_ptr); +if (VERBOSE) fprintf(stderr, "_PUSH_FRAME: frame=%p frame->prev_instr=%p frame->instr_ptr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, frame->new_return_offset); frame = tstate->current_frame = new_frame; tstate->py_recursion_remaining--; LOAD_SP(); @@ -3632,12 +3632,15 @@ if (VERBOSE) fprintf(stderr, "_PUSH_FRAME: frame=%p frame->prev_instr=%p frame-> // DICT_MERGE is called before this opcode if there are kwargs. // It converts all dict subtypes in kwargs into regular dicts. assert(kwargs == NULL || PyDict_CheckExact(kwargs)); +if (VERBOSE) fprintf(stderr, "CALL_FUNCTION_EX BEGIN: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); if (!PyTuple_CheckExact(callargs)) { if (check_args_iterable(tstate, func, callargs) < 0) { +if (VERBOSE) fprintf(stderr, "CALL_FUNCTION_EX0: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); goto error; } PyObject *tuple = PySequence_Tuple(callargs); if (tuple == NULL) { +if (VERBOSE) fprintf(stderr, "CALL_FUNCTION_EX1: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); goto error; } Py_SETREF(callargs, tuple); @@ -3652,7 +3655,10 @@ if (VERBOSE) fprintf(stderr, "_PUSH_FRAME: frame=%p frame->prev_instr=%p frame-> int err = _Py_call_instrumentation_2args( tstate, PY_MONITORING_EVENT_CALL, frame, next_instr-1, func, arg); - if (err) goto error; + if (err) { +if (VERBOSE) fprintf(stderr, "CALL_FUNCTION_EX2: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); + goto error; + } result = PyObject_Call(func, callargs, kwargs); if (result == NULL) { _Py_call_instrumentation_exc2( @@ -3683,17 +3689,24 @@ if (VERBOSE) fprintf(stderr, "_PUSH_FRAME: frame=%p frame->prev_instr=%p frame-> // Need to manually shrink the stack since we exit with DISPATCH_INLINED. STACK_SHRINK(oparg + 3); if (new_frame == NULL) { +if (VERBOSE) fprintf(stderr, "CALL_FUNCTION_EX3: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); goto error; } frame->return_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; +if (VERBOSE) fprintf(stderr, "CALL_FUNCTION_EX3a: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); DISPATCH_INLINED(new_frame); } result = PyObject_Call(func, callargs, kwargs); } DECREF_INPUTS(); assert(PEEK(2 + (oparg & 1)) == NULL); - ERROR_IF(result == NULL, error); +if (VERBOSE) fprintf(stderr, "CALL_FUNCTION_EX4: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); + //ERROR_IF(result == NULL, error); + if (result == NULL) { +if (VERBOSE) fprintf(stderr, "CALL_FUNCTION_EX3a: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); + goto error; + } CHECK_EVAL_BREAKER(); } @@ -3959,7 +3972,7 @@ if (VERBOSE) fprintf(stderr, "_PUSH_FRAME: frame=%p frame->prev_instr=%p frame-> if (VERBOSE) fprintf(stderr, "_SAVE_CURRENT_IP[1]: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); frame->prev_instr = next_instr - 1; assert(frame->new_return_offset == 0); - frame->new_return_offset = next_instr - frame->instr_ptr; + frame->new_return_offset = next_instr - frame->instr_ptr + frame->new_return_offset; if (VERBOSE) fprintf(stderr, "_SAVE_CURRENT_IP[2]: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); #endif #if TIER_TWO diff --git a/Python/ceval.c b/Python/ceval.c index bb396c861eede2..3f075cbd92c59a 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -731,10 +731,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int /* Sets the above local variables from the frame */ #define SET_LOCALS_FROM_FRAME() \ /* Jump back to the last instruction executed... */ \ -if (!(frame->instr_ptr == frame->prev_instr + 1)) if (VERBOSE) fprintf(stderr, "SET_LOCALS_FROM_FRAME: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p\n", frame, frame->prev_instr, frame->instr_ptr, next_instr); \ +if (!(frame->instr_ptr == frame->prev_instr + 1)) if (VERBOSE) fprintf(stderr, "SET_LOCALS_FROM_FRAME: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); \ if (0) frame->instr_ptr += 1 + _PyOpcode_Caches[_PyOpcode_Deopt[frame->instr_ptr->op.code]]; \ - assert (frame->instr_ptr == frame->prev_instr + 1); \ - next_instr = frame->instr_ptr; \ + next_instr = frame->instr_ptr + frame->new_return_offset; \ + assert (next_instr == frame->prev_instr + 1); \ stack_pointer = _PyFrame_GetStackPointer(frame); start_frame: @@ -868,10 +868,10 @@ if (!(frame->instr_ptr == frame->prev_instr + 1)) if (VERBOSE) fprintf(stderr, " { /* We can't use frame->f_lasti here, as RERAISE may have set it */ int offset = INSTR_OFFSET()-1; -if (VERBOSE) fprintf(stderr, "exception_unwind: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr-1=%p\n", frame, frame->prev_instr, frame->instr_ptr, next_instr-1); +if (VERBOSE) fprintf(stderr, "exception_unwind: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr-1=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr-1, frame->new_return_offset); int level, handler, lasti; if (get_exception_handler(_PyFrame_GetCode(frame), offset, &level, &handler, &lasti) == 0) { -if (VERBOSE) fprintf(stderr, "got_exception_handler: offset=%d lasti=%d handler=%d\n", offset, lasti, handler); +if (VERBOSE) fprintf(stderr, "No Exception Handler: offset=%d lasti=%d handler=%d\n", offset, lasti, handler); // No handlers, so exit. assert(_PyErr_Occurred(tstate)); @@ -884,10 +884,12 @@ if (VERBOSE) fprintf(stderr, "got_exception_handler: offset=%d lasti=%d handler assert(STACK_LEVEL() == 0); _PyFrame_SetStackPointer(frame, stack_pointer); monitor_unwind(tstate, frame, next_instr-1); -if (VERBOSE) fprintf(stderr, "goto exit_unwind: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p\n", frame, frame->prev_instr, frame->instr_ptr, next_instr); +if (VERBOSE) fprintf(stderr, "goto exit_unwind: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); goto exit_unwind; } +if (VERBOSE) fprintf(stderr, "Exception Handler: %d\n", handler); + assert(STACK_LEVEL() >= level); PyObject **new_top = _PyFrame_Stackbase(frame) + level; while (stack_pointer > new_top) { @@ -932,10 +934,7 @@ if (VERBOSE) fprintf(stderr, "goto exit_unwind: frame=%p frame->prev_instr=%p fr _PyInterpreterFrame *dying = frame; frame = tstate->current_frame = dying->previous; _PyEval_FrameClearAndPop(tstate, dying); - frame->instr_ptr += frame->new_return_offset; - frame->new_return_offset = 0; -if (VERBOSE) fprintf(stderr, "exit_unwind: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p\n", frame, frame->prev_instr, frame->instr_ptr, next_instr); - +if (VERBOSE) fprintf(stderr, "exit_unwind: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); if (frame == &entry_frame) { /* Restore previous frame and exit */ tstate->current_frame = frame->previous; diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index 34003c2fb0bd68..29ebc27b0b4819 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -153,7 +153,10 @@ GETITEM(PyObject *v, Py_ssize_t i) { opcode = word.op.code; \ oparg = word.op.arg; \ } while (0) -#define JUMPTO(x) (next_instr = _PyCode_CODE(_PyFrame_GetCode(frame)) + (x)) +#define JUMPTO(x) do { \ + next_instr = _PyCode_CODE(_PyFrame_GetCode(frame)) + (x); \ + frame->new_return_offset = 0; \ + } while(0) /* JUMPBY makes the generator identify the instruction as a jump. SKIP_OVER is * for advancing to the next instruction, taking into account cache entries diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index abe33430346f0f..35ef1bb82d4a72 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -2981,7 +2981,7 @@ if (VERBOSE) fprintf(stderr, "_POP_FRAME[3]: frame=%p frame->prev_instr=%p frame if (VERBOSE) fprintf(stderr, "_SAVE_CURRENT_IP[1]: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); frame->prev_instr = next_instr - 1; assert(frame->new_return_offset == 0); - frame->new_return_offset = next_instr - frame->instr_ptr; + frame->new_return_offset = next_instr - frame->instr_ptr + frame->new_return_offset; if (VERBOSE) fprintf(stderr, "_SAVE_CURRENT_IP[2]: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); #endif #if TIER_TWO diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 0bfe61c3acd7d7..965e011540a1de 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -995,7 +995,7 @@ if (frame->previous) if (VERBOSE) fprintf(stderr, "INTERPRETER_EXIT2: tstate->cu if (VERBOSE) fprintf(stderr, "_SAVE_CURRENT_IP[1]: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); frame->prev_instr = next_instr - 1; assert(frame->new_return_offset == 0); - frame->new_return_offset = next_instr - frame->instr_ptr; + frame->new_return_offset = next_instr - frame->instr_ptr + frame->new_return_offset; if (VERBOSE) fprintf(stderr, "_SAVE_CURRENT_IP[2]: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); #endif #if TIER_TWO @@ -1074,7 +1074,7 @@ if (frame->previous) if (VERBOSE) fprintf(stderr, "INTERPRETER_EXIT2: tstate->cu if (VERBOSE) fprintf(stderr, "_SAVE_CURRENT_IP[1]: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); frame->prev_instr = next_instr - 1; assert(frame->new_return_offset == 0); - frame->new_return_offset = next_instr - frame->instr_ptr; + frame->new_return_offset = next_instr - frame->instr_ptr + frame->new_return_offset; if (VERBOSE) fprintf(stderr, "_SAVE_CURRENT_IP[2]: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); #endif #if TIER_TWO @@ -3919,7 +3919,7 @@ if (VERBOSE) fprintf(stderr, "CALL-END: frame=%p frame->prev_instr=%p frame->ins if (VERBOSE) fprintf(stderr, "_SAVE_CURRENT_IP[1]: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); frame->prev_instr = next_instr - 1; assert(frame->new_return_offset == 0); - frame->new_return_offset = next_instr - frame->instr_ptr; + frame->new_return_offset = next_instr - frame->instr_ptr + frame->new_return_offset; if (VERBOSE) fprintf(stderr, "_SAVE_CURRENT_IP[2]: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); #endif #if TIER_TWO @@ -3939,7 +3939,7 @@ if (VERBOSE) fprintf(stderr, "CALL-END: frame=%p frame->prev_instr=%p frame->ins STORE_SP(); new_frame->previous = frame; CALL_STAT_INC(inlined_py_calls); - if (VERBOSE) fprintf(stderr, "_PUSH_FRAME: frame=%p frame->prev_instr=%p frame->instr_ptr=%p\n", frame, frame->prev_instr, frame->instr_ptr); + if (VERBOSE) fprintf(stderr, "_PUSH_FRAME: frame=%p frame->prev_instr=%p frame->instr_ptr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, frame->new_return_offset); frame = tstate->current_frame = new_frame; tstate->py_recursion_remaining--; LOAD_SP(); @@ -4003,7 +4003,7 @@ if (VERBOSE) fprintf(stderr, "CALL-END: frame=%p frame->prev_instr=%p frame->ins if (VERBOSE) fprintf(stderr, "_SAVE_CURRENT_IP[1]: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); frame->prev_instr = next_instr - 1; assert(frame->new_return_offset == 0); - frame->new_return_offset = next_instr - frame->instr_ptr; + frame->new_return_offset = next_instr - frame->instr_ptr + frame->new_return_offset; if (VERBOSE) fprintf(stderr, "_SAVE_CURRENT_IP[2]: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); #endif #if TIER_TWO @@ -4023,7 +4023,7 @@ if (VERBOSE) fprintf(stderr, "CALL-END: frame=%p frame->prev_instr=%p frame->ins STORE_SP(); new_frame->previous = frame; CALL_STAT_INC(inlined_py_calls); - if (VERBOSE) fprintf(stderr, "_PUSH_FRAME: frame=%p frame->prev_instr=%p frame->instr_ptr=%p\n", frame, frame->prev_instr, frame->instr_ptr); + if (VERBOSE) fprintf(stderr, "_PUSH_FRAME: frame=%p frame->prev_instr=%p frame->instr_ptr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, frame->new_return_offset); frame = tstate->current_frame = new_frame; tstate->py_recursion_remaining--; LOAD_SP(); @@ -4764,12 +4764,15 @@ if (VERBOSE) fprintf(stderr, "CALL-END: frame=%p frame->prev_instr=%p frame->ins // DICT_MERGE is called before this opcode if there are kwargs. // It converts all dict subtypes in kwargs into regular dicts. assert(kwargs == NULL || PyDict_CheckExact(kwargs)); +if (VERBOSE) fprintf(stderr, "CALL_FUNCTION_EX BEGIN: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); if (!PyTuple_CheckExact(callargs)) { if (check_args_iterable(tstate, func, callargs) < 0) { +if (VERBOSE) fprintf(stderr, "CALL_FUNCTION_EX0: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); goto error; } PyObject *tuple = PySequence_Tuple(callargs); if (tuple == NULL) { +if (VERBOSE) fprintf(stderr, "CALL_FUNCTION_EX1: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); goto error; } Py_SETREF(callargs, tuple); @@ -4784,7 +4787,10 @@ if (VERBOSE) fprintf(stderr, "CALL-END: frame=%p frame->prev_instr=%p frame->ins int err = _Py_call_instrumentation_2args( tstate, PY_MONITORING_EVENT_CALL, frame, next_instr-1, func, arg); - if (err) goto error; + if (err) { +if (VERBOSE) fprintf(stderr, "CALL_FUNCTION_EX2: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); + goto error; + } result = PyObject_Call(func, callargs, kwargs); if (result == NULL) { _Py_call_instrumentation_exc2( @@ -4815,10 +4821,12 @@ if (VERBOSE) fprintf(stderr, "CALL-END: frame=%p frame->prev_instr=%p frame->ins // Need to manually shrink the stack since we exit with DISPATCH_INLINED. STACK_SHRINK(oparg + 3); if (new_frame == NULL) { +if (VERBOSE) fprintf(stderr, "CALL_FUNCTION_EX3: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); goto error; } frame->return_offset = 0; frame->new_return_offset = next_instr - frame->instr_ptr; +if (VERBOSE) fprintf(stderr, "CALL_FUNCTION_EX3a: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); DISPATCH_INLINED(new_frame); } result = PyObject_Call(func, callargs, kwargs); @@ -4827,7 +4835,12 @@ if (VERBOSE) fprintf(stderr, "CALL-END: frame=%p frame->prev_instr=%p frame->ins Py_DECREF(callargs); Py_XDECREF(kwargs); assert(PEEK(2 + (oparg & 1)) == NULL); - if (result == NULL) { STACK_SHRINK(((oparg & 1) ? 1 : 0)); goto pop_3_error; } +if (VERBOSE) fprintf(stderr, "CALL_FUNCTION_EX4: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); + //ERROR_IF(result == NULL, error); + if (result == NULL) { +if (VERBOSE) fprintf(stderr, "CALL_FUNCTION_EX3a: frame=%p frame->prev_instr=%p frame->instr_ptr=%p next_instr=%p new_return_offset=%d\n", frame, frame->prev_instr, frame->instr_ptr, next_instr, frame->new_return_offset); + goto error; + } STACK_SHRINK(((oparg & 1) ? 1 : 0)); STACK_SHRINK(2); stack_pointer[-1] = result;