mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
gh-106290: Fix edge cases around uops (#106319)
- Tweak uops debugging output - Fix the bug from gh-106290 - Rename `SET_IP` to `SAVE_IP` (per https://github.com/faster-cpython/ideas/issues/558) - Add a `SAVE_IP` uop at the start of the trace (ditto) - Allow `unbound_local_error`; this gives us uops for `LOAD_FAST_CHECK`, `LOAD_CLOSURE`, and `DELETE_FAST` - Longer traces - Support `STORE_FAST_LOAD_FAST`, `STORE_FAST_STORE_FAST` - Add deps on pycore_uops.h to Makefile(.pre.in)
This commit is contained in:
parent
58906213cc
commit
2028a4f6d9
7 changed files with 274 additions and 234 deletions
|
@ -2773,24 +2773,26 @@ void Py_LeaveRecursiveCall(void)
|
|||
_PyInterpreterFrame *
|
||||
_PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject **stack_pointer)
|
||||
{
|
||||
#ifdef LLTRACE
|
||||
#ifdef Py_DEBUG
|
||||
char *uop_debug = Py_GETENV("PYTHONUOPSDEBUG");
|
||||
int lltrace = 0;
|
||||
if (uop_debug != NULL && *uop_debug >= '0') {
|
||||
lltrace = *uop_debug - '0'; // TODO: Parse an int and all that
|
||||
}
|
||||
if (lltrace >= 2) {
|
||||
PyCodeObject *code = _PyFrame_GetCode(frame);
|
||||
_Py_CODEUNIT *instr = frame->prev_instr + 1;
|
||||
fprintf(stderr,
|
||||
"Entering _PyUopExecute for %s (%s:%d) at offset %ld\n",
|
||||
PyUnicode_AsUTF8(code->co_qualname),
|
||||
PyUnicode_AsUTF8(code->co_filename),
|
||||
code->co_firstlineno,
|
||||
(long)(instr - (_Py_CODEUNIT *)code->co_code_adaptive));
|
||||
}
|
||||
#define DPRINTF(level, ...) \
|
||||
if (lltrace >= (level)) { fprintf(stderr, __VA_ARGS__); }
|
||||
#else
|
||||
#define DPRINTF(level, ...)
|
||||
#endif
|
||||
|
||||
DPRINTF(3,
|
||||
"Entering _PyUopExecute for %s (%s:%d) at offset %ld\n",
|
||||
PyUnicode_AsUTF8(_PyFrame_GetCode(frame)->co_qualname),
|
||||
PyUnicode_AsUTF8(_PyFrame_GetCode(frame)->co_filename),
|
||||
_PyFrame_GetCode(frame)->co_firstlineno,
|
||||
(long)(frame->prev_instr + 1 -
|
||||
(_Py_CODEUNIT *)_PyFrame_GetCode(frame)->co_code_adaptive));
|
||||
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
_PyUOpExecutorObject *self = (_PyUOpExecutorObject *)executor;
|
||||
|
||||
|
@ -2803,7 +2805,7 @@ _PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject
|
|||
}
|
||||
|
||||
OBJECT_STAT_INC(optimization_traces_executed);
|
||||
_Py_CODEUNIT *ip_offset = (_Py_CODEUNIT *)_PyFrame_GetCode(frame)->co_code_adaptive - 1;
|
||||
_Py_CODEUNIT *ip_offset = (_Py_CODEUNIT *)_PyFrame_GetCode(frame)->co_code_adaptive;
|
||||
int pc = 0;
|
||||
int opcode;
|
||||
uint64_t operand;
|
||||
|
@ -2812,14 +2814,11 @@ _PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject
|
|||
opcode = self->trace[pc].opcode;
|
||||
operand = self->trace[pc].operand;
|
||||
oparg = (int)operand;
|
||||
#ifdef LLTRACE
|
||||
if (lltrace >= 3) {
|
||||
const char *opname = opcode < 256 ? _PyOpcode_OpName[opcode] : _PyOpcode_uop_name[opcode];
|
||||
int stack_level = (int)(stack_pointer - _PyFrame_Stackbase(frame));
|
||||
fprintf(stderr, " uop %s, operand %" PRIu64 ", stack_level %d\n",
|
||||
opname, operand, stack_level);
|
||||
}
|
||||
#endif
|
||||
DPRINTF(3,
|
||||
" uop %s, operand %" PRIu64 ", stack_level %d\n",
|
||||
opcode < 256 ? _PyOpcode_OpName[opcode] : _PyOpcode_uop_name[opcode],
|
||||
operand,
|
||||
(int)(stack_pointer - _PyFrame_Stackbase(frame)));
|
||||
pc++;
|
||||
OBJECT_STAT_INC(optimization_uops_executed);
|
||||
switch (opcode) {
|
||||
|
@ -2828,7 +2827,7 @@ _PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject
|
|||
#define ENABLE_SPECIALIZATION 0
|
||||
#include "executor_cases.c.h"
|
||||
|
||||
case SET_IP:
|
||||
case SAVE_IP:
|
||||
{
|
||||
frame->prev_instr = ip_offset + oparg;
|
||||
break;
|
||||
|
@ -2836,6 +2835,7 @@ _PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject
|
|||
|
||||
case EXIT_TRACE:
|
||||
{
|
||||
frame->prev_instr--; // Back up to just before destination
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
Py_DECREF(self);
|
||||
return frame;
|
||||
|
@ -2850,6 +2850,13 @@ _PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject
|
|||
}
|
||||
}
|
||||
|
||||
unbound_local_error:
|
||||
format_exc_check_arg(tstate, PyExc_UnboundLocalError,
|
||||
UNBOUNDLOCAL_ERROR_MSG,
|
||||
PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg)
|
||||
);
|
||||
goto error;
|
||||
|
||||
pop_4_error:
|
||||
STACK_SHRINK(1);
|
||||
pop_3_error:
|
||||
|
@ -2861,11 +2868,7 @@ pop_1_error:
|
|||
error:
|
||||
// On ERROR_IF we return NULL as the frame.
|
||||
// The caller recovers the frame from cframe.current_frame.
|
||||
#ifdef LLTRACE
|
||||
if (lltrace >= 2) {
|
||||
fprintf(stderr, "Error: [Opcode %d, operand %" PRIu64 "]\n", opcode, operand);
|
||||
}
|
||||
#endif
|
||||
DPRINTF(2, "Error: [Opcode %d, operand %" PRIu64 "]\n", opcode, operand);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
Py_DECREF(self);
|
||||
return NULL;
|
||||
|
@ -2873,11 +2876,8 @@ error:
|
|||
deoptimize:
|
||||
// On DEOPT_IF we just repeat the last instruction.
|
||||
// This presumes nothing was popped from the stack (nor pushed).
|
||||
#ifdef LLTRACE
|
||||
if (lltrace >= 2) {
|
||||
fprintf(stderr, "DEOPT: [Opcode %d, operand %" PRIu64 "]\n", opcode, operand);
|
||||
}
|
||||
#endif
|
||||
DPRINTF(2, "DEOPT: [Opcode %d, operand %" PRIu64 "]\n", opcode, operand);
|
||||
frame->prev_instr--; // Back up to just before destination
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
Py_DECREF(self);
|
||||
return frame;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue