From f79e7d17d8dcb37b822393951b594713cbd50c1c Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 21 Jan 2025 09:33:35 +0800 Subject: [PATCH 01/14] Move lltrace into the frame struct --- Include/internal/pycore_frame.h | 3 +++ Python/bytecodes.c | 4 ++-- Python/ceval.c | 24 ++++++++++++++---------- Python/ceval_macros.h | 7 ++++--- Python/executor_cases.c.h | 4 ++-- 5 files changed, 25 insertions(+), 17 deletions(-) diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h index 96ae4dd22ecb43..3f3edd0ffff061 100644 --- a/Include/internal/pycore_frame.h +++ b/Include/internal/pycore_frame.h @@ -76,6 +76,9 @@ typedef struct _PyInterpreterFrame { uint16_t return_offset; /* Only relevant during a function call */ char owner; char visited; +#ifdef Py_DEBUG + char lltrace; +#endif /* Locals and stack */ _PyStackRef localsplus[1]; } _PyInterpreterFrame; diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 398f1d564fad4a..ec21e81ed0ba00 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -4993,7 +4993,7 @@ dummy_func( _Py_CODEUNIT *target = _PyFrame_GetBytecode(frame) + exit->target; #if defined(Py_DEBUG) && !defined(_Py_JIT) OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); - if (lltrace >= 2) { + if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 2) { printf("SIDE EXIT: [UOp "); _PyUOpPrint(&next_uop[-1]); printf(", exit %u, temp %d, target %d -> %s]\n", @@ -5111,7 +5111,7 @@ dummy_func( _Py_CODEUNIT *target = frame->instr_ptr; #if defined(Py_DEBUG) && !defined(_Py_JIT) OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); - if (lltrace >= 2) { + if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 2) { printf("DYNAMIC EXIT: [UOp "); _PyUOpPrint(&next_uop[-1]); printf(", exit %u, temp %d, target %d -> %s]\n", diff --git a/Python/ceval.c b/Python/ceval.c index 28b0b4c6de39a7..fd1e62cd042100 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -799,9 +799,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int #endif uint8_t opcode; /* Current opcode */ int oparg; /* Current opcode argument, if any */ -#ifdef LLTRACE - int lltrace = 0; -#endif _PyInterpreterFrame entry_frame; @@ -821,6 +818,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int entry_frame.owner = FRAME_OWNED_BY_CSTACK; entry_frame.visited = 0; entry_frame.return_offset = 0; +#ifdef LLTRACE + entry_frame.lltrace = 0; +#endif /* Push frame */ entry_frame.previous = tstate->current_frame; frame->previous = &entry_frame; @@ -880,9 +880,13 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int stack_pointer = _PyFrame_GetStackPointer(frame); #ifdef LLTRACE - lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); - if (lltrace < 0) { - goto exit_unwind; + { + int lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, + GLOBALS()); + FT_ATOMIC_STORE_UINT8_RELAXED(frame->lltrace, (uint8_t)lltrace); + if (lltrace < 0) { + goto exit_unwind; + } } #endif @@ -1002,7 +1006,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } /* Resume normal execution */ #ifdef LLTRACE - if (lltrace >= 5) { + if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 5) { lltrace_resume_frame(frame); } #endif @@ -1079,7 +1083,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int for (;;) { uopcode = next_uop->opcode; #ifdef Py_DEBUG - if (lltrace >= 3) { + if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 3) { dump_stack(frame, stack_pointer); if (next_uop->opcode == _START_EXECUTOR) { printf("%4d uop: ", 0); @@ -1121,7 +1125,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int jump_to_error_target: #ifdef Py_DEBUG - if (lltrace >= 2) { + if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 2) { printf("Error: [UOp "); _PyUOpPrint(&next_uop[-1]); printf(" @ %d -> %s]\n", @@ -1157,7 +1161,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int next_instr = next_uop[-1].target + _PyFrame_GetBytecode(frame); goto_to_tier1: #ifdef Py_DEBUG - if (lltrace >= 2) { + if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 2) { printf("DEOPT: [UOp "); _PyUOpPrint(&next_uop[-1]); printf(" -> %s]\n", diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index c37e1cf3afa60e..01b3c16190de57 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -80,7 +80,7 @@ /* PRE_DISPATCH_GOTO() does lltrace if enabled. Normally a no-op */ #ifdef LLTRACE -#define PRE_DISPATCH_GOTO() if (lltrace >= 5) { \ +#define PRE_DISPATCH_GOTO() if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 5) { \ lltrace_instruction(frame, stack_pointer, next_instr, opcode, oparg); } #else #define PRE_DISPATCH_GOTO() ((void)0) @@ -89,7 +89,8 @@ #if LLTRACE #define LLTRACE_RESUME_FRAME() \ do { \ - lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); \ + int lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); \ + FT_ATOMIC_STORE_UINT8_RELAXED(frame->lltrace, (uint8_t)lltrace); \ if (lltrace < 0) { \ goto exit_unwind; \ } \ @@ -153,7 +154,7 @@ GETITEM(PyObject *v, Py_ssize_t i) { /* The integer overflow is checked by an assertion below. */ #define INSTR_OFFSET() ((int)(next_instr - _PyFrame_GetBytecode(frame))) #define NEXTOPARG() do { \ - _Py_CODEUNIT word = {.cache = FT_ATOMIC_LOAD_UINT16_RELAXED(*(uint16_t*)next_instr)}; \ + _Py_CODEUNIT word = {.cache = FT_ATOMIC_LOAD_UINT8_RELAXED(*(uint16_t*)next_instr)}; \ opcode = word.op.code; \ oparg = word.op.arg; \ } while (0) diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 049073162b6c5f..9894add4a75a03 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -5882,7 +5882,7 @@ stack_pointer = _PyFrame_GetStackPointer(frame); #if defined(Py_DEBUG) && !defined(_Py_JIT) OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); - if (lltrace >= 2) { + if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 2) { _PyFrame_SetStackPointer(frame, stack_pointer); printf("SIDE EXIT: [UOp "); _PyUOpPrint(&next_uop[-1]); @@ -6076,7 +6076,7 @@ _Py_CODEUNIT *target = frame->instr_ptr; #if defined(Py_DEBUG) && !defined(_Py_JIT) OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); - if (lltrace >= 2) { + if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 2) { _PyFrame_SetStackPointer(frame, stack_pointer); printf("DYNAMIC EXIT: [UOp "); _PyUOpPrint(&next_uop[-1]); From da0d7ae1b0b4e42c03ce8798b688cdd49627c02b Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 21 Jan 2025 09:43:45 +0800 Subject: [PATCH 02/14] fix free-threaded --- Include/internal/pycore_frame.h | 2 +- Python/ceval_macros.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h index 3f3edd0ffff061..7af48c1108af1f 100644 --- a/Include/internal/pycore_frame.h +++ b/Include/internal/pycore_frame.h @@ -77,7 +77,7 @@ typedef struct _PyInterpreterFrame { char owner; char visited; #ifdef Py_DEBUG - char lltrace; + unsigned char lltrace; #endif /* Locals and stack */ _PyStackRef localsplus[1]; diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index 01b3c16190de57..6fcacb720032c1 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -154,7 +154,7 @@ GETITEM(PyObject *v, Py_ssize_t i) { /* The integer overflow is checked by an assertion below. */ #define INSTR_OFFSET() ((int)(next_instr - _PyFrame_GetBytecode(frame))) #define NEXTOPARG() do { \ - _Py_CODEUNIT word = {.cache = FT_ATOMIC_LOAD_UINT8_RELAXED(*(uint16_t*)next_instr)}; \ + _Py_CODEUNIT word = {.cache = FT_ATOMIC_LOAD_UINT16_RELAXED(*(uint16_t*)next_instr)}; \ opcode = word.op.code; \ oparg = word.op.arg; \ } while (0) From 989f841402017eb06377b22a8fdf0b753fd78fdb Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 21 Jan 2025 09:46:16 +0800 Subject: [PATCH 03/14] Cleanup --- .gitattributes | 1 + Tools/c-analyzer/cpython/_parser.py | 1 + 2 files changed, 2 insertions(+) diff --git a/.gitattributes b/.gitattributes index 2f5a030981fb94..67b5a56eed564f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -95,6 +95,7 @@ Programs/test_frozenmain.h generated Python/Python-ast.c generated Python/executor_cases.c.h generated Python/generated_cases.c.h generated +Python/generated_labels.c.h generated Python/optimizer_cases.c.h generated Python/opcode_targets.h generated Python/stdlib_module_names.h generated diff --git a/Tools/c-analyzer/cpython/_parser.py b/Tools/c-analyzer/cpython/_parser.py index a08b32fa45db3e..396d840dc43f12 100644 --- a/Tools/c-analyzer/cpython/_parser.py +++ b/Tools/c-analyzer/cpython/_parser.py @@ -80,6 +80,7 @@ def clean_lines(text): Python/deepfreeze/*.c Python/frozen_modules/*.h Python/generated_cases.c.h +Python/generated_labels.c.h Python/executor_cases.c.h Python/optimizer_cases.c.h From 80361992ea50233f925af6e82e67588ef2ddc0a7 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 21 Jan 2025 11:05:16 +0800 Subject: [PATCH 04/14] Try fix on Windows --- Lib/test/test_sys.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index d839893d2c657e..d2c45e61a80802 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1621,9 +1621,9 @@ def func(): return sys._getframe() x = func() if support.Py_GIL_DISABLED: - INTERPRETER_FRAME = '10PhcP' + INTERPRETER_FRAME = '10PhccP' else: - INTERPRETER_FRAME = '9PhcP' + INTERPRETER_FRAME = '9PhcccP' check(x, size('3PiccPP' + INTERPRETER_FRAME + 'P')) # function def func(): pass From d3d1dbfc1c781763802346648f639650c5280c80 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 21 Jan 2025 11:44:38 +0800 Subject: [PATCH 05/14] Fix test_wasi --- Lib/test/test_sys.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index d2c45e61a80802..3b2b22dbf69fec 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1620,10 +1620,11 @@ class C(object): pass def func(): return sys._getframe() x = func() + LLTRACE = 'c' if support.Py_DEBUG else '' if support.Py_GIL_DISABLED: - INTERPRETER_FRAME = '10PhccP' + INTERPRETER_FRAME = f'10Phc{LLTRACE}P' else: - INTERPRETER_FRAME = '9PhcccP' + INTERPRETER_FRAME = f'9Phc{LLTRACE}P' check(x, size('3PiccPP' + INTERPRETER_FRAME + 'P')) # function def func(): pass From e062681613635297cccbb709449e19732d53a4f3 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 21 Jan 2025 12:48:06 +0800 Subject: [PATCH 06/14] fix for real --- Lib/test/test_sys.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 3b2b22dbf69fec..b77e17b6a8d5d7 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1620,11 +1620,11 @@ class C(object): pass def func(): return sys._getframe() x = func() - LLTRACE = 'c' if support.Py_DEBUG else '' + LLTRACE = 'B' if support.Py_DEBUG else '' if support.Py_GIL_DISABLED: - INTERPRETER_FRAME = f'10Phc{LLTRACE}P' + INTERPRETER_FRAME = f'10Phcc{LLTRACE}P' else: - INTERPRETER_FRAME = f'9Phc{LLTRACE}P' + INTERPRETER_FRAME = f'9Phcc{LLTRACE}P' check(x, size('3PiccPP' + INTERPRETER_FRAME + 'P')) # function def func(): pass From 6ba4e59df4beb8cdc900345429d9947f8f9849af Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 21 Jan 2025 12:54:43 +0800 Subject: [PATCH 07/14] 8 -> 16 --- Python/ceval.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index fd1e62cd042100..033c34e7ad4921 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -883,7 +883,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int { int lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); - FT_ATOMIC_STORE_UINT8_RELAXED(frame->lltrace, (uint8_t)lltrace); + FT_ATOMIC_STORE_UINT16_RELAXED(frame->lltrace, (uint8_t)lltrace); if (lltrace < 0) { goto exit_unwind; } @@ -1006,7 +1006,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } /* Resume normal execution */ #ifdef LLTRACE - if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 5) { + if (FT_ATOMIC_LOAD_UINT16_RELAXED(frame->lltrace) >= 5) { lltrace_resume_frame(frame); } #endif @@ -1083,7 +1083,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int for (;;) { uopcode = next_uop->opcode; #ifdef Py_DEBUG - if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 3) { + if (FT_ATOMIC_LOAD_UINT16_RELAXED(frame->lltrace) >= 3) { dump_stack(frame, stack_pointer); if (next_uop->opcode == _START_EXECUTOR) { printf("%4d uop: ", 0); @@ -1125,7 +1125,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int jump_to_error_target: #ifdef Py_DEBUG - if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 2) { + if (FT_ATOMIC_LOAD_UINT16_RELAXED(frame->lltrace) >= 2) { printf("Error: [UOp "); _PyUOpPrint(&next_uop[-1]); printf(" @ %d -> %s]\n", @@ -1161,7 +1161,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int next_instr = next_uop[-1].target + _PyFrame_GetBytecode(frame); goto_to_tier1: #ifdef Py_DEBUG - if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 2) { + if (FT_ATOMIC_LOAD_UINT16_RELAXED(frame->lltrace) >= 2) { printf("DEOPT: [UOp "); _PyUOpPrint(&next_uop[-1]); printf(" -> %s]\n", From 959ba82677bf2eb6e273e0eca00a2710f331261c Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 21 Jan 2025 12:56:18 +0800 Subject: [PATCH 08/14] Revert "8 -> 16" This reverts commit 6ba4e59df4beb8cdc900345429d9947f8f9849af. --- Python/ceval.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index 033c34e7ad4921..fd1e62cd042100 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -883,7 +883,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int { int lltrace = maybe_lltrace_resume_frame(frame, &entry_frame, GLOBALS()); - FT_ATOMIC_STORE_UINT16_RELAXED(frame->lltrace, (uint8_t)lltrace); + FT_ATOMIC_STORE_UINT8_RELAXED(frame->lltrace, (uint8_t)lltrace); if (lltrace < 0) { goto exit_unwind; } @@ -1006,7 +1006,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } /* Resume normal execution */ #ifdef LLTRACE - if (FT_ATOMIC_LOAD_UINT16_RELAXED(frame->lltrace) >= 5) { + if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 5) { lltrace_resume_frame(frame); } #endif @@ -1083,7 +1083,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int for (;;) { uopcode = next_uop->opcode; #ifdef Py_DEBUG - if (FT_ATOMIC_LOAD_UINT16_RELAXED(frame->lltrace) >= 3) { + if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 3) { dump_stack(frame, stack_pointer); if (next_uop->opcode == _START_EXECUTOR) { printf("%4d uop: ", 0); @@ -1125,7 +1125,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int jump_to_error_target: #ifdef Py_DEBUG - if (FT_ATOMIC_LOAD_UINT16_RELAXED(frame->lltrace) >= 2) { + if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 2) { printf("Error: [UOp "); _PyUOpPrint(&next_uop[-1]); printf(" @ %d -> %s]\n", @@ -1161,7 +1161,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int next_instr = next_uop[-1].target + _PyFrame_GetBytecode(frame); goto_to_tier1: #ifdef Py_DEBUG - if (FT_ATOMIC_LOAD_UINT16_RELAXED(frame->lltrace) >= 2) { + if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 2) { printf("DEOPT: [UOp "); _PyUOpPrint(&next_uop[-1]); printf(" -> %s]\n", From 134d2a0e336176209f0570749406652dad4978af Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 21 Jan 2025 15:51:51 +0800 Subject: [PATCH 09/14] reduce diff --- .gitattributes | 1 - Tools/c-analyzer/cpython/_parser.py | 1 - 2 files changed, 2 deletions(-) diff --git a/.gitattributes b/.gitattributes index 67b5a56eed564f..2f5a030981fb94 100644 --- a/.gitattributes +++ b/.gitattributes @@ -95,7 +95,6 @@ Programs/test_frozenmain.h generated Python/Python-ast.c generated Python/executor_cases.c.h generated Python/generated_cases.c.h generated -Python/generated_labels.c.h generated Python/optimizer_cases.c.h generated Python/opcode_targets.h generated Python/stdlib_module_names.h generated diff --git a/Tools/c-analyzer/cpython/_parser.py b/Tools/c-analyzer/cpython/_parser.py index 396d840dc43f12..a08b32fa45db3e 100644 --- a/Tools/c-analyzer/cpython/_parser.py +++ b/Tools/c-analyzer/cpython/_parser.py @@ -80,7 +80,6 @@ def clean_lines(text): Python/deepfreeze/*.c Python/frozen_modules/*.h Python/generated_cases.c.h -Python/generated_labels.c.h Python/executor_cases.c.h Python/optimizer_cases.c.h From 732c6b4be69dc11a9b09209d6daabcbb9d12d770 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 21 Jan 2025 18:28:21 +0800 Subject: [PATCH 10/14] Address review --- Include/internal/pycore_frame.h | 6 ++++-- Lib/test/test_sys.py | 5 ++--- Python/bytecodes.c | 4 ++-- Python/ceval.c | 8 ++++---- Python/ceval_macros.h | 2 +- Python/executor_cases.c.h | 4 ++-- 6 files changed, 15 insertions(+), 14 deletions(-) diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h index 7af48c1108af1f..a8c06fbe57c0f7 100644 --- a/Include/internal/pycore_frame.h +++ b/Include/internal/pycore_frame.h @@ -75,9 +75,11 @@ typedef struct _PyInterpreterFrame { _PyStackRef *stackpointer; uint16_t return_offset; /* Only relevant during a function call */ char owner; - char visited; #ifdef Py_DEBUG - unsigned char lltrace; + char visited:4; + char lltrace:4; +#else + char visited; #endif /* Locals and stack */ _PyStackRef localsplus[1]; diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index b77e17b6a8d5d7..57f7a3bebef778 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1620,11 +1620,10 @@ class C(object): pass def func(): return sys._getframe() x = func() - LLTRACE = 'B' if support.Py_DEBUG else '' if support.Py_GIL_DISABLED: - INTERPRETER_FRAME = f'10Phcc{LLTRACE}P' + INTERPRETER_FRAME = f'10PhcP' else: - INTERPRETER_FRAME = f'9Phcc{LLTRACE}P' + INTERPRETER_FRAME = f'9PhcP' check(x, size('3PiccPP' + INTERPRETER_FRAME + 'P')) # function def func(): pass diff --git a/Python/bytecodes.c b/Python/bytecodes.c index ec21e81ed0ba00..c951abf4bd6a54 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -4993,7 +4993,7 @@ dummy_func( _Py_CODEUNIT *target = _PyFrame_GetBytecode(frame) + exit->target; #if defined(Py_DEBUG) && !defined(_Py_JIT) OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); - if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 2) { + if (frame->lltrace >= 2) { printf("SIDE EXIT: [UOp "); _PyUOpPrint(&next_uop[-1]); printf(", exit %u, temp %d, target %d -> %s]\n", @@ -5111,7 +5111,7 @@ dummy_func( _Py_CODEUNIT *target = frame->instr_ptr; #if defined(Py_DEBUG) && !defined(_Py_JIT) OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); - if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 2) { + if (frame->lltrace >= 2) { printf("DYNAMIC EXIT: [UOp "); _PyUOpPrint(&next_uop[-1]); printf(", exit %u, temp %d, target %d -> %s]\n", diff --git a/Python/ceval.c b/Python/ceval.c index fd1e62cd042100..5556c4766658c6 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1006,7 +1006,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } /* Resume normal execution */ #ifdef LLTRACE - if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 5) { + if (frame->lltrace >= 5) { lltrace_resume_frame(frame); } #endif @@ -1083,7 +1083,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int for (;;) { uopcode = next_uop->opcode; #ifdef Py_DEBUG - if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 3) { + if (frame->lltrace >= 3) { dump_stack(frame, stack_pointer); if (next_uop->opcode == _START_EXECUTOR) { printf("%4d uop: ", 0); @@ -1125,7 +1125,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int jump_to_error_target: #ifdef Py_DEBUG - if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 2) { + if (frame->lltrace >= 2) { printf("Error: [UOp "); _PyUOpPrint(&next_uop[-1]); printf(" @ %d -> %s]\n", @@ -1161,7 +1161,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int next_instr = next_uop[-1].target + _PyFrame_GetBytecode(frame); goto_to_tier1: #ifdef Py_DEBUG - if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 2) { + if (frame->lltrace >= 2) { printf("DEOPT: [UOp "); _PyUOpPrint(&next_uop[-1]); printf(" -> %s]\n", diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index 6fcacb720032c1..edcb3caf1c7361 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -80,7 +80,7 @@ /* PRE_DISPATCH_GOTO() does lltrace if enabled. Normally a no-op */ #ifdef LLTRACE -#define PRE_DISPATCH_GOTO() if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 5) { \ +#define PRE_DISPATCH_GOTO() if (frame->lltrace >= 5) { \ lltrace_instruction(frame, stack_pointer, next_instr, opcode, oparg); } #else #define PRE_DISPATCH_GOTO() ((void)0) diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 9894add4a75a03..0e82db31b3f1c9 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -5882,7 +5882,7 @@ stack_pointer = _PyFrame_GetStackPointer(frame); #if defined(Py_DEBUG) && !defined(_Py_JIT) OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); - if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 2) { + if (frame->lltrace >= 2) { _PyFrame_SetStackPointer(frame, stack_pointer); printf("SIDE EXIT: [UOp "); _PyUOpPrint(&next_uop[-1]); @@ -6076,7 +6076,7 @@ _Py_CODEUNIT *target = frame->instr_ptr; #if defined(Py_DEBUG) && !defined(_Py_JIT) OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); - if (FT_ATOMIC_LOAD_UINT8_RELAXED(frame->lltrace) >= 2) { + if (frame->lltrace >= 2) { _PyFrame_SetStackPointer(frame, stack_pointer); printf("DYNAMIC EXIT: [UOp "); _PyUOpPrint(&next_uop[-1]); From a28f2c5df63d5cc61759f8762d00e402d72e797a Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 21 Jan 2025 18:35:00 +0800 Subject: [PATCH 11/14] reduce diff --- Lib/test/test_sys.py | 4 ++-- Python/ceval_macros.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 57f7a3bebef778..d839893d2c657e 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1621,9 +1621,9 @@ def func(): return sys._getframe() x = func() if support.Py_GIL_DISABLED: - INTERPRETER_FRAME = f'10PhcP' + INTERPRETER_FRAME = '10PhcP' else: - INTERPRETER_FRAME = f'9PhcP' + INTERPRETER_FRAME = '9PhcP' check(x, size('3PiccPP' + INTERPRETER_FRAME + 'P')) # function def func(): pass diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index 829a57361a4ee3..7d3597fe2f45f9 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -89,7 +89,7 @@ #if LLTRACE #define LLTRACE_RESUME_FRAME() \ do { \ - lltrace = maybe_lltrace_resume_frame(frame, GLOBALS()); \ + int lltrace = maybe_lltrace_resume_frame(frame, GLOBALS()); \ frame->lltrace = lltrace; if (lltrace < 0) { \ goto exit_unwind; \ From ef209dbbb24057e19360fad74ab672d2b65f2586 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 21 Jan 2025 18:41:51 +0800 Subject: [PATCH 12/14] fix build --- Python/ceval.c | 2 +- Python/ceval_macros.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index af32614d9df1c5..58a54467f06bb0 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -882,7 +882,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int #ifdef LLTRACE { int lltrace = maybe_lltrace_resume_frame(frame, GLOBALS()); - FT_ATOMIC_STORE_UINT8_RELAXED(frame->lltrace, (uint8_t)lltrace); + frame->lltrace = lltrace; if (lltrace < 0) { goto exit_unwind; } diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index 7d3597fe2f45f9..feaac07fe435b6 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -90,7 +90,7 @@ #define LLTRACE_RESUME_FRAME() \ do { \ int lltrace = maybe_lltrace_resume_frame(frame, GLOBALS()); \ - frame->lltrace = lltrace; + frame->lltrace = lltrace; \ if (lltrace < 0) { \ goto exit_unwind; \ } \ From 3f51e08f363a6994497dc1bf53d524863ffe0dbd Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 21 Jan 2025 19:52:30 +0800 Subject: [PATCH 13/14] Address review --- Include/internal/pycore_frame.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h index 8d9ba22ec9ef37..191abf8b958302 100644 --- a/Include/internal/pycore_frame.h +++ b/Include/internal/pycore_frame.h @@ -77,10 +77,10 @@ typedef struct _PyInterpreterFrame { uint16_t return_offset; /* Only relevant during a function call */ char owner; #ifdef Py_DEBUG - char visited:4; - char lltrace:4; + char visited:1; + uint8_t lltrace:7; #else - char visited; + uint8_t visited; #endif /* Locals and stack */ _PyStackRef localsplus[1]; From f2cd9686a882c27999664c9f50bcee1ff90c761a Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 21 Jan 2025 21:44:11 +0800 Subject: [PATCH 14/14] fix visited --- Include/internal/pycore_frame.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h index 191abf8b958302..14dc91e54298ce 100644 --- a/Include/internal/pycore_frame.h +++ b/Include/internal/pycore_frame.h @@ -77,7 +77,7 @@ typedef struct _PyInterpreterFrame { uint16_t return_offset; /* Only relevant during a function call */ char owner; #ifdef Py_DEBUG - char visited:1; + uint8_t visited:1; uint8_t lltrace:7; #else uint8_t visited;