mirror of
https://github.com/python/cpython.git
synced 2026-01-26 21:03:34 +00:00
gh-143946: Show JitOptSymbol on abstract stack when set PYTHON_OPT_DEBUG > 4 (GH-143957)
This commit is contained in:
parent
7e28ae550f
commit
61ec66acd5
@ -115,8 +115,10 @@ static inline uint16_t uop_get_error_target(const _PyUOpInstruction *inst)
|
||||
|
||||
|
||||
#define REF_IS_BORROWED 1
|
||||
#define REF_IS_INVALID 2
|
||||
#define REF_TAG_BITS 3
|
||||
|
||||
#define JIT_BITS_TO_PTR_MASKED(REF) ((JitOptSymbol *)(((REF).bits) & (~REF_IS_BORROWED)))
|
||||
#define JIT_BITS_TO_PTR_MASKED(REF) ((JitOptSymbol *)(((REF).bits) & (~REF_TAG_BITS)))
|
||||
|
||||
static inline JitOptSymbol *
|
||||
PyJitRef_Unwrap(JitOptRef ref)
|
||||
@ -133,6 +135,18 @@ PyJitRef_Wrap(JitOptSymbol *sym)
|
||||
return (JitOptRef){.bits=(uintptr_t)sym};
|
||||
}
|
||||
|
||||
static inline JitOptRef
|
||||
PyJitRef_WrapInvalid(void *ptr)
|
||||
{
|
||||
return (JitOptRef){.bits=(uintptr_t)ptr | REF_IS_INVALID};
|
||||
}
|
||||
|
||||
static inline bool
|
||||
PyJitRef_IsInvalid(JitOptRef ref)
|
||||
{
|
||||
return (ref.bits & REF_IS_INVALID) == REF_IS_INVALID;
|
||||
}
|
||||
|
||||
static inline JitOptRef
|
||||
PyJitRef_StripReferenceInfo(JitOptRef ref)
|
||||
{
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
#ifdef Py_DEBUG
|
||||
extern const char *_PyUOpName(int index);
|
||||
extern void _PyUOpPrint(const _PyUOpInstruction *uop);
|
||||
extern void _PyUOpSymPrint(JitOptRef ref);
|
||||
static const char *const DEBUG_ENV = "PYTHON_OPT_DEBUG";
|
||||
static inline int get_lltrace(void) {
|
||||
char *uop_debug = Py_GETENV(DEBUG_ENV);
|
||||
@ -50,6 +51,38 @@
|
||||
}
|
||||
#define DPRINTF(level, ...) \
|
||||
if (get_lltrace() >= (level)) { printf(__VA_ARGS__); }
|
||||
|
||||
|
||||
|
||||
static void
|
||||
dump_abstract_stack(_Py_UOpsAbstractFrame *frame, JitOptRef *stack_pointer)
|
||||
{
|
||||
JitOptRef *stack_base = frame->stack;
|
||||
JitOptRef *locals_base = frame->locals;
|
||||
printf(" locals=[");
|
||||
for (JitOptRef *ptr = locals_base; ptr < stack_base; ptr++) {
|
||||
if (ptr != locals_base) {
|
||||
printf(", ");
|
||||
}
|
||||
_PyUOpSymPrint(*ptr);
|
||||
}
|
||||
printf("]\n");
|
||||
if (stack_pointer < stack_base) {
|
||||
printf(" stack=%d\n", (int)(stack_pointer - stack_base));
|
||||
}
|
||||
else {
|
||||
printf(" stack=[");
|
||||
for (JitOptRef *ptr = stack_base; ptr < stack_pointer; ptr++) {
|
||||
if (ptr != stack_base) {
|
||||
printf(", ");
|
||||
}
|
||||
_PyUOpSymPrint(*ptr);
|
||||
}
|
||||
printf("]\n");
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
#else
|
||||
#define DPRINTF(level, ...)
|
||||
#endif
|
||||
@ -383,7 +416,10 @@ optimize_uops(
|
||||
if (get_lltrace() >= 3) {
|
||||
printf("%4d abs: ", (int)(this_instr - trace));
|
||||
_PyUOpPrint(this_instr);
|
||||
printf(" ");
|
||||
printf(" \n");
|
||||
if (get_lltrace() >= 5 && !CURRENT_FRAME_IS_INIT_SHIM()) {
|
||||
dump_abstract_stack(ctx->frame, stack_pointer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -340,7 +340,7 @@ dummy_func(void) {
|
||||
}
|
||||
f->locals[0] = container;
|
||||
f->locals[1] = sub;
|
||||
new_frame = PyJitRef_Wrap((JitOptSymbol *)f);
|
||||
new_frame = PyJitRef_WrapInvalid(f);
|
||||
}
|
||||
|
||||
op(_BINARY_OP_SUBSCR_STR_INT, (str_st, sub_st -- res, s, i)) {
|
||||
@ -784,7 +784,7 @@ dummy_func(void) {
|
||||
break;
|
||||
}
|
||||
f->locals[0] = owner;
|
||||
new_frame = PyJitRef_Wrap((JitOptSymbol *)f);
|
||||
new_frame = PyJitRef_WrapInvalid(f);
|
||||
}
|
||||
|
||||
op(_INIT_CALL_BOUND_METHOD_EXACT_ARGS, (callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) {
|
||||
@ -848,9 +848,9 @@ dummy_func(void) {
|
||||
}
|
||||
|
||||
if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) {
|
||||
new_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co, 0, args, argcount));
|
||||
new_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, args, argcount));
|
||||
} else {
|
||||
new_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co, 0, NULL, 0));
|
||||
new_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, NULL, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@ -868,7 +868,7 @@ dummy_func(void) {
|
||||
break;
|
||||
}
|
||||
|
||||
new_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co, 0, NULL, 0));
|
||||
new_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, NULL, 0));
|
||||
}
|
||||
|
||||
op(_PY_FRAME_KW, (callable, self_or_null, args[oparg], kwnames -- new_frame)) {
|
||||
@ -879,7 +879,7 @@ dummy_func(void) {
|
||||
break;
|
||||
}
|
||||
|
||||
new_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co, 0, NULL, 0));
|
||||
new_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, NULL, 0));
|
||||
}
|
||||
|
||||
op(_PY_FRAME_EX, (func_st, null, callargs_st, kwargs_st -- ex_frame)) {
|
||||
@ -890,7 +890,7 @@ dummy_func(void) {
|
||||
break;
|
||||
}
|
||||
|
||||
ex_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co, 0, NULL, 0));
|
||||
ex_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, NULL, 0));
|
||||
}
|
||||
|
||||
op(_CHECK_AND_ALLOCATE_OBJECT, (type_version/2, callable, self_or_null, args[oparg] -- callable, self_or_null, args[oparg])) {
|
||||
@ -914,7 +914,7 @@ dummy_func(void) {
|
||||
ctx->curr_frame_depth++;
|
||||
assert((this_instr + 1)->opcode == _PUSH_FRAME);
|
||||
PyCodeObject *co = get_code_with_logging((this_instr + 1));
|
||||
init_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co, 0, args-1, oparg+1));
|
||||
init_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, args-1, oparg+1));
|
||||
}
|
||||
|
||||
op(_RETURN_VALUE, (retval -- res)) {
|
||||
@ -1007,7 +1007,7 @@ dummy_func(void) {
|
||||
break;
|
||||
}
|
||||
new_frame->stack[0] = sym_new_const(ctx, Py_None);
|
||||
gen_frame = PyJitRef_Wrap((JitOptSymbol *)new_frame);
|
||||
gen_frame = PyJitRef_WrapInvalid(new_frame);
|
||||
}
|
||||
|
||||
op(_SEND_GEN_FRAME, (unused, v -- unused, gen_frame)) {
|
||||
@ -1023,7 +1023,7 @@ dummy_func(void) {
|
||||
break;
|
||||
}
|
||||
new_frame->stack[0] = PyJitRef_StripReferenceInfo(v);
|
||||
gen_frame = PyJitRef_Wrap((JitOptSymbol *)new_frame);
|
||||
gen_frame = PyJitRef_WrapInvalid(new_frame);
|
||||
}
|
||||
|
||||
op(_CHECK_STACK_SPACE, (unused, unused, unused[oparg] -- unused, unused, unused[oparg])) {
|
||||
|
||||
20
Python/optimizer_cases.c.h
generated
20
Python/optimizer_cases.c.h
generated
@ -1131,7 +1131,7 @@
|
||||
}
|
||||
f->locals[0] = container;
|
||||
f->locals[1] = sub;
|
||||
new_frame = PyJitRef_Wrap((JitOptSymbol *)f);
|
||||
new_frame = PyJitRef_WrapInvalid(f);
|
||||
CHECK_STACK_BOUNDS(-2);
|
||||
stack_pointer[-3] = new_frame;
|
||||
stack_pointer += -2;
|
||||
@ -1295,7 +1295,7 @@
|
||||
break;
|
||||
}
|
||||
new_frame->stack[0] = PyJitRef_StripReferenceInfo(v);
|
||||
gen_frame = PyJitRef_Wrap((JitOptSymbol *)new_frame);
|
||||
gen_frame = PyJitRef_WrapInvalid(new_frame);
|
||||
stack_pointer[-1] = gen_frame;
|
||||
break;
|
||||
}
|
||||
@ -1977,7 +1977,7 @@
|
||||
break;
|
||||
}
|
||||
f->locals[0] = owner;
|
||||
new_frame = PyJitRef_Wrap((JitOptSymbol *)f);
|
||||
new_frame = PyJitRef_WrapInvalid(f);
|
||||
stack_pointer[-1] = new_frame;
|
||||
break;
|
||||
}
|
||||
@ -2662,7 +2662,7 @@
|
||||
break;
|
||||
}
|
||||
new_frame->stack[0] = sym_new_const(ctx, Py_None);
|
||||
gen_frame = PyJitRef_Wrap((JitOptSymbol *)new_frame);
|
||||
gen_frame = PyJitRef_WrapInvalid(new_frame);
|
||||
CHECK_STACK_BOUNDS(1);
|
||||
stack_pointer[0] = gen_frame;
|
||||
stack_pointer += 1;
|
||||
@ -2846,7 +2846,7 @@
|
||||
ctx->done = true;
|
||||
break;
|
||||
}
|
||||
new_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co, 0, NULL, 0));
|
||||
new_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, NULL, 0));
|
||||
CHECK_STACK_BOUNDS(-1 - oparg);
|
||||
stack_pointer[-2 - oparg] = new_frame;
|
||||
stack_pointer += -1 - oparg;
|
||||
@ -2978,9 +2978,9 @@
|
||||
argcount++;
|
||||
}
|
||||
if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) {
|
||||
new_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co, 0, args, argcount));
|
||||
new_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, args, argcount));
|
||||
} else {
|
||||
new_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co, 0, NULL, 0));
|
||||
new_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, NULL, 0));
|
||||
}
|
||||
CHECK_STACK_BOUNDS(-1 - oparg);
|
||||
stack_pointer[-2 - oparg] = new_frame;
|
||||
@ -3175,7 +3175,7 @@
|
||||
ctx->curr_frame_depth++;
|
||||
assert((this_instr + 1)->opcode == _PUSH_FRAME);
|
||||
PyCodeObject *co = get_code_with_logging((this_instr + 1));
|
||||
init_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co, 0, args-1, oparg+1));
|
||||
init_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, args-1, oparg+1));
|
||||
CHECK_STACK_BOUNDS(-1 - oparg);
|
||||
stack_pointer[-2 - oparg] = init_frame;
|
||||
stack_pointer += -1 - oparg;
|
||||
@ -3441,7 +3441,7 @@
|
||||
ctx->done = true;
|
||||
break;
|
||||
}
|
||||
new_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co, 0, NULL, 0));
|
||||
new_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, NULL, 0));
|
||||
CHECK_STACK_BOUNDS(-2 - oparg);
|
||||
stack_pointer[-3 - oparg] = new_frame;
|
||||
stack_pointer += -2 - oparg;
|
||||
@ -3493,7 +3493,7 @@
|
||||
ctx->done = true;
|
||||
break;
|
||||
}
|
||||
ex_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co, 0, NULL, 0));
|
||||
ex_frame = PyJitRef_WrapInvalid(frame_new(ctx, co, 0, NULL, 0));
|
||||
CHECK_STACK_BOUNDS(-3);
|
||||
stack_pointer[-4] = ex_frame;
|
||||
stack_pointer += -3;
|
||||
|
||||
@ -68,6 +68,57 @@ static inline int get_lltrace(void) {
|
||||
}
|
||||
#define DPRINTF(level, ...) \
|
||||
if (get_lltrace() >= (level)) { printf(__VA_ARGS__); }
|
||||
|
||||
void
|
||||
_PyUOpSymPrint(JitOptRef ref)
|
||||
{
|
||||
if (PyJitRef_IsNull(ref)) {
|
||||
printf("<JitRef NULL>");
|
||||
return;
|
||||
}
|
||||
if (PyJitRef_IsInvalid(ref)) {
|
||||
printf("<INVALID frame at %p>", (void *)PyJitRef_Unwrap(ref));
|
||||
return;
|
||||
}
|
||||
JitOptSymbol *sym = PyJitRef_Unwrap(ref);
|
||||
switch (sym->tag) {
|
||||
case JIT_SYM_UNKNOWN_TAG:
|
||||
printf("<? at %p>", (void *)sym);
|
||||
break;
|
||||
case JIT_SYM_NULL_TAG:
|
||||
printf("<NULL at %p>", (void *)sym);
|
||||
break;
|
||||
case JIT_SYM_NON_NULL_TAG:
|
||||
printf("<!NULL at %p>", (void *)sym);
|
||||
break;
|
||||
case JIT_SYM_BOTTOM_TAG:
|
||||
printf("<BOTTOM at %p>", (void *)sym);
|
||||
break;
|
||||
case JIT_SYM_TYPE_VERSION_TAG:
|
||||
printf("<v%u at %p>", sym->version.version, (void *)sym);
|
||||
break;
|
||||
case JIT_SYM_KNOWN_CLASS_TAG:
|
||||
printf("<%s at %p>", sym->cls.type->tp_name, (void *)sym);
|
||||
break;
|
||||
case JIT_SYM_KNOWN_VALUE_TAG:
|
||||
printf("<%s val=%p at %p>", Py_TYPE(sym->value.value)->tp_name,
|
||||
(void *)sym->value.value, (void *)sym);
|
||||
break;
|
||||
case JIT_SYM_TUPLE_TAG:
|
||||
printf("<tuple[%d] at %p>", sym->tuple.length, (void *)sym);
|
||||
break;
|
||||
case JIT_SYM_TRUTHINESS_TAG:
|
||||
printf("<truthiness%s at %p>", sym->truthiness.invert ? "!" : "", (void *)sym);
|
||||
break;
|
||||
case JIT_SYM_COMPACT_INT:
|
||||
printf("<compact_int at %p>", (void *)sym);
|
||||
break;
|
||||
default:
|
||||
printf("<tag=%d at %p>", sym->tag, (void *)sym);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#define DPRINTF(level, ...)
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user