summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2023-07-03 20:05:11 (GMT)
committerGitHub <noreply@github.com>2023-07-03 20:05:11 (GMT)
commit2028a4f6d996d2a46cbc33d0b65fdae284ee71fc (patch)
tree39508420ebb64059d1e04b6ffd015b8f7c81a52e /Python/ceval.c
parent58906213cc5d8f2be311664766b4923ef29dae1f (diff)
downloadcpython-2028a4f6d996d2a46cbc33d0b65fdae284ee71fc.zip
cpython-2028a4f6d996d2a46cbc33d0b65fdae284ee71fc.tar.gz
cpython-2028a4f6d996d2a46cbc33d0b65fdae284ee71fc.tar.bz2
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)
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c62
1 files changed, 31 insertions, 31 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 80ae85c..6ce1a6a 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -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;