GH-139109: Support switch/case dispatch with the tracing interpreter. (GH-141703)

This commit is contained in:
Mark Shannon 2025-11-18 13:31:48 +00:00 committed by GitHub
parent b87613f214
commit b420f6be53
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 617 additions and 585 deletions

View file

@ -286,6 +286,7 @@ Known values:
Python 3.15a1 3653 (Fix handling of opcodes that may leave operands on the stack when optimizing LOAD_FAST)
Python 3.15a1 3654 (Fix missing exception handlers in logical expression)
Python 3.15a1 3655 (Fix miscompilation of some module-level annotations)
Python 3.15a1 3656 (Add TRACE_RECORD instruction, for platforms with switch based interpreter)
Python 3.16 will start with 3700
@ -299,7 +300,7 @@ PC/launcher.c must also be updated.
*/
#define PYC_MAGIC_NUMBER 3655
#define PYC_MAGIC_NUMBER 3656
/* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes
(little-endian) and then appending b'\r\n'. */
#define PYC_MAGIC_NUMBER_TOKEN \

View file

@ -488,6 +488,8 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
return 1;
case TO_BOOL_STR:
return 1;
case TRACE_RECORD:
return 0;
case UNARY_INVERT:
return 1;
case UNARY_NEGATIVE:
@ -971,6 +973,8 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
return 1;
case TO_BOOL_STR:
return 1;
case TRACE_RECORD:
return 0;
case UNARY_INVERT:
return 1;
case UNARY_NEGATIVE:
@ -1287,6 +1291,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
[TO_BOOL_LIST] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
[TO_BOOL_NONE] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG },
[TO_BOOL_STR] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
[TRACE_RECORD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[UNARY_INVERT] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[UNARY_NEGATIVE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[UNARY_NOT] = { true, INSTR_FMT_IX, HAS_PURE_FLAG },
@ -1738,6 +1743,7 @@ const char *_PyOpcode_OpName[267] = {
[TO_BOOL_LIST] = "TO_BOOL_LIST",
[TO_BOOL_NONE] = "TO_BOOL_NONE",
[TO_BOOL_STR] = "TO_BOOL_STR",
[TRACE_RECORD] = "TRACE_RECORD",
[UNARY_INVERT] = "UNARY_INVERT",
[UNARY_NEGATIVE] = "UNARY_NEGATIVE",
[UNARY_NOT] = "UNARY_NOT",
@ -1809,7 +1815,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
[230] = 230,
[231] = 231,
[232] = 232,
[233] = 233,
[BINARY_OP] = BINARY_OP,
[BINARY_OP_ADD_FLOAT] = BINARY_OP,
[BINARY_OP_ADD_INT] = BINARY_OP,
@ -2025,6 +2030,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
[TO_BOOL_LIST] = TO_BOOL,
[TO_BOOL_NONE] = TO_BOOL,
[TO_BOOL_STR] = TO_BOOL,
[TRACE_RECORD] = TRACE_RECORD,
[UNARY_INVERT] = UNARY_INVERT,
[UNARY_NEGATIVE] = UNARY_NEGATIVE,
[UNARY_NOT] = UNARY_NOT,
@ -2070,7 +2076,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
case 230: \
case 231: \
case 232: \
case 233: \
;
struct pseudo_targets {
uint8_t as_sequence;

View file

@ -364,7 +364,7 @@ extern void _Py_ClearExecutorDeletionList(PyInterpreterState *interp);
int _PyJit_translate_single_bytecode_to_trace(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *next_instr, int stop_tracing_opcode);
int
PyAPI_FUNC(int)
_PyJit_TryInitializeTracing(PyThreadState *tstate, _PyInterpreterFrame *frame,
_Py_CODEUNIT *curr_instr, _Py_CODEUNIT *start_instr,
_Py_CODEUNIT *close_loop_instr, int curr_stackdepth, int chain_depth, _PyExitData *exit,

View file

@ -352,6 +352,7 @@ extern "C" {
#define _TO_BOOL_LIST 550
#define _TO_BOOL_NONE TO_BOOL_NONE
#define _TO_BOOL_STR 551
#define _TRACE_RECORD TRACE_RECORD
#define _UNARY_INVERT UNARY_INVERT
#define _UNARY_NEGATIVE UNARY_NEGATIVE
#define _UNARY_NOT UNARY_NOT

47
Include/opcode_ids.h generated
View file

@ -213,28 +213,29 @@ extern "C" {
#define UNPACK_SEQUENCE_LIST 207
#define UNPACK_SEQUENCE_TUPLE 208
#define UNPACK_SEQUENCE_TWO_TUPLE 209
#define INSTRUMENTED_END_FOR 234
#define INSTRUMENTED_POP_ITER 235
#define INSTRUMENTED_END_SEND 236
#define INSTRUMENTED_FOR_ITER 237
#define INSTRUMENTED_INSTRUCTION 238
#define INSTRUMENTED_JUMP_FORWARD 239
#define INSTRUMENTED_NOT_TAKEN 240
#define INSTRUMENTED_POP_JUMP_IF_TRUE 241
#define INSTRUMENTED_POP_JUMP_IF_FALSE 242
#define INSTRUMENTED_POP_JUMP_IF_NONE 243
#define INSTRUMENTED_POP_JUMP_IF_NOT_NONE 244
#define INSTRUMENTED_RESUME 245
#define INSTRUMENTED_RETURN_VALUE 246
#define INSTRUMENTED_YIELD_VALUE 247
#define INSTRUMENTED_END_ASYNC_FOR 248
#define INSTRUMENTED_LOAD_SUPER_ATTR 249
#define INSTRUMENTED_CALL 250
#define INSTRUMENTED_CALL_KW 251
#define INSTRUMENTED_CALL_FUNCTION_EX 252
#define INSTRUMENTED_JUMP_BACKWARD 253
#define INSTRUMENTED_LINE 254
#define ENTER_EXECUTOR 255
#define INSTRUMENTED_END_FOR 233
#define INSTRUMENTED_POP_ITER 234
#define INSTRUMENTED_END_SEND 235
#define INSTRUMENTED_FOR_ITER 236
#define INSTRUMENTED_INSTRUCTION 237
#define INSTRUMENTED_JUMP_FORWARD 238
#define INSTRUMENTED_NOT_TAKEN 239
#define INSTRUMENTED_POP_JUMP_IF_TRUE 240
#define INSTRUMENTED_POP_JUMP_IF_FALSE 241
#define INSTRUMENTED_POP_JUMP_IF_NONE 242
#define INSTRUMENTED_POP_JUMP_IF_NOT_NONE 243
#define INSTRUMENTED_RESUME 244
#define INSTRUMENTED_RETURN_VALUE 245
#define INSTRUMENTED_YIELD_VALUE 246
#define INSTRUMENTED_END_ASYNC_FOR 247
#define INSTRUMENTED_LOAD_SUPER_ATTR 248
#define INSTRUMENTED_CALL 249
#define INSTRUMENTED_CALL_KW 250
#define INSTRUMENTED_CALL_FUNCTION_EX 251
#define INSTRUMENTED_JUMP_BACKWARD 252
#define INSTRUMENTED_LINE 253
#define ENTER_EXECUTOR 254
#define TRACE_RECORD 255
#define ANNOTATIONS_PLACEHOLDER 256
#define JUMP 257
#define JUMP_IF_FALSE 258
@ -249,7 +250,7 @@ extern "C" {
#define HAVE_ARGUMENT 43
#define MIN_SPECIALIZED_OPCODE 129
#define MIN_INSTRUMENTED_OPCODE 234
#define MIN_INSTRUMENTED_OPCODE 233
#ifdef __cplusplus
}