From 40bf6c1964d5870f8fe79c5d431417cc8967c133 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Fri, 19 Sep 2025 15:19:38 +0100 Subject: [PATCH] WIP generators --- Include/internal/pycore_interp_structs.h | 7 + Include/internal/pycore_magic_number.h | 3 +- Include/internal/pycore_opcode_metadata.h | 72 +- Include/internal/pycore_optimizer.h | 2 +- Include/internal/pycore_uop.h | 2 +- Include/internal/pycore_uop_ids.h | 351 +++--- Include/internal/pycore_uop_metadata.h | 26 +- Include/opcode_ids.h | 168 +-- Lib/_opcode_metadata.py | 168 +-- Python/bytecodes.c | 110 +- Python/ceval.c | 98 +- Python/ceval_macros.h | 55 +- Python/executor_cases.c.h | 124 +- Python/generated_cases.c.h | 202 ++- Python/opcode_targets.h | 20 +- Python/optimizer.c | 414 ++----- Python/optimizer_analysis.c | 14 +- Python/optimizer_cases.c.h | 33 +- Python/pystate.c | 4 + Tools/cases_generator/analyzer.py | 4 + .../opcode_metadata_generator.py | 11 + Tools/cases_generator/tier2_generator.py | 44 + Tools/cases_generator/tracer_generator.py | 1 + out.txt | 1089 +++++++++++++++++ 24 files changed, 2248 insertions(+), 774 deletions(-) create mode 100644 out.txt diff --git a/Include/internal/pycore_interp_structs.h b/Include/internal/pycore_interp_structs.h index a0a0e8665398..2cd61c215ce0 100644 --- a/Include/internal/pycore_interp_structs.h +++ b/Include/internal/pycore_interp_structs.h @@ -943,9 +943,16 @@ struct _is { struct types_state types; struct callable_cache callable_cache; PyObject *common_consts[NUM_COMMON_CONSTANTS]; + // JIT tracing state int jit_tracer_code_curr_size; _Py_CODEUNIT *jit_tracer_code_buffer; _Py_CODEUNIT *jit_tracer_initial_instr; + int jit_tracer_initial_stack_depth; + int jit_tracer_initial_chain_depth; + PyCodeObject *jit_tracer_initial_code; // Borrowed + PyFunctionObject *jit_tracer_initial_func; // Borrowed + int jit_tracer_seen_initial_before; + bool jit_completed_loop; bool jit; bool compiling; struct _PyUOpInstruction *jit_uop_buffer; diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h index 7ec7bd1c6955..e1f5d29d2b8c 100644 --- a/Include/internal/pycore_magic_number.h +++ b/Include/internal/pycore_magic_number.h @@ -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 GUARD_IP instruction) 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 \ diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index bd6b84ec7fd9..97642c2ff467 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -474,6 +474,10 @@ int _PyOpcode_num_popped(int opcode, int oparg) { return 3; case SWAP: return 2 + (oparg-2); + case TIER1_GUARD_IP: + return 0; + case TIER1_SET_IP: + return 0; case TO_BOOL: return 1; case TO_BOOL_ALWAYS_TRUE: @@ -957,6 +961,10 @@ int _PyOpcode_num_pushed(int opcode, int oparg) { return 0; case SWAP: return 2 + (oparg-2); + case TIER1_GUARD_IP: + return 0; + case TIER1_SET_IP: + return 0; case TO_BOOL: return 1; case TO_BOOL_ALWAYS_TRUE: @@ -1276,6 +1284,8 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [STORE_SUBSCR_DICT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [STORE_SUBSCR_LIST_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, [SWAP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_PURE_FLAG }, + [TIER1_GUARD_IP] = { true, INSTR_FMT_IXC000, HAS_ESCAPES_FLAG | HAS_NO_SAVE_IP_FLAG }, + [TIER1_SET_IP] = { true, INSTR_FMT_IXC000, HAS_ESCAPES_FLAG }, [TO_BOOL] = { true, INSTR_FMT_IXC00, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [TO_BOOL_ALWAYS_TRUE] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, [TO_BOOL_BOOL] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG }, @@ -1394,7 +1404,7 @@ _PyOpcode_macro_expansion[256] = { [FORMAT_WITH_SPEC] = { .nuops = 1, .uops = { { _FORMAT_WITH_SPEC, OPARG_SIMPLE, 0 } } }, [FOR_ITER] = { .nuops = 1, .uops = { { _FOR_ITER, OPARG_REPLACED, 0 } } }, [FOR_ITER_GEN] = { .nuops = 3, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _FOR_ITER_GEN_FRAME, OPARG_SIMPLE, 1 }, { _PUSH_FRAME, OPARG_SIMPLE, 1 } } }, - [FOR_ITER_LIST] = { .nuops = 3, .uops = { { _ITER_CHECK_LIST, OPARG_SIMPLE, 1 }, { _ITER_JUMP_LIST, OPARG_REPLACED, 1 }, { _ITER_NEXT_LIST, OPARG_REPLACED, 1 } } }, + [FOR_ITER_LIST] = { .nuops = 3, .uops = { { _ITER_CHECK_LIST, OPARG_SIMPLE, 1 }, { _ITER_JUMP_LIST, OPARG_REPLACED, 1 }, { _ITER_NEXT_LIST, OPARG_SIMPLE, 1 } } }, [FOR_ITER_RANGE] = { .nuops = 3, .uops = { { _ITER_CHECK_RANGE, OPARG_SIMPLE, 1 }, { _ITER_JUMP_RANGE, OPARG_REPLACED, 1 }, { _ITER_NEXT_RANGE, OPARG_SIMPLE, 1 } } }, [FOR_ITER_TUPLE] = { .nuops = 3, .uops = { { _ITER_CHECK_TUPLE, OPARG_SIMPLE, 1 }, { _ITER_JUMP_TUPLE, OPARG_REPLACED, 1 }, { _ITER_NEXT_TUPLE, OPARG_SIMPLE, 1 } } }, [GET_AITER] = { .nuops = 1, .uops = { { _GET_AITER, OPARG_SIMPLE, 0 } } }, @@ -1406,6 +1416,8 @@ _PyOpcode_macro_expansion[256] = { [IMPORT_FROM] = { .nuops = 1, .uops = { { _IMPORT_FROM, OPARG_SIMPLE, 0 } } }, [IMPORT_NAME] = { .nuops = 1, .uops = { { _IMPORT_NAME, OPARG_SIMPLE, 0 } } }, [IS_OP] = { .nuops = 1, .uops = { { _IS_OP, OPARG_SIMPLE, 0 } } }, + [JUMP_BACKWARD_NO_INTERRUPT] = { .nuops = 1, .uops = { { _JUMP_BACKWARD_NO_INTERRUPT, OPARG_SIMPLE, 0 } } }, + [JUMP_BACKWARD_NO_JIT] = { .nuops = 2, .uops = { { _CHECK_PERIODIC, OPARG_SIMPLE, 1 }, { _JUMP_BACKWARD_NO_INTERRUPT, OPARG_SIMPLE, 1 } } }, [LIST_APPEND] = { .nuops = 1, .uops = { { _LIST_APPEND, OPARG_SIMPLE, 0 } } }, [LIST_EXTEND] = { .nuops = 1, .uops = { { _LIST_EXTEND, OPARG_SIMPLE, 0 } } }, [LOAD_ATTR] = { .nuops = 1, .uops = { { _LOAD_ATTR, OPARG_SIMPLE, 8 } } }, @@ -1452,10 +1464,10 @@ _PyOpcode_macro_expansion[256] = { [NOT_TAKEN] = { .nuops = 1, .uops = { { _NOP, OPARG_SIMPLE, 0 } } }, [POP_EXCEPT] = { .nuops = 1, .uops = { { _POP_EXCEPT, OPARG_SIMPLE, 0 } } }, [POP_ITER] = { .nuops = 1, .uops = { { _POP_ITER, OPARG_SIMPLE, 0 } } }, - [POP_JUMP_IF_FALSE] = { .nuops = 1, .uops = { { _POP_JUMP_IF_FALSE, OPARG_REPLACED, 1 } } }, - [POP_JUMP_IF_NONE] = { .nuops = 2, .uops = { { _IS_NONE, OPARG_SIMPLE, 1 }, { _POP_JUMP_IF_TRUE, OPARG_REPLACED, 1 } } }, - [POP_JUMP_IF_NOT_NONE] = { .nuops = 2, .uops = { { _IS_NONE, OPARG_SIMPLE, 1 }, { _POP_JUMP_IF_FALSE, OPARG_REPLACED, 1 } } }, - [POP_JUMP_IF_TRUE] = { .nuops = 1, .uops = { { _POP_JUMP_IF_TRUE, OPARG_REPLACED, 1 } } }, + [POP_JUMP_IF_FALSE] = { .nuops = 1, .uops = { { _POP_JUMP_IF_FALSE, OPARG_SIMPLE, 1 } } }, + [POP_JUMP_IF_NONE] = { .nuops = 2, .uops = { { _IS_NONE, OPARG_SIMPLE, 1 }, { _POP_JUMP_IF_TRUE, OPARG_SIMPLE, 1 } } }, + [POP_JUMP_IF_NOT_NONE] = { .nuops = 2, .uops = { { _IS_NONE, OPARG_SIMPLE, 1 }, { _POP_JUMP_IF_FALSE, OPARG_SIMPLE, 1 } } }, + [POP_JUMP_IF_TRUE] = { .nuops = 1, .uops = { { _POP_JUMP_IF_TRUE, OPARG_SIMPLE, 1 } } }, [POP_TOP] = { .nuops = 1, .uops = { { _POP_TOP, OPARG_SIMPLE, 0 } } }, [PUSH_EXC_INFO] = { .nuops = 1, .uops = { { _PUSH_EXC_INFO, OPARG_SIMPLE, 0 } } }, [PUSH_NULL] = { .nuops = 1, .uops = { { _PUSH_NULL, OPARG_SIMPLE, 0 } } }, @@ -1724,6 +1736,8 @@ const char *_PyOpcode_OpName[267] = { [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT", [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT", [SWAP] = "SWAP", + [TIER1_GUARD_IP] = "TIER1_GUARD_IP", + [TIER1_SET_IP] = "TIER1_SET_IP", [TO_BOOL] = "TO_BOOL", [TO_BOOL_ALWAYS_TRUE] = "TO_BOOL_ALWAYS_TRUE", [TO_BOOL_BOOL] = "TO_BOOL_BOOL", @@ -1747,6 +1761,8 @@ const char *_PyOpcode_OpName[267] = { extern const uint8_t _PyOpcode_Caches[256]; #ifdef NEED_OPCODE_METADATA const uint8_t _PyOpcode_Caches[256] = { + [TIER1_GUARD_IP] = 4, + [TIER1_SET_IP] = 4, [TO_BOOL] = 3, [STORE_SUBSCR] = 1, [SEND] = 1, @@ -1769,11 +1785,49 @@ const uint8_t _PyOpcode_Caches[256] = { }; #endif +extern const uint8_t _PyOpcode_NeedsGuardIp[256]; +#ifdef NEED_OPCODE_METADATA +const uint8_t _PyOpcode_NeedsGuardIp[256] = { + [INTERPRETER_EXIT] = 1, + [RETURN_VALUE] = 1, + [YIELD_VALUE] = 1, + [JUMP_FORWARD] = 1, + [INSTRUMENTED_FOR_ITER] = 1, + [RETURN_GENERATOR] = 1, + [BINARY_OP_SUBSCR_GETITEM] = 1, + [INSTRUMENTED_RETURN_VALUE] = 1, + [SEND] = 1, + [SEND_GEN] = 1, + [INSTRUMENTED_YIELD_VALUE] = 1, + [INSTRUMENTED_END_ASYNC_FOR] = 1, + [END_ASYNC_FOR] = 1, + [LOAD_ATTR_PROPERTY] = 1, + [JUMP_BACKWARD] = 1, + [JUMP_BACKWARD_NO_JIT] = 1, + [JUMP_BACKWARD_JIT] = 1, + [POP_JUMP_IF_TRUE] = 1, + [POP_JUMP_IF_FALSE] = 1, + [POP_JUMP_IF_NONE] = 1, + [POP_JUMP_IF_NOT_NONE] = 1, + [JUMP_BACKWARD_NO_INTERRUPT] = 1, + [FOR_ITER] = 1, + [FOR_ITER_LIST] = 1, + [FOR_ITER_TUPLE] = 1, + [FOR_ITER_RANGE] = 1, + [FOR_ITER_GEN] = 1, + [CALL_PY_GENERAL] = 1, + [CALL_BOUND_METHOD_GENERAL] = 1, + [CALL_BOUND_METHOD_EXACT_ARGS] = 1, + [CALL_PY_EXACT_ARGS] = 1, + [CALL_ALLOC_AND_ENTER_INIT] = 1, + [CALL_KW_PY] = 1, + [CALL_KW_BOUND_METHOD] = 1, +}; +#endif + extern const uint8_t _PyOpcode_Deopt[256]; #ifdef NEED_OPCODE_METADATA const uint8_t _PyOpcode_Deopt[256] = { - [121] = 121, - [122] = 122, [123] = 123, [124] = 124, [125] = 125, @@ -2011,6 +2065,8 @@ const uint8_t _PyOpcode_Deopt[256] = { [STORE_SUBSCR_DICT] = STORE_SUBSCR, [STORE_SUBSCR_LIST_INT] = STORE_SUBSCR, [SWAP] = SWAP, + [TIER1_GUARD_IP] = TIER1_GUARD_IP, + [TIER1_SET_IP] = TIER1_SET_IP, [TO_BOOL] = TO_BOOL, [TO_BOOL_ALWAYS_TRUE] = TO_BOOL, [TO_BOOL_BOOL] = TO_BOOL, @@ -2033,8 +2089,6 @@ const uint8_t _PyOpcode_Deopt[256] = { #endif // NEED_OPCODE_METADATA #define EXTRA_CASES \ - case 121: \ - case 122: \ case 123: \ case 124: \ case 125: \ diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h index 685c39dcd65f..9bfd301efecc 100644 --- a/Include/internal/pycore_optimizer.h +++ b/Include/internal/pycore_optimizer.h @@ -336,7 +336,7 @@ extern int _Py_uop_frame_pop(JitOptContext *ctx); PyAPI_FUNC(PyObject *) _Py_uop_symbols_test(PyObject *self, PyObject *ignored); -PyAPI_FUNC(int) _PyOptimizer_Optimize(_PyInterpreterFrame *frame, _Py_CODEUNIT *start, _PyExecutorObject **exec_ptr, int chain_depth); +PyAPI_FUNC(int) _PyOptimizer_Optimize(_PyInterpreterFrame *frame, PyThreadState *tstate); static inline _PyExecutorObject *_PyExecutor_FromExit(_PyExitData *exit) { diff --git a/Include/internal/pycore_uop.h b/Include/internal/pycore_uop.h index f364c01ba920..301779905cf4 100644 --- a/Include/internal/pycore_uop.h +++ b/Include/internal/pycore_uop.h @@ -41,7 +41,7 @@ typedef struct _PyUOpInstruction{ // This is the length of the trace we record. // This includes the inline caches. -#define TRACE_MAX_TRACE_LENGTH 1000 +#define TRACE_MAX_TRACE_LENGTH 2000 #define TRACER_BUFFER_SIZE ((int)(TRACE_MAX_TRACE_LENGTH * sizeof(_Py_CODEUNIT))) #ifdef __cplusplus diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index ff1d75c0cb19..2ef1fccc8d8e 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -108,74 +108,76 @@ extern "C" { #define _DO_CALL 374 #define _DO_CALL_FUNCTION_EX 375 #define _DO_CALL_KW 376 +#define _DYNAMIC_EXIT 377 #define _END_FOR END_FOR #define _END_SEND END_SEND -#define _ERROR_POP_N 377 +#define _ERROR_POP_N 378 #define _EXIT_INIT_CHECK EXIT_INIT_CHECK -#define _EXPAND_METHOD 378 -#define _EXPAND_METHOD_KW 379 -#define _FATAL_ERROR 380 +#define _EXPAND_METHOD 379 +#define _EXPAND_METHOD_KW 380 +#define _FATAL_ERROR 381 #define _FORMAT_SIMPLE FORMAT_SIMPLE #define _FORMAT_WITH_SPEC FORMAT_WITH_SPEC -#define _FOR_ITER 381 -#define _FOR_ITER_GEN_FRAME 382 -#define _FOR_ITER_TIER_TWO 383 +#define _FOR_ITER 382 +#define _FOR_ITER_GEN_FRAME 383 +#define _FOR_ITER_TIER_TWO 384 #define _GET_AITER GET_AITER #define _GET_ANEXT GET_ANEXT #define _GET_AWAITABLE GET_AWAITABLE #define _GET_ITER GET_ITER #define _GET_LEN GET_LEN #define _GET_YIELD_FROM_ITER GET_YIELD_FROM_ITER -#define _GUARD_BINARY_OP_EXTEND 384 -#define _GUARD_CALLABLE_ISINSTANCE 385 -#define _GUARD_CALLABLE_LEN 386 -#define _GUARD_CALLABLE_LIST_APPEND 387 -#define _GUARD_CALLABLE_STR_1 388 -#define _GUARD_CALLABLE_TUPLE_1 389 -#define _GUARD_CALLABLE_TYPE_1 390 -#define _GUARD_DORV_NO_DICT 391 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 392 -#define _GUARD_GLOBALS_VERSION 393 -#define _GUARD_IS_FALSE_POP 394 -#define _GUARD_IS_NONE_POP 395 -#define _GUARD_IS_NOT_NONE_POP 396 -#define _GUARD_IS_TRUE_POP 397 -#define _GUARD_KEYS_VERSION 398 -#define _GUARD_NOS_DICT 399 -#define _GUARD_NOS_FLOAT 400 -#define _GUARD_NOS_INT 401 -#define _GUARD_NOS_LIST 402 -#define _GUARD_NOS_NOT_NULL 403 -#define _GUARD_NOS_NULL 404 -#define _GUARD_NOS_OVERFLOWED 405 -#define _GUARD_NOS_TUPLE 406 -#define _GUARD_NOS_UNICODE 407 -#define _GUARD_NOT_EXHAUSTED_LIST 408 -#define _GUARD_NOT_EXHAUSTED_RANGE 409 -#define _GUARD_NOT_EXHAUSTED_TUPLE 410 -#define _GUARD_THIRD_NULL 411 -#define _GUARD_TOS_ANY_SET 412 -#define _GUARD_TOS_DICT 413 -#define _GUARD_TOS_FLOAT 414 -#define _GUARD_TOS_INT 415 -#define _GUARD_TOS_LIST 416 -#define _GUARD_TOS_OVERFLOWED 417 -#define _GUARD_TOS_SLICE 418 -#define _GUARD_TOS_TUPLE 419 -#define _GUARD_TOS_UNICODE 420 -#define _GUARD_TYPE_VERSION 421 -#define _GUARD_TYPE_VERSION_AND_LOCK 422 -#define _HANDLE_PENDING_AND_DEOPT 423 +#define _GUARD_BINARY_OP_EXTEND 385 +#define _GUARD_CALLABLE_ISINSTANCE 386 +#define _GUARD_CALLABLE_LEN 387 +#define _GUARD_CALLABLE_LIST_APPEND 388 +#define _GUARD_CALLABLE_STR_1 389 +#define _GUARD_CALLABLE_TUPLE_1 390 +#define _GUARD_CALLABLE_TYPE_1 391 +#define _GUARD_DORV_NO_DICT 392 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 393 +#define _GUARD_GLOBALS_VERSION 394 +#define _GUARD_IP 395 +#define _GUARD_IS_FALSE_POP 396 +#define _GUARD_IS_NONE_POP 397 +#define _GUARD_IS_NOT_NONE_POP 398 +#define _GUARD_IS_TRUE_POP 399 +#define _GUARD_KEYS_VERSION 400 +#define _GUARD_NOS_DICT 401 +#define _GUARD_NOS_FLOAT 402 +#define _GUARD_NOS_INT 403 +#define _GUARD_NOS_LIST 404 +#define _GUARD_NOS_NOT_NULL 405 +#define _GUARD_NOS_NULL 406 +#define _GUARD_NOS_OVERFLOWED 407 +#define _GUARD_NOS_TUPLE 408 +#define _GUARD_NOS_UNICODE 409 +#define _GUARD_NOT_EXHAUSTED_LIST 410 +#define _GUARD_NOT_EXHAUSTED_RANGE 411 +#define _GUARD_NOT_EXHAUSTED_TUPLE 412 +#define _GUARD_THIRD_NULL 413 +#define _GUARD_TOS_ANY_SET 414 +#define _GUARD_TOS_DICT 415 +#define _GUARD_TOS_FLOAT 416 +#define _GUARD_TOS_INT 417 +#define _GUARD_TOS_LIST 418 +#define _GUARD_TOS_OVERFLOWED 419 +#define _GUARD_TOS_SLICE 420 +#define _GUARD_TOS_TUPLE 421 +#define _GUARD_TOS_UNICODE 422 +#define _GUARD_TYPE_VERSION 423 +#define _GUARD_TYPE_VERSION_AND_LOCK 424 +#define _HANDLE_PENDING_AND_DEOPT 425 #define _IMPORT_FROM IMPORT_FROM #define _IMPORT_NAME IMPORT_NAME -#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 424 -#define _INIT_CALL_PY_EXACT_ARGS 425 -#define _INIT_CALL_PY_EXACT_ARGS_0 426 -#define _INIT_CALL_PY_EXACT_ARGS_1 427 -#define _INIT_CALL_PY_EXACT_ARGS_2 428 -#define _INIT_CALL_PY_EXACT_ARGS_3 429 -#define _INIT_CALL_PY_EXACT_ARGS_4 430 -#define _INSERT_NULL 431 +#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 426 +#define _INIT_CALL_PY_EXACT_ARGS 427 +#define _INIT_CALL_PY_EXACT_ARGS_0 428 +#define _INIT_CALL_PY_EXACT_ARGS_1 429 +#define _INIT_CALL_PY_EXACT_ARGS_2 430 +#define _INIT_CALL_PY_EXACT_ARGS_3 431 +#define _INIT_CALL_PY_EXACT_ARGS_4 432 +#define _INSERT_NULL 433 #define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER #define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION #define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD @@ -185,177 +187,178 @@ extern "C" { #define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE #define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE INSTRUMENTED_POP_JUMP_IF_NOT_NONE #define _INSTRUMENTED_POP_JUMP_IF_TRUE INSTRUMENTED_POP_JUMP_IF_TRUE -#define _IS_NONE 432 +#define _IS_NONE 434 #define _IS_OP IS_OP -#define _ITER_CHECK_LIST 433 -#define _ITER_CHECK_RANGE 434 -#define _ITER_CHECK_TUPLE 435 -#define _ITER_JUMP_LIST 436 -#define _ITER_JUMP_RANGE 437 -#define _ITER_JUMP_TUPLE 438 -#define _ITER_NEXT_LIST 439 -#define _ITER_NEXT_LIST_TIER_TWO 440 -#define _ITER_NEXT_RANGE 441 -#define _ITER_NEXT_TUPLE 442 -#define _JUMP_TO_TOP 443 +#define _ITER_CHECK_LIST 435 +#define _ITER_CHECK_RANGE 436 +#define _ITER_CHECK_TUPLE 437 +#define _ITER_JUMP_LIST 438 +#define _ITER_JUMP_RANGE 439 +#define _ITER_JUMP_TUPLE 440 +#define _ITER_NEXT_LIST 441 +#define _ITER_NEXT_LIST_TIER_TWO 442 +#define _ITER_NEXT_RANGE 443 +#define _ITER_NEXT_TUPLE 444 +#define _JUMP_BACKWARD_NO_INTERRUPT 445 +#define _JUMP_TO_TOP 446 #define _LIST_APPEND LIST_APPEND #define _LIST_EXTEND LIST_EXTEND -#define _LOAD_ATTR 444 -#define _LOAD_ATTR_CLASS 445 +#define _LOAD_ATTR 447 +#define _LOAD_ATTR_CLASS 448 #define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN -#define _LOAD_ATTR_INSTANCE_VALUE 446 -#define _LOAD_ATTR_METHOD_LAZY_DICT 447 -#define _LOAD_ATTR_METHOD_NO_DICT 448 -#define _LOAD_ATTR_METHOD_WITH_VALUES 449 -#define _LOAD_ATTR_MODULE 450 -#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 451 -#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 452 -#define _LOAD_ATTR_PROPERTY_FRAME 453 -#define _LOAD_ATTR_SLOT 454 -#define _LOAD_ATTR_WITH_HINT 455 +#define _LOAD_ATTR_INSTANCE_VALUE 449 +#define _LOAD_ATTR_METHOD_LAZY_DICT 450 +#define _LOAD_ATTR_METHOD_NO_DICT 451 +#define _LOAD_ATTR_METHOD_WITH_VALUES 452 +#define _LOAD_ATTR_MODULE 453 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 454 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 455 +#define _LOAD_ATTR_PROPERTY_FRAME 456 +#define _LOAD_ATTR_SLOT 457 +#define _LOAD_ATTR_WITH_HINT 458 #define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS -#define _LOAD_BYTECODE 456 +#define _LOAD_BYTECODE 459 #define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT #define _LOAD_CONST LOAD_CONST -#define _LOAD_CONST_INLINE 457 -#define _LOAD_CONST_INLINE_BORROW 458 -#define _LOAD_CONST_UNDER_INLINE 459 -#define _LOAD_CONST_UNDER_INLINE_BORROW 460 +#define _LOAD_CONST_INLINE 460 +#define _LOAD_CONST_INLINE_BORROW 461 +#define _LOAD_CONST_UNDER_INLINE 462 +#define _LOAD_CONST_UNDER_INLINE_BORROW 463 #define _LOAD_DEREF LOAD_DEREF -#define _LOAD_FAST 461 -#define _LOAD_FAST_0 462 -#define _LOAD_FAST_1 463 -#define _LOAD_FAST_2 464 -#define _LOAD_FAST_3 465 -#define _LOAD_FAST_4 466 -#define _LOAD_FAST_5 467 -#define _LOAD_FAST_6 468 -#define _LOAD_FAST_7 469 +#define _LOAD_FAST 464 +#define _LOAD_FAST_0 465 +#define _LOAD_FAST_1 466 +#define _LOAD_FAST_2 467 +#define _LOAD_FAST_3 468 +#define _LOAD_FAST_4 469 +#define _LOAD_FAST_5 470 +#define _LOAD_FAST_6 471 +#define _LOAD_FAST_7 472 #define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR -#define _LOAD_FAST_BORROW 470 -#define _LOAD_FAST_BORROW_0 471 -#define _LOAD_FAST_BORROW_1 472 -#define _LOAD_FAST_BORROW_2 473 -#define _LOAD_FAST_BORROW_3 474 -#define _LOAD_FAST_BORROW_4 475 -#define _LOAD_FAST_BORROW_5 476 -#define _LOAD_FAST_BORROW_6 477 -#define _LOAD_FAST_BORROW_7 478 +#define _LOAD_FAST_BORROW 473 +#define _LOAD_FAST_BORROW_0 474 +#define _LOAD_FAST_BORROW_1 475 +#define _LOAD_FAST_BORROW_2 476 +#define _LOAD_FAST_BORROW_3 477 +#define _LOAD_FAST_BORROW_4 478 +#define _LOAD_FAST_BORROW_5 479 +#define _LOAD_FAST_BORROW_6 480 +#define _LOAD_FAST_BORROW_7 481 #define _LOAD_FAST_BORROW_LOAD_FAST_BORROW LOAD_FAST_BORROW_LOAD_FAST_BORROW #define _LOAD_FAST_CHECK LOAD_FAST_CHECK #define _LOAD_FAST_LOAD_FAST LOAD_FAST_LOAD_FAST #define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF #define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS -#define _LOAD_GLOBAL 479 -#define _LOAD_GLOBAL_BUILTINS 480 -#define _LOAD_GLOBAL_MODULE 481 +#define _LOAD_GLOBAL 482 +#define _LOAD_GLOBAL_BUILTINS 483 +#define _LOAD_GLOBAL_MODULE 484 #define _LOAD_LOCALS LOAD_LOCALS #define _LOAD_NAME LOAD_NAME -#define _LOAD_SMALL_INT 482 -#define _LOAD_SMALL_INT_0 483 -#define _LOAD_SMALL_INT_1 484 -#define _LOAD_SMALL_INT_2 485 -#define _LOAD_SMALL_INT_3 486 -#define _LOAD_SPECIAL 487 +#define _LOAD_SMALL_INT 485 +#define _LOAD_SMALL_INT_0 486 +#define _LOAD_SMALL_INT_1 487 +#define _LOAD_SMALL_INT_2 488 +#define _LOAD_SMALL_INT_3 489 +#define _LOAD_SPECIAL 490 #define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR #define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD -#define _MAKE_CALLARGS_A_TUPLE 488 +#define _MAKE_CALLARGS_A_TUPLE 491 #define _MAKE_CELL MAKE_CELL #define _MAKE_FUNCTION MAKE_FUNCTION -#define _MAKE_WARM 489 +#define _MAKE_WARM 492 #define _MAP_ADD MAP_ADD #define _MATCH_CLASS MATCH_CLASS #define _MATCH_KEYS MATCH_KEYS #define _MATCH_MAPPING MATCH_MAPPING #define _MATCH_SEQUENCE MATCH_SEQUENCE -#define _MAYBE_EXPAND_METHOD 490 -#define _MAYBE_EXPAND_METHOD_KW 491 -#define _MONITOR_CALL 492 -#define _MONITOR_CALL_KW 493 -#define _MONITOR_JUMP_BACKWARD 494 -#define _MONITOR_RESUME 495 +#define _MAYBE_EXPAND_METHOD 493 +#define _MAYBE_EXPAND_METHOD_KW 494 +#define _MONITOR_CALL 495 +#define _MONITOR_CALL_KW 496 +#define _MONITOR_JUMP_BACKWARD 497 +#define _MONITOR_RESUME 498 #define _NOP NOP -#define _POP_CALL 496 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW 497 -#define _POP_CALL_ONE 498 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 499 -#define _POP_CALL_TWO 500 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 501 +#define _POP_CALL 499 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW 500 +#define _POP_CALL_ONE 501 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 502 +#define _POP_CALL_TWO 503 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 504 #define _POP_EXCEPT POP_EXCEPT #define _POP_ITER POP_ITER -#define _POP_JUMP_IF_FALSE 502 -#define _POP_JUMP_IF_TRUE 503 +#define _POP_JUMP_IF_FALSE 505 +#define _POP_JUMP_IF_TRUE 506 #define _POP_TOP POP_TOP -#define _POP_TOP_FLOAT 504 -#define _POP_TOP_INT 505 -#define _POP_TOP_LOAD_CONST_INLINE 506 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW 507 -#define _POP_TOP_NOP 508 -#define _POP_TOP_UNICODE 509 -#define _POP_TWO 510 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW 511 +#define _POP_TOP_FLOAT 507 +#define _POP_TOP_INT 508 +#define _POP_TOP_LOAD_CONST_INLINE 509 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW 510 +#define _POP_TOP_NOP 511 +#define _POP_TOP_UNICODE 512 +#define _POP_TWO 513 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW 514 #define _PUSH_EXC_INFO PUSH_EXC_INFO -#define _PUSH_FRAME 512 +#define _PUSH_FRAME 515 #define _PUSH_NULL PUSH_NULL -#define _PUSH_NULL_CONDITIONAL 513 -#define _PY_FRAME_GENERAL 514 -#define _PY_FRAME_KW 515 -#define _QUICKEN_RESUME 516 -#define _REPLACE_WITH_TRUE 517 +#define _PUSH_NULL_CONDITIONAL 516 +#define _PY_FRAME_GENERAL 517 +#define _PY_FRAME_KW 518 +#define _QUICKEN_RESUME 519 +#define _REPLACE_WITH_TRUE 520 #define _RESUME_CHECK RESUME_CHECK #define _RETURN_GENERATOR RETURN_GENERATOR #define _RETURN_VALUE RETURN_VALUE -#define _SAVE_RETURN_OFFSET 518 -#define _SEND 519 -#define _SEND_GEN_FRAME 520 +#define _SAVE_RETURN_OFFSET 521 +#define _SEND 522 +#define _SEND_GEN_FRAME 523 #define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS #define _SET_ADD SET_ADD #define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE #define _SET_UPDATE SET_UPDATE -#define _START_EXECUTOR 521 -#define _STORE_ATTR 522 -#define _STORE_ATTR_INSTANCE_VALUE 523 -#define _STORE_ATTR_SLOT 524 -#define _STORE_ATTR_WITH_HINT 525 +#define _START_EXECUTOR 524 +#define _STORE_ATTR 525 +#define _STORE_ATTR_INSTANCE_VALUE 526 +#define _STORE_ATTR_SLOT 527 +#define _STORE_ATTR_WITH_HINT 528 #define _STORE_DEREF STORE_DEREF -#define _STORE_FAST 526 -#define _STORE_FAST_0 527 -#define _STORE_FAST_1 528 -#define _STORE_FAST_2 529 -#define _STORE_FAST_3 530 -#define _STORE_FAST_4 531 -#define _STORE_FAST_5 532 -#define _STORE_FAST_6 533 -#define _STORE_FAST_7 534 +#define _STORE_FAST 529 +#define _STORE_FAST_0 530 +#define _STORE_FAST_1 531 +#define _STORE_FAST_2 532 +#define _STORE_FAST_3 533 +#define _STORE_FAST_4 534 +#define _STORE_FAST_5 535 +#define _STORE_FAST_6 536 +#define _STORE_FAST_7 537 #define _STORE_FAST_LOAD_FAST STORE_FAST_LOAD_FAST #define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST #define _STORE_GLOBAL STORE_GLOBAL #define _STORE_NAME STORE_NAME -#define _STORE_SLICE 535 -#define _STORE_SUBSCR 536 -#define _STORE_SUBSCR_DICT 537 -#define _STORE_SUBSCR_LIST_INT 538 -#define _SWAP 539 -#define _SWAP_2 540 -#define _SWAP_3 541 -#define _TIER2_RESUME_CHECK 542 -#define _TO_BOOL 543 +#define _STORE_SLICE 538 +#define _STORE_SUBSCR 539 +#define _STORE_SUBSCR_DICT 540 +#define _STORE_SUBSCR_LIST_INT 541 +#define _SWAP 542 +#define _SWAP_2 543 +#define _SWAP_3 544 +#define _TIER2_RESUME_CHECK 545 +#define _TO_BOOL 546 #define _TO_BOOL_BOOL TO_BOOL_BOOL #define _TO_BOOL_INT TO_BOOL_INT -#define _TO_BOOL_LIST 544 +#define _TO_BOOL_LIST 547 #define _TO_BOOL_NONE TO_BOOL_NONE -#define _TO_BOOL_STR 545 +#define _TO_BOOL_STR 548 #define _UNARY_INVERT UNARY_INVERT #define _UNARY_NEGATIVE UNARY_NEGATIVE #define _UNARY_NOT UNARY_NOT #define _UNPACK_EX UNPACK_EX -#define _UNPACK_SEQUENCE 546 -#define _UNPACK_SEQUENCE_LIST 547 -#define _UNPACK_SEQUENCE_TUPLE 548 -#define _UNPACK_SEQUENCE_TWO_TUPLE 549 +#define _UNPACK_SEQUENCE 549 +#define _UNPACK_SEQUENCE_LIST 550 +#define _UNPACK_SEQUENCE_TUPLE 551 +#define _UNPACK_SEQUENCE_TWO_TUPLE 552 #define _WITH_EXCEPT_START WITH_EXCEPT_START #define _YIELD_VALUE YIELD_VALUE -#define MAX_UOP_ID 549 +#define MAX_UOP_ID 552 #ifdef __cplusplus } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 124877199694..f8099301b6b4 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -205,7 +205,10 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_CHECK_EXC_MATCH] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_IMPORT_NAME] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_IMPORT_FROM] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, + [_POP_JUMP_IF_FALSE] = HAS_ARG_FLAG | HAS_JUMP_FLAG, + [_POP_JUMP_IF_TRUE] = HAS_ARG_FLAG | HAS_JUMP_FLAG, [_IS_NONE] = HAS_ESCAPES_FLAG, + [_JUMP_BACKWARD_NO_INTERRUPT] = HAS_ARG_FLAG | HAS_JUMP_FLAG, [_GET_LEN] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_MATCH_CLASS] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_MATCH_MAPPING] = 0, @@ -213,9 +216,10 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_MATCH_KEYS] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_GET_ITER] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG, [_GET_YIELD_FROM_ITER] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, - [_FOR_ITER_TIER_TWO] = HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, + [_FOR_ITER_TIER_TWO] = HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_ITER_CHECK_LIST] = HAS_EXIT_FLAG, [_GUARD_NOT_EXHAUSTED_LIST] = HAS_EXIT_FLAG, + [_ITER_NEXT_LIST] = HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG, [_ITER_NEXT_LIST_TIER_TWO] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG, [_ITER_CHECK_TUPLE] = HAS_EXIT_FLAG, [_GUARD_NOT_EXHAUSTED_TUPLE] = HAS_EXIT_FLAG, @@ -337,6 +341,8 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_ERROR_POP_N] = HAS_ARG_FLAG, [_TIER2_RESUME_CHECK] = HAS_PERIODIC_FLAG, [_COLD_EXIT] = HAS_ESCAPES_FLAG, + [_GUARD_IP] = HAS_ESCAPES_FLAG, + [_DYNAMIC_EXIT] = 0, }; const ReplicationRange _PyUop_Replication[MAX_UOP_ID+1] = { @@ -443,6 +449,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = { [_DEOPT] = "_DEOPT", [_DICT_MERGE] = "_DICT_MERGE", [_DICT_UPDATE] = "_DICT_UPDATE", + [_DYNAMIC_EXIT] = "_DYNAMIC_EXIT", [_END_FOR] = "_END_FOR", [_END_SEND] = "_END_SEND", [_ERROR_POP_N] = "_ERROR_POP_N", @@ -471,6 +478,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = { [_GUARD_DORV_NO_DICT] = "_GUARD_DORV_NO_DICT", [_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = "_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT", [_GUARD_GLOBALS_VERSION] = "_GUARD_GLOBALS_VERSION", + [_GUARD_IP] = "_GUARD_IP", [_GUARD_IS_FALSE_POP] = "_GUARD_IS_FALSE_POP", [_GUARD_IS_NONE_POP] = "_GUARD_IS_NONE_POP", [_GUARD_IS_NOT_NONE_POP] = "_GUARD_IS_NOT_NONE_POP", @@ -516,9 +524,11 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = { [_ITER_CHECK_LIST] = "_ITER_CHECK_LIST", [_ITER_CHECK_RANGE] = "_ITER_CHECK_RANGE", [_ITER_CHECK_TUPLE] = "_ITER_CHECK_TUPLE", + [_ITER_NEXT_LIST] = "_ITER_NEXT_LIST", [_ITER_NEXT_LIST_TIER_TWO] = "_ITER_NEXT_LIST_TIER_TWO", [_ITER_NEXT_RANGE] = "_ITER_NEXT_RANGE", [_ITER_NEXT_TUPLE] = "_ITER_NEXT_TUPLE", + [_JUMP_BACKWARD_NO_INTERRUPT] = "_JUMP_BACKWARD_NO_INTERRUPT", [_JUMP_TO_TOP] = "_JUMP_TO_TOP", [_LIST_APPEND] = "_LIST_APPEND", [_LIST_EXTEND] = "_LIST_EXTEND", @@ -598,6 +608,8 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = { [_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW] = "_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW", [_POP_EXCEPT] = "_POP_EXCEPT", [_POP_ITER] = "_POP_ITER", + [_POP_JUMP_IF_FALSE] = "_POP_JUMP_IF_FALSE", + [_POP_JUMP_IF_TRUE] = "_POP_JUMP_IF_TRUE", [_POP_TOP] = "_POP_TOP", [_POP_TOP_FLOAT] = "_POP_TOP_FLOAT", [_POP_TOP_INT] = "_POP_TOP_INT", @@ -1041,8 +1053,14 @@ int _PyUop_num_popped(int opcode, int oparg) return 2; case _IMPORT_FROM: return 0; + case _POP_JUMP_IF_FALSE: + return 1; + case _POP_JUMP_IF_TRUE: + return 1; case _IS_NONE: return 1; + case _JUMP_BACKWARD_NO_INTERRUPT: + return 0; case _GET_LEN: return 0; case _MATCH_CLASS: @@ -1063,6 +1081,8 @@ int _PyUop_num_popped(int opcode, int oparg) return 0; case _GUARD_NOT_EXHAUSTED_LIST: return 0; + case _ITER_NEXT_LIST: + return 0; case _ITER_NEXT_LIST_TIER_TWO: return 0; case _ITER_CHECK_TUPLE: @@ -1305,6 +1325,10 @@ int _PyUop_num_popped(int opcode, int oparg) return 0; case _COLD_EXIT: return 0; + case _GUARD_IP: + return 0; + case _DYNAMIC_EXIT: + return 0; default: return -1; } diff --git a/Include/opcode_ids.h b/Include/opcode_ids.h index 1d5c74adefcd..4021dc0ad72e 100644 --- a/Include/opcode_ids.h +++ b/Include/opcode_ids.h @@ -49,88 +49,90 @@ extern "C" { #define SETUP_ANNOTATIONS 36 #define STORE_SLICE 37 #define STORE_SUBSCR 38 -#define TO_BOOL 39 -#define UNARY_INVERT 40 -#define UNARY_NEGATIVE 41 -#define UNARY_NOT 42 -#define WITH_EXCEPT_START 43 -#define BINARY_OP 44 -#define BUILD_INTERPOLATION 45 -#define BUILD_LIST 46 -#define BUILD_MAP 47 -#define BUILD_SET 48 -#define BUILD_SLICE 49 -#define BUILD_STRING 50 -#define BUILD_TUPLE 51 -#define CALL 52 -#define CALL_INTRINSIC_1 53 -#define CALL_INTRINSIC_2 54 -#define CALL_KW 55 -#define COMPARE_OP 56 -#define CONTAINS_OP 57 -#define CONVERT_VALUE 58 -#define COPY 59 -#define COPY_FREE_VARS 60 -#define DELETE_ATTR 61 -#define DELETE_DEREF 62 -#define DELETE_FAST 63 -#define DELETE_GLOBAL 64 -#define DELETE_NAME 65 -#define DICT_MERGE 66 -#define DICT_UPDATE 67 -#define END_ASYNC_FOR 68 -#define EXTENDED_ARG 69 -#define FOR_ITER 70 -#define GET_AWAITABLE 71 -#define IMPORT_FROM 72 -#define IMPORT_NAME 73 -#define IS_OP 74 -#define JUMP_BACKWARD 75 -#define JUMP_BACKWARD_NO_INTERRUPT 76 -#define JUMP_FORWARD 77 -#define LIST_APPEND 78 -#define LIST_EXTEND 79 -#define LOAD_ATTR 80 -#define LOAD_COMMON_CONSTANT 81 -#define LOAD_CONST 82 -#define LOAD_DEREF 83 -#define LOAD_FAST 84 -#define LOAD_FAST_AND_CLEAR 85 -#define LOAD_FAST_BORROW 86 -#define LOAD_FAST_BORROW_LOAD_FAST_BORROW 87 -#define LOAD_FAST_CHECK 88 -#define LOAD_FAST_LOAD_FAST 89 -#define LOAD_FROM_DICT_OR_DEREF 90 -#define LOAD_FROM_DICT_OR_GLOBALS 91 -#define LOAD_GLOBAL 92 -#define LOAD_NAME 93 -#define LOAD_SMALL_INT 94 -#define LOAD_SPECIAL 95 -#define LOAD_SUPER_ATTR 96 -#define MAKE_CELL 97 -#define MAP_ADD 98 -#define MATCH_CLASS 99 -#define POP_JUMP_IF_FALSE 100 -#define POP_JUMP_IF_NONE 101 -#define POP_JUMP_IF_NOT_NONE 102 -#define POP_JUMP_IF_TRUE 103 -#define RAISE_VARARGS 104 -#define RERAISE 105 -#define SEND 106 -#define SET_ADD 107 -#define SET_FUNCTION_ATTRIBUTE 108 -#define SET_UPDATE 109 -#define STORE_ATTR 110 -#define STORE_DEREF 111 -#define STORE_FAST 112 -#define STORE_FAST_LOAD_FAST 113 -#define STORE_FAST_STORE_FAST 114 -#define STORE_GLOBAL 115 -#define STORE_NAME 116 -#define SWAP 117 -#define UNPACK_EX 118 -#define UNPACK_SEQUENCE 119 -#define YIELD_VALUE 120 +#define TIER1_GUARD_IP 39 +#define TIER1_SET_IP 40 +#define TO_BOOL 41 +#define UNARY_INVERT 42 +#define UNARY_NEGATIVE 43 +#define UNARY_NOT 44 +#define WITH_EXCEPT_START 45 +#define BINARY_OP 46 +#define BUILD_INTERPOLATION 47 +#define BUILD_LIST 48 +#define BUILD_MAP 49 +#define BUILD_SET 50 +#define BUILD_SLICE 51 +#define BUILD_STRING 52 +#define BUILD_TUPLE 53 +#define CALL 54 +#define CALL_INTRINSIC_1 55 +#define CALL_INTRINSIC_2 56 +#define CALL_KW 57 +#define COMPARE_OP 58 +#define CONTAINS_OP 59 +#define CONVERT_VALUE 60 +#define COPY 61 +#define COPY_FREE_VARS 62 +#define DELETE_ATTR 63 +#define DELETE_DEREF 64 +#define DELETE_FAST 65 +#define DELETE_GLOBAL 66 +#define DELETE_NAME 67 +#define DICT_MERGE 68 +#define DICT_UPDATE 69 +#define END_ASYNC_FOR 70 +#define EXTENDED_ARG 71 +#define FOR_ITER 72 +#define GET_AWAITABLE 73 +#define IMPORT_FROM 74 +#define IMPORT_NAME 75 +#define IS_OP 76 +#define JUMP_BACKWARD 77 +#define JUMP_BACKWARD_NO_INTERRUPT 78 +#define JUMP_FORWARD 79 +#define LIST_APPEND 80 +#define LIST_EXTEND 81 +#define LOAD_ATTR 82 +#define LOAD_COMMON_CONSTANT 83 +#define LOAD_CONST 84 +#define LOAD_DEREF 85 +#define LOAD_FAST 86 +#define LOAD_FAST_AND_CLEAR 87 +#define LOAD_FAST_BORROW 88 +#define LOAD_FAST_BORROW_LOAD_FAST_BORROW 89 +#define LOAD_FAST_CHECK 90 +#define LOAD_FAST_LOAD_FAST 91 +#define LOAD_FROM_DICT_OR_DEREF 92 +#define LOAD_FROM_DICT_OR_GLOBALS 93 +#define LOAD_GLOBAL 94 +#define LOAD_NAME 95 +#define LOAD_SMALL_INT 96 +#define LOAD_SPECIAL 97 +#define LOAD_SUPER_ATTR 98 +#define MAKE_CELL 99 +#define MAP_ADD 100 +#define MATCH_CLASS 101 +#define POP_JUMP_IF_FALSE 102 +#define POP_JUMP_IF_NONE 103 +#define POP_JUMP_IF_NOT_NONE 104 +#define POP_JUMP_IF_TRUE 105 +#define RAISE_VARARGS 106 +#define RERAISE 107 +#define SEND 108 +#define SET_ADD 109 +#define SET_FUNCTION_ATTRIBUTE 110 +#define SET_UPDATE 111 +#define STORE_ATTR 112 +#define STORE_DEREF 113 +#define STORE_FAST 114 +#define STORE_FAST_LOAD_FAST 115 +#define STORE_FAST_STORE_FAST 116 +#define STORE_GLOBAL 117 +#define STORE_NAME 118 +#define SWAP 119 +#define UNPACK_EX 120 +#define UNPACK_SEQUENCE 121 +#define YIELD_VALUE 122 #define RESUME 128 #define BINARY_OP_ADD_FLOAT 129 #define BINARY_OP_ADD_INT 130 @@ -247,7 +249,7 @@ extern "C" { #define SETUP_WITH 265 #define STORE_FAST_MAYBE_NULL 266 -#define HAVE_ARGUMENT 43 +#define HAVE_ARGUMENT 45 #define MIN_SPECIALIZED_OPCODE 129 #define MIN_INSTRUMENTED_OPCODE 234 diff --git a/Lib/_opcode_metadata.py b/Lib/_opcode_metadata.py index f168d169a329..ca7fc579b3aa 100644 --- a/Lib/_opcode_metadata.py +++ b/Lib/_opcode_metadata.py @@ -246,88 +246,90 @@ opmap = { 'SETUP_ANNOTATIONS': 36, 'STORE_SLICE': 37, 'STORE_SUBSCR': 38, - 'TO_BOOL': 39, - 'UNARY_INVERT': 40, - 'UNARY_NEGATIVE': 41, - 'UNARY_NOT': 42, - 'WITH_EXCEPT_START': 43, - 'BINARY_OP': 44, - 'BUILD_INTERPOLATION': 45, - 'BUILD_LIST': 46, - 'BUILD_MAP': 47, - 'BUILD_SET': 48, - 'BUILD_SLICE': 49, - 'BUILD_STRING': 50, - 'BUILD_TUPLE': 51, - 'CALL': 52, - 'CALL_INTRINSIC_1': 53, - 'CALL_INTRINSIC_2': 54, - 'CALL_KW': 55, - 'COMPARE_OP': 56, - 'CONTAINS_OP': 57, - 'CONVERT_VALUE': 58, - 'COPY': 59, - 'COPY_FREE_VARS': 60, - 'DELETE_ATTR': 61, - 'DELETE_DEREF': 62, - 'DELETE_FAST': 63, - 'DELETE_GLOBAL': 64, - 'DELETE_NAME': 65, - 'DICT_MERGE': 66, - 'DICT_UPDATE': 67, - 'END_ASYNC_FOR': 68, - 'EXTENDED_ARG': 69, - 'FOR_ITER': 70, - 'GET_AWAITABLE': 71, - 'IMPORT_FROM': 72, - 'IMPORT_NAME': 73, - 'IS_OP': 74, - 'JUMP_BACKWARD': 75, - 'JUMP_BACKWARD_NO_INTERRUPT': 76, - 'JUMP_FORWARD': 77, - 'LIST_APPEND': 78, - 'LIST_EXTEND': 79, - 'LOAD_ATTR': 80, - 'LOAD_COMMON_CONSTANT': 81, - 'LOAD_CONST': 82, - 'LOAD_DEREF': 83, - 'LOAD_FAST': 84, - 'LOAD_FAST_AND_CLEAR': 85, - 'LOAD_FAST_BORROW': 86, - 'LOAD_FAST_BORROW_LOAD_FAST_BORROW': 87, - 'LOAD_FAST_CHECK': 88, - 'LOAD_FAST_LOAD_FAST': 89, - 'LOAD_FROM_DICT_OR_DEREF': 90, - 'LOAD_FROM_DICT_OR_GLOBALS': 91, - 'LOAD_GLOBAL': 92, - 'LOAD_NAME': 93, - 'LOAD_SMALL_INT': 94, - 'LOAD_SPECIAL': 95, - 'LOAD_SUPER_ATTR': 96, - 'MAKE_CELL': 97, - 'MAP_ADD': 98, - 'MATCH_CLASS': 99, - 'POP_JUMP_IF_FALSE': 100, - 'POP_JUMP_IF_NONE': 101, - 'POP_JUMP_IF_NOT_NONE': 102, - 'POP_JUMP_IF_TRUE': 103, - 'RAISE_VARARGS': 104, - 'RERAISE': 105, - 'SEND': 106, - 'SET_ADD': 107, - 'SET_FUNCTION_ATTRIBUTE': 108, - 'SET_UPDATE': 109, - 'STORE_ATTR': 110, - 'STORE_DEREF': 111, - 'STORE_FAST': 112, - 'STORE_FAST_LOAD_FAST': 113, - 'STORE_FAST_STORE_FAST': 114, - 'STORE_GLOBAL': 115, - 'STORE_NAME': 116, - 'SWAP': 117, - 'UNPACK_EX': 118, - 'UNPACK_SEQUENCE': 119, - 'YIELD_VALUE': 120, + 'TIER1_GUARD_IP': 39, + 'TIER1_SET_IP': 40, + 'TO_BOOL': 41, + 'UNARY_INVERT': 42, + 'UNARY_NEGATIVE': 43, + 'UNARY_NOT': 44, + 'WITH_EXCEPT_START': 45, + 'BINARY_OP': 46, + 'BUILD_INTERPOLATION': 47, + 'BUILD_LIST': 48, + 'BUILD_MAP': 49, + 'BUILD_SET': 50, + 'BUILD_SLICE': 51, + 'BUILD_STRING': 52, + 'BUILD_TUPLE': 53, + 'CALL': 54, + 'CALL_INTRINSIC_1': 55, + 'CALL_INTRINSIC_2': 56, + 'CALL_KW': 57, + 'COMPARE_OP': 58, + 'CONTAINS_OP': 59, + 'CONVERT_VALUE': 60, + 'COPY': 61, + 'COPY_FREE_VARS': 62, + 'DELETE_ATTR': 63, + 'DELETE_DEREF': 64, + 'DELETE_FAST': 65, + 'DELETE_GLOBAL': 66, + 'DELETE_NAME': 67, + 'DICT_MERGE': 68, + 'DICT_UPDATE': 69, + 'END_ASYNC_FOR': 70, + 'EXTENDED_ARG': 71, + 'FOR_ITER': 72, + 'GET_AWAITABLE': 73, + 'IMPORT_FROM': 74, + 'IMPORT_NAME': 75, + 'IS_OP': 76, + 'JUMP_BACKWARD': 77, + 'JUMP_BACKWARD_NO_INTERRUPT': 78, + 'JUMP_FORWARD': 79, + 'LIST_APPEND': 80, + 'LIST_EXTEND': 81, + 'LOAD_ATTR': 82, + 'LOAD_COMMON_CONSTANT': 83, + 'LOAD_CONST': 84, + 'LOAD_DEREF': 85, + 'LOAD_FAST': 86, + 'LOAD_FAST_AND_CLEAR': 87, + 'LOAD_FAST_BORROW': 88, + 'LOAD_FAST_BORROW_LOAD_FAST_BORROW': 89, + 'LOAD_FAST_CHECK': 90, + 'LOAD_FAST_LOAD_FAST': 91, + 'LOAD_FROM_DICT_OR_DEREF': 92, + 'LOAD_FROM_DICT_OR_GLOBALS': 93, + 'LOAD_GLOBAL': 94, + 'LOAD_NAME': 95, + 'LOAD_SMALL_INT': 96, + 'LOAD_SPECIAL': 97, + 'LOAD_SUPER_ATTR': 98, + 'MAKE_CELL': 99, + 'MAP_ADD': 100, + 'MATCH_CLASS': 101, + 'POP_JUMP_IF_FALSE': 102, + 'POP_JUMP_IF_NONE': 103, + 'POP_JUMP_IF_NOT_NONE': 104, + 'POP_JUMP_IF_TRUE': 105, + 'RAISE_VARARGS': 106, + 'RERAISE': 107, + 'SEND': 108, + 'SET_ADD': 109, + 'SET_FUNCTION_ATTRIBUTE': 110, + 'SET_UPDATE': 111, + 'STORE_ATTR': 112, + 'STORE_DEREF': 113, + 'STORE_FAST': 114, + 'STORE_FAST_LOAD_FAST': 115, + 'STORE_FAST_STORE_FAST': 116, + 'STORE_GLOBAL': 117, + 'STORE_NAME': 118, + 'SWAP': 119, + 'UNPACK_EX': 120, + 'UNPACK_SEQUENCE': 121, + 'YIELD_VALUE': 122, 'INSTRUMENTED_END_FOR': 234, 'INSTRUMENTED_POP_ITER': 235, 'INSTRUMENTED_END_SEND': 236, @@ -361,5 +363,5 @@ opmap = { 'STORE_FAST_MAYBE_NULL': 266, } -HAVE_ARGUMENT = 43 +HAVE_ARGUMENT = 45 MIN_INSTRUMENTED_OPCODE = 234 diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 99b3bc849b60..a495e332d978 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -45,6 +45,8 @@ #define USE_COMPUTED_GOTOS 0 #include "ceval_macros.h" +#include "../Include/internal/pycore_code.h" +#include "../Include/internal/pycore_stackref.h" /* Flow control macros */ @@ -1250,6 +1252,9 @@ dummy_func( _PyEval_FrameClearAndPop(tstate, dying); RELOAD_STACK(); LOAD_IP(frame->return_offset); +#if TIER_TWO + frame->instr_ptr += frame->return_offset; +#endif res = temp; LLTRACE_RESUME_FRAME(); } @@ -1437,6 +1442,9 @@ dummy_func( #endif RELOAD_STACK(); LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); +#if TIER_TWO + frame->instr_ptr += (1 + INLINE_CACHE_ENTRIES_SEND); +#endif value = PyStackRef_MakeHeapSafe(temp); LLTRACE_RESUME_FRAME(); } @@ -2942,7 +2950,7 @@ dummy_func( tier1 op(_SPECIALIZE_JUMP_BACKWARD, (--)) { #if ENABLE_SPECIALIZATION if (this_instr->op.code == JUMP_BACKWARD) { - this_instr->op.code = tstate->interp->jit ? JUMP_BACKWARD_JIT : JUMP_BACKWARD_NO_JIT; + this_instr->op.code = (tstate->interp->jit && !PyStackRef_IsNull(frame->f_funcobj)) ? JUMP_BACKWARD_JIT : JUMP_BACKWARD_NO_JIT; // Need to re-dispatch so the warmup counter isn't off by one: next_instr = this_instr; DISPATCH_SAME_OPARG(); @@ -2953,32 +2961,34 @@ dummy_func( tier1 op(_JIT, (--)) { #ifdef _Py_TIER2 _Py_BackoffCounter counter = this_instr[1].counter; - if (backoff_counter_triggers(counter) && this_instr->op.code == JUMP_BACKWARD_JIT) { + if (!IS_JIT_TRACING() && backoff_counter_triggers(counter) && this_instr->op.code == JUMP_BACKWARD_JIT) { _Py_CODEUNIT *start = this_instr; /* Back up over EXTENDED_ARGs so optimizer sees the whole instruction */ - while (oparg > 255) { - oparg >>= 8; + int curr_oparg = oparg; + while (curr_oparg > 255) { + curr_oparg >>= 8; start--; } if (tstate->interp->jit_tracer_code_buffer == NULL) { tstate->interp->jit_tracer_code_buffer = (_Py_CODEUNIT *)_PyObject_VirtualAlloc(TRACER_BUFFER_SIZE); - tstate->interp->jit_tracer_code_curr_size = 0; if (tstate->interp->jit_tracer_code_buffer == NULL) { // Don't error, just go to next instruction. DISPATCH(); } - } - if (this_instr == tstate->interp->jit_tracer_initial_instr) { - // Looped back to initial instr. End tracing. - LEAVE_TRACING(); - DISPATCH(); + tstate->interp->jit_tracer_code_curr_size = 0; } ENTER_TRACING(); // Nothing in the buffer, begin tracing! if (tstate->interp->jit_tracer_code_curr_size == 0) { - tstate->interp->jit_tracer_initial_instr = this_instr; + tstate->interp->jit_tracer_initial_instr = next_instr; + tstate->interp->jit_tracer_initial_code = _PyFrame_GetCode(frame); + tstate->interp->jit_tracer_initial_func = _PyFrame_GetFunction(frame); + tstate->interp->jit_tracer_seen_initial_before = 0; + tstate->interp->jit_completed_loop = false; + tstate->interp->jit_tracer_initial_stack_depth = (int)STACK_LEVEL(); + tstate->interp->jit_tracer_initial_chain_depth = 0; } - // Not tracing dispatch, normal dispatch because we don't record the current instruction. + // Don't add the JUMP_BACKWARD_JIT instruction to the trace. DISPATCH(); } else { @@ -2991,17 +3001,17 @@ dummy_func( unused/1 + _SPECIALIZE_JUMP_BACKWARD + _CHECK_PERIODIC + - JUMP_BACKWARD_NO_INTERRUPT; + _JUMP_BACKWARD_NO_INTERRUPT; macro(JUMP_BACKWARD_NO_JIT) = unused/1 + _CHECK_PERIODIC + - JUMP_BACKWARD_NO_INTERRUPT; + _JUMP_BACKWARD_NO_INTERRUPT; macro(JUMP_BACKWARD_JIT) = unused/1 + _CHECK_PERIODIC + - JUMP_BACKWARD_NO_INTERRUPT + + _JUMP_BACKWARD_NO_INTERRUPT + _JIT; pseudo(JUMP, (--)) = { @@ -3033,7 +3043,7 @@ dummy_func( /* If the eval breaker is set then stay in tier 1. * This avoids any potentially infinite loops * involving _RESUME_CHECK */ - if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { + if (IS_JIT_TRACING() || _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { opcode = executor->vm_data.opcode; oparg = (oparg & ~255) | executor->vm_data.oparg; next_instr = this_instr; @@ -3050,20 +3060,18 @@ dummy_func( #endif /* _Py_TIER2 */ } - replaced op(_POP_JUMP_IF_FALSE, (cond -- )) { + op(_POP_JUMP_IF_FALSE, (cond -- )) { assert(PyStackRef_BoolCheck(cond)); int flag = PyStackRef_IsFalse(cond); DEAD(cond); - RECORD_BRANCH_TAKEN(this_instr[1].cache, flag); - JUMPBY(flag ? oparg : next_instr->op.code == NOT_TAKEN); + JUMPBY(flag ? oparg : 0); } - replaced op(_POP_JUMP_IF_TRUE, (cond -- )) { + op(_POP_JUMP_IF_TRUE, (cond -- )) { assert(PyStackRef_BoolCheck(cond)); int flag = PyStackRef_IsTrue(cond); DEAD(cond); - RECORD_BRANCH_TAKEN(this_instr[1].cache, flag); - JUMPBY(flag ? oparg : next_instr->op.code == NOT_TAKEN); + JUMPBY(flag ? oparg : 0); } op(_IS_NONE, (value -- b)) { @@ -3085,13 +3093,18 @@ dummy_func( macro(POP_JUMP_IF_NOT_NONE) = unused/1 + _IS_NONE + _POP_JUMP_IF_FALSE; - tier1 inst(JUMP_BACKWARD_NO_INTERRUPT, (--)) { + // This actually has 1 cache entry, but for some reason it's not factored in the oparg. + macro(JUMP_BACKWARD_NO_INTERRUPT) = _JUMP_BACKWARD_NO_INTERRUPT; + + op(_JUMP_BACKWARD_NO_INTERRUPT, (--)) { /* This bytecode is used in the `yield from` or `await` loop. * If there is an interrupt, we want it handled in the innermost * generator or coroutine, so we deliberately do not check it here. * (see bpo-30039). */ +#if TIER_ONE assert(oparg <= INSTR_OFFSET()); +#endif JUMPBY(-oparg); } @@ -3237,7 +3250,8 @@ dummy_func( ERROR_NO_POP(); } /* iterator ended normally */ - /* The translator sets the deopt target just past the matching END_FOR */ + // Jump forward by oparg and skip the following END_FOR + TIER2_JUMPBY(oparg + 1); EXIT_IF(true); } next = item; @@ -3298,7 +3312,7 @@ dummy_func( #endif } - replaced op(_ITER_NEXT_LIST, (iter, null_or_index -- iter, null_or_index, next)) { + op(_ITER_NEXT_LIST, (iter, null_or_index -- iter, null_or_index, next)) { PyObject *list_o = PyStackRef_AsPyObjectBorrow(iter); assert(PyList_CheckExact(list_o)); #ifdef Py_GIL_DISABLED @@ -4986,6 +5000,9 @@ dummy_func( _PyThreadState_PopFrame(tstate, frame); frame = tstate->current_frame = prev; LOAD_IP(frame->return_offset); +#if TIER_TWO + frame->instr_ptr += (frame->return_offset); +#endif RELOAD_STACK(); res = PyStackRef_FromPyObjectStealMortal((PyObject *)gen); LLTRACE_RESUME_FRAME(); @@ -5380,19 +5397,19 @@ dummy_func( } tier2 op(_DEOPT, (--)) { - GOTO_TIER_ONE(_PyFrame_GetBytecode(frame) + CURRENT_TARGET()); + GOTO_TIER_ONE(_PyFrame_GetBytecode(frame) + CURRENT_TARGET(), 0); } tier2 op(_HANDLE_PENDING_AND_DEOPT, (--)) { int err = _Py_HandlePending(tstate); - GOTO_TIER_ONE(err ? NULL : _PyFrame_GetBytecode(frame) + CURRENT_TARGET()); + GOTO_TIER_ONE(err ? NULL : _PyFrame_GetBytecode(frame) + CURRENT_TARGET(), 0); } tier2 op(_ERROR_POP_N, (target/2 --)) { assert(oparg == 0); frame->instr_ptr = _PyFrame_GetBytecode(frame) + target; SYNC_SP(); - GOTO_TIER_ONE(NULL); + GOTO_TIER_ONE(NULL, 0); } /* Progress is guaranteed if we DEOPT on the eval breaker, because @@ -5414,7 +5431,7 @@ dummy_func( _Py_BackoffCounter temperature = exit->temperature; if (!backoff_counter_triggers(temperature)) { exit->temperature = advance_backoff_counter(temperature); - GOTO_TIER_ONE(target); + GOTO_TIER_ONE(target, 0); } _PyExecutorObject *executor; if (target->op.code == ENTER_EXECUTOR) { @@ -5426,18 +5443,41 @@ dummy_func( _PyExecutorObject *previous_executor = _PyExecutor_FromExit(exit); assert(tstate->current_executor == (PyObject *)previous_executor); int chain_depth = previous_executor->vm_data.chain_depth + 1; - int optimized = _PyOptimizer_Optimize(frame, target, &executor, chain_depth); - if (optimized <= 0) { - exit->temperature = restart_backoff_counter(temperature); - GOTO_TIER_ONE(optimized < 0 ? NULL : target); - } - exit->temperature = initial_temperature_backoff_counter(); + tstate->interp->jit_tracer_initial_chain_depth = chain_depth; + tstate->interp->jit_tracer_initial_instr = target; + tstate->interp->jit_tracer_initial_code = _PyFrame_GetCode(frame); + tstate->interp->jit_tracer_initial_func = _PyFrame_GetFunction(frame); + tstate->interp->jit_tracer_seen_initial_before = 0; + tstate->interp->jit_completed_loop = false; + exit->temperature = restart_backoff_counter(temperature); + GOTO_TIER_ONE(target, 1); } assert(tstate->jit_exit == exit); exit->executor = executor; TIER2_TO_TIER2(exit->executor); } + + no_save_ip tier1 inst(TIER1_GUARD_IP, (func_ptr/4 --)) { + (void)(func_ptr); + } + + tier2 op(_GUARD_IP, (ip/4 --)) { + if (frame->instr_ptr != (_Py_CODEUNIT *)ip) { + fprintf(stdout, "d:%p:%p\n", frame->instr_ptr, ip); + GOTO_TIER_ONE(frame->instr_ptr, 1); + } + } + + tier2 op(_DYNAMIC_EXIT, (ip/4 --)) { + GOTO_TIER_ONE(frame->instr_ptr, 1); + } + + tier1 inst(TIER1_SET_IP, (ip/4 --)) { + (void)(ip); + } + + label(pop_2_error) { stack_pointer -= 2; assert(WITHIN_STACK_BOUNDS()); diff --git a/Python/ceval.c b/Python/ceval.c index 453ec103484b..4378afebc6ab 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -974,18 +974,99 @@ _PyObjectArray_Free(PyObject **array, PyObject **scratch) } // 1 for trace full, 0 for successful write. -static inline int -add_to_code_trace(PyThreadState *tstate, _Py_CODEUNIT *this_instr) +static int +add_to_code_trace(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *this_instr, int oparg) { + assert(frame != NULL); assert(tstate->interp->jit_tracer_code_curr_size < TRACE_MAX_TRACE_LENGTH); int curr_size = tstate->interp->jit_tracer_code_curr_size; - int nsize = _PyOpcode_Caches[this_instr->op.code] + 1; - if (curr_size + nsize > TRACE_MAX_TRACE_LENGTH) { + int opcode = this_instr->op.code; + if (opcode == ENTER_EXECUTOR) { return 1; + // PyCodeObject *code = _PyFrame_GetCode(frame); + // assert(code != NULL); + // _PyExecutorObject *executor = code->co_executors->executors[oparg & 255]; + // assert(executor->vm_data.code == code); + // assert(executor->vm_data.valid); + // assert(tstate->current_executor == NULL); + // opcode = executor->vm_data.opcode; + // oparg = (oparg & ~255) | executor->vm_data.oparg; + } + else { + oparg = this_instr->op.arg; + } + assert(opcode != 0); + // Check if we looped back to the start. + if (this_instr == tstate->interp->jit_tracer_initial_instr) { + if (tstate->interp->jit_tracer_seen_initial_before >= 1) { + tstate->interp->jit_completed_loop = true; + return 1; + } + tstate->interp->jit_tracer_seen_initial_before++; + } +#ifdef Py_DEBUG + char *python_lltrace = Py_GETENV("PYTHON_LLTRACE"); + int lltrace = 3; + if (python_lltrace != NULL && *python_lltrace >= '0') { + lltrace = *python_lltrace - '0'; } - for (int i = 0; i < nsize; i++) { + if (lltrace >= 3) { + printf("%d ADD_TO_BYTECODE_TRACE: %s %d\n", curr_size, _PyOpcode_OpName[opcode], oparg); + } +#endif + // JUMP_BACKWARD_NO_INTERRUPT is not registered with cache due to a bug in the compiler. + int caches = opcode == JUMP_BACKWARD_NO_INTERRUPT ? 1 : _PyOpcode_Caches[_PyOpcode_Deopt[opcode]]; + int nsize = caches + 1; + int needs_guard_ip = _PyOpcode_NeedsGuardIp[opcode]; + int total_size = nsize + (needs_guard_ip ? 5 : 0) + 5; + if (curr_size + total_size >= TRACE_MAX_TRACE_LENGTH) { +#ifdef Py_DEBUG + if (lltrace >= 3) { + printf("END TRACE LENGTH: %d\n", curr_size); + } +#endif + return 1; + } + tstate->interp->jit_tracer_code_buffer[curr_size].op.code = opcode; + tstate->interp->jit_tracer_code_buffer[curr_size].op.arg = oparg; + for (int i = 1; i < nsize; i++) { tstate->interp->jit_tracer_code_buffer[curr_size + i] = *(this_instr + i); } + if (needs_guard_ip) { +#ifdef Py_DEBUG + if (lltrace >= 3) { + printf("%d ADD_TO_BYTECODE_TRACE: %s %d\n", curr_size + nsize, _PyOpcode_OpName[TIER1_GUARD_IP], 0); + } +#endif + tstate->interp->jit_tracer_code_buffer[curr_size + nsize].op.code = TIER1_GUARD_IP; + PyObject *func = PyStackRef_AsPyObjectBorrow(frame->f_funcobj); + if (Py_IsNone(func)) { + func = NULL; // Trampoline frames don't set their func object field. + } + assert(func == NULL || PyFunction_Check(func)); + write_ptr(&tstate->interp->jit_tracer_code_buffer[curr_size + nsize + 1].cache, func); + +#ifdef Py_DEBUG + if (lltrace >= 3) { + printf("%d ADD_TO_BYTECODE_TRACE: %s %p\n", curr_size + nsize + 5, _PyOpcode_OpName[TIER1_SET_IP], frame->instr_ptr); + } +#endif + tstate->interp->jit_tracer_code_buffer[curr_size + nsize + 5].op.code = TIER1_SET_IP; + write_ptr(&tstate->interp->jit_tracer_code_buffer[curr_size + nsize + 6].cache, frame->instr_ptr); + + } + else { +#ifdef Py_DEBUG + if (lltrace >= 3) { + printf("%d ADD_TO_BYTECODE_TRACE: %s %p\n", curr_size + nsize, _PyOpcode_OpName[TIER1_SET_IP], frame->instr_ptr); + } +#endif + tstate->interp->jit_tracer_code_buffer[curr_size + nsize].op.code = TIER1_SET_IP; + write_ptr(&tstate->interp->jit_tracer_code_buffer[curr_size + nsize + 1].cache, frame->instr_ptr); + + } + + tstate->interp->jit_tracer_code_curr_size += total_size; return 0; } @@ -1061,11 +1142,11 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int _Py_CODEUNIT *next_instr; _PyStackRef *stack_pointer; entry.stack[0] = PyStackRef_NULL; + entry.frame.f_funcobj = PyStackRef_None; #ifdef Py_STACKREF_DEBUG entry.frame.f_funcobj = PyStackRef_None; #elif defined(Py_DEBUG) /* Set these to invalid but identifiable values for debugging. */ - entry.frame.f_funcobj = (_PyStackRef){.bits = 0xaaa0}; entry.frame.f_locals = (PyObject*)0xaaa1; entry.frame.frame_obj = (PyFrameObject*)0xaaa2; entry.frame.f_globals = (PyObject*)0xaaa3; @@ -1199,10 +1280,11 @@ tier2_start: assert(next_uop->opcode == _START_EXECUTOR || next_uop->opcode == _COLD_EXIT); tier2_dispatch: for (;;) { + frame->lltrace = 4; uopcode = next_uop->opcode; #ifdef Py_DEBUG - if (frame->lltrace >= 3) { - dump_stack(frame, stack_pointer); + if (1 && next_uop->opcode != _YIELD_VALUE) { + // dump_stack(frame, stack_pointer); if (next_uop->opcode == _START_EXECUTOR) { printf("%4d uop: ", 0); } diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index 1afe5d400379..c0f33dd5b31f 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -78,12 +78,6 @@ # define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, instruction_funcptr_table, oparg #endif -# define TRACING_DISPATCH_GOTO() do { \ - if (add_to_code_trace(tstate, this_instr)) { \ - LEAVE_TRACING(); \ - } \ - DISPATCH_GOTO(); \ - } while (0); #if _Py_TAIL_CALL_INTERP // Note: [[clang::musttail]] works for GCC 15, but not __attribute__((musttail)) at the moment. @@ -91,10 +85,12 @@ # define Py_PRESERVE_NONE_CC __attribute__((preserve_none)) Py_PRESERVE_NONE_CC typedef PyObject* (*py_tail_call_funcptr)(TAIL_CALL_PARAMS); +# define DISPATCH_TABLE_VAR instruction_funcptr_table +# define DISPATCH_TABLE instruction_funcptr_handler_table +# define TRACING_DISPATCH_TABLE instruction_funcptr_tracing_table # define TARGET(op) Py_PRESERVE_NONE_CC PyObject *_TAIL_CALL_##op(TAIL_CALL_PARAMS) # define TRACING_TARGET(op) Py_PRESERVE_NONE_CC PyObject *_TAIL_CALL_TRACING_##op(TAIL_CALL_PARAMS) -# define LEAVE_TRACING() instruction_funcptr_table = instruction_funcptr_handler_table; -# define ENTER_TRACING() instruction_funcptr_table = instruction_funcptr_tracing_table + # define DISPATCH_GOTO() \ do { \ Py_MUSTTAIL return (((py_tail_call_funcptr *)instruction_funcptr_table)[opcode])(TAIL_CALL_ARGS); \ @@ -116,11 +112,13 @@ # endif # define LABEL(name) TARGET(name) #elif USE_COMPUTED_GOTOS +# define DISPATCH_TABLE_VAR opcode_targets +# define DISPATCH_TABLE opcode_targets_table +# define TRACING_DISPATCH_TABLE opcode_tracing_targets_table # define TARGET(op) TARGET_##op: # define TRACING_TARGET(op) TARGET_TRACING_##op: # define DISPATCH_GOTO() goto *opcode_targets[opcode] -# define LEAVE_TRACING() opcode_targets = opcode_targets_table; -# define ENTER_TRACING() opcode_targets = opcode_tracing_targets_table; + # define JUMP_TO_LABEL(name) goto name; # define JUMP_TO_PREDICTED(name) goto PREDICTED_##name; # define LABEL(name) name: @@ -132,6 +130,27 @@ # define LABEL(name) name: #endif +#if _Py_TAIL_CALL_INTERP || USE_COMPUTED_GOTOS +# define IS_JIT_TRACING() (DISPATCH_TABLE_VAR == TRACING_DISPATCH_TABLE) +# define ENTER_TRACING() DISPATCH_TABLE_VAR = TRACING_DISPATCH_TABLE; +# define LEAVE_TRACING() DISPATCH_TABLE_VAR = DISPATCH_TABLE; +# define BAIL_TRACING() \ + LEAVE_TRACING(); \ + int err = _PyOptimizer_Optimize(frame, tstate); \ + tstate->interp->jit_tracer_code_curr_size = 0; \ + if (err < 0) { \ + JUMP_TO_LABEL(error); \ + } \ + DISPATCH(); +# define RECORD_TRACE() do { \ + frame->instr_ptr = next_instr; \ + if (add_to_code_trace(tstate, frame, this_instr, oparg)) { \ + BAIL_TRACING(); \ + } \ + } while (0); +#endif + + /* PRE_DISPATCH_GOTO() does lltrace if enabled. Normally a no-op */ #ifdef Py_DEBUG #define PRE_DISPATCH_GOTO() if (frame->lltrace >= 5) { \ @@ -188,9 +207,10 @@ do { \ #define TRACING_DISPATCH() \ { \ assert(frame->stackpointer == NULL); \ + RECORD_TRACE(); \ NEXTOPARG(); \ PRE_DISPATCH_GOTO(); \ - TRACING_DISPATCH_GOTO(); \ + DISPATCH_GOTO(); \ } /* Tuple access macros */ @@ -222,6 +242,7 @@ GETITEM(PyObject *v, Py_ssize_t i) { * and skipped instructions. */ #define JUMPBY(x) (next_instr += (x)) +#define TIER2_JUMPBY(x) (frame->instr_ptr += (x)) #define SKIP_OVER(x) (next_instr += (x)) #define STACK_LEVEL() ((int)(stack_pointer - _PyFrame_Stackbase(frame))) @@ -378,10 +399,18 @@ do { \ next_instr = _Py_jit_entry((EXECUTOR), frame, stack_pointer, tstate); \ frame = tstate->current_frame; \ stack_pointer = _PyFrame_GetStackPointer(frame); \ + int keep_tracing_bit = (uintptr_t)next_instr & 1; \ + next_instr = (_Py_CODEUNIT *)(((uintptr_t)next_instr) >> 1 << 1); \ if (next_instr == NULL) { \ next_instr = frame->instr_ptr; \ JUMP_TO_LABEL(error); \ } \ + if (keep_tracing_bit) { \ + ENTER_TRACING(); \ + } \ + else { \ + LEAVE_TRACING(); \ + } \ DISPATCH(); \ } while (0) @@ -392,13 +421,13 @@ do { \ goto tier2_start; \ } while (0) -#define GOTO_TIER_ONE(TARGET) \ +#define GOTO_TIER_ONE(TARGET, SHOULD_CONTINUE_TRACING) \ do \ { \ tstate->current_executor = NULL; \ OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); \ _PyFrame_SetStackPointer(frame, stack_pointer); \ - return TARGET; \ + return (_Py_CODEUNIT *)(((uintptr_t)(TARGET)) | SHOULD_CONTINUE_TRACING); \ } while (0) #define CURRENT_OPARG() (next_uop[-1].oparg) diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 0e4d86463761..0b5aee504012 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -1931,6 +1931,9 @@ _PyEval_FrameClearAndPop(tstate, dying); stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(frame->return_offset); + #if TIER_TWO + frame->instr_ptr += frame->return_offset; + #endif res = temp; LLTRACE_RESUME_FRAME(); stack_pointer[0] = res; @@ -2097,6 +2100,9 @@ #endif stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); + #if TIER_TWO + frame->instr_ptr += (1 + INLINE_CACHE_ENTRIES_SEND); + #endif value = PyStackRef_MakeHeapSafe(temp); LLTRACE_RESUME_FRAME(); stack_pointer[0] = value; @@ -4165,9 +4171,31 @@ break; } - /* _POP_JUMP_IF_FALSE is not a viable micro-op for tier 2 because it is replaced */ + case _POP_JUMP_IF_FALSE: { + TIER2_JUMPBY(2); + _PyStackRef cond; + oparg = CURRENT_OPARG(); + cond = stack_pointer[-1]; + assert(PyStackRef_BoolCheck(cond)); + int flag = PyStackRef_IsFalse(cond); + TIER2_JUMPBY(flag ? oparg : 0); + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); + break; + } - /* _POP_JUMP_IF_TRUE is not a viable micro-op for tier 2 because it is replaced */ + case _POP_JUMP_IF_TRUE: { + TIER2_JUMPBY(2); + _PyStackRef cond; + oparg = CURRENT_OPARG(); + cond = stack_pointer[-1]; + assert(PyStackRef_BoolCheck(cond)); + int flag = PyStackRef_IsTrue(cond); + TIER2_JUMPBY(flag ? oparg : 0); + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); + break; + } case _IS_NONE: { _PyStackRef value; @@ -4189,6 +4217,16 @@ break; } + case _JUMP_BACKWARD_NO_INTERRUPT: { + TIER2_JUMPBY(2); + oparg = CURRENT_OPARG(); + #if TIER_ONE + assert(oparg <= INSTR_OFFSET()); + #endif + TIER2_JUMPBY(-oparg); + break; + } + case _GET_LEN: { _PyStackRef obj; _PyStackRef len; @@ -4383,6 +4421,7 @@ _PyStackRef null_or_index; _PyStackRef iter; _PyStackRef next; + oparg = CURRENT_OPARG(); null_or_index = stack_pointer[-1]; iter = stack_pointer[-2]; _PyFrame_SetStackPointer(frame, stack_pointer); @@ -4392,6 +4431,7 @@ if (PyStackRef_IsError(item)) { JUMP_TO_ERROR(); } + TIER2_JUMPBY(oparg + 1); if (true) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); @@ -4445,7 +4485,43 @@ break; } - /* _ITER_NEXT_LIST is not a viable micro-op for tier 2 because it is replaced */ + case _ITER_NEXT_LIST: { + TIER2_JUMPBY(2); + _PyStackRef null_or_index; + _PyStackRef iter; + _PyStackRef next; + oparg = CURRENT_OPARG(); + null_or_index = stack_pointer[-1]; + iter = stack_pointer[-2]; + PyObject *list_o = PyStackRef_AsPyObjectBorrow(iter); + assert(PyList_CheckExact(list_o)); + #ifdef Py_GIL_DISABLED + assert(_Py_IsOwnedByCurrentThread(list_o) || + _PyObject_GC_IS_SHARED(list_o)); + STAT_INC(FOR_ITER, hit); + _PyFrame_SetStackPointer(frame, stack_pointer); + int result = _PyList_GetItemRefNoLock((PyListObject *)list_o, PyStackRef_UntagInt(null_or_index), &next); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (result < 0) { + UOP_STAT_INC(uopcode, miss); + JUMP_TO_JUMP_TARGET(); + } + if (result == 0) { + null_or_index = PyStackRef_TagInt(-1); + stack_pointer[-1] = null_or_index; + TIER2_JUMPBY(oparg + 1); + break; + } + #else + next = PyStackRef_FromPyObjectNew(PyList_GET_ITEM(list_o, PyStackRef_UntagInt(null_or_index))); + #endif + null_or_index = PyStackRef_IncrementTaggedIntNoOverflow(null_or_index); + stack_pointer[-1] = null_or_index; + stack_pointer[0] = next; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } case _ITER_NEXT_LIST_TIER_TWO: { _PyStackRef null_or_index; @@ -6749,6 +6825,9 @@ _PyThreadState_PopFrame(tstate, frame); frame = tstate->current_frame = prev; LOAD_IP(frame->return_offset); + #if TIER_TWO + frame->instr_ptr += (frame->return_offset); + #endif stack_pointer = _PyFrame_GetStackPointer(frame); res = PyStackRef_FromPyObjectStealMortal((PyObject *)gen); LLTRACE_RESUME_FRAME(); @@ -7422,7 +7501,7 @@ } case _DEOPT: { - GOTO_TIER_ONE(_PyFrame_GetBytecode(frame) + CURRENT_TARGET()); + GOTO_TIER_ONE(_PyFrame_GetBytecode(frame) + CURRENT_TARGET(), 0); break; } @@ -7430,7 +7509,7 @@ _PyFrame_SetStackPointer(frame, stack_pointer); int err = _Py_HandlePending(tstate); stack_pointer = _PyFrame_GetStackPointer(frame); - GOTO_TIER_ONE(err ? NULL : _PyFrame_GetBytecode(frame) + CURRENT_TARGET()); + GOTO_TIER_ONE(err ? NULL : _PyFrame_GetBytecode(frame) + CURRENT_TARGET(), 0); break; } @@ -7439,7 +7518,7 @@ uint32_t target = (uint32_t)CURRENT_OPERAND0(); assert(oparg == 0); frame->instr_ptr = _PyFrame_GetBytecode(frame) + target; - GOTO_TIER_ONE(NULL); + GOTO_TIER_ONE(NULL, 0); break; } @@ -7467,7 +7546,7 @@ _Py_BackoffCounter temperature = exit->temperature; if (!backoff_counter_triggers(temperature)) { exit->temperature = advance_backoff_counter(temperature); - GOTO_TIER_ONE(target); + GOTO_TIER_ONE(target, 0); } _PyExecutorObject *executor; if (target->op.code == ENTER_EXECUTOR) { @@ -7481,14 +7560,16 @@ stack_pointer = _PyFrame_GetStackPointer(frame); assert(tstate->current_executor == (PyObject *)previous_executor); int chain_depth = previous_executor->vm_data.chain_depth + 1; + tstate->interp->jit_tracer_initial_chain_depth = chain_depth; + tstate->interp->jit_tracer_initial_instr = target; + tstate->interp->jit_tracer_initial_code = _PyFrame_GetCode(frame); _PyFrame_SetStackPointer(frame, stack_pointer); - int optimized = _PyOptimizer_Optimize(frame, target, &executor, chain_depth); + tstate->interp->jit_tracer_initial_func = _PyFrame_GetFunction(frame); stack_pointer = _PyFrame_GetStackPointer(frame); - if (optimized <= 0) { - exit->temperature = restart_backoff_counter(temperature); - GOTO_TIER_ONE(optimized < 0 ? NULL : target); - } - exit->temperature = initial_temperature_backoff_counter(); + tstate->interp->jit_tracer_seen_initial_before = 0; + tstate->interp->jit_completed_loop = false; + exit->temperature = restart_backoff_counter(temperature); + GOTO_TIER_ONE(target, 1); } assert(tstate->jit_exit == exit); exit->executor = executor; @@ -7496,4 +7577,21 @@ break; } + case _GUARD_IP: { + PyObject *ip = (PyObject *)CURRENT_OPERAND0(); + if (frame->instr_ptr != (_Py_CODEUNIT *)ip) { + _PyFrame_SetStackPointer(frame, stack_pointer); + fprintf(stdout, "d:%p:%p\n", frame->instr_ptr, ip); + stack_pointer = _PyFrame_GetStackPointer(frame); + GOTO_TIER_ONE(frame->instr_ptr, 1); + } + break; + } + + case _DYNAMIC_EXIT: { + PyObject *ip = (PyObject *)CURRENT_OPERAND0(); + GOTO_TIER_ONE(frame->instr_ptr, 1); + break; + } + #undef TIER_TWO diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 884f2e928733..a9749abb5fad 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -5482,7 +5482,7 @@ assert(executor->vm_data.code == code); assert(executor->vm_data.valid); assert(tstate->current_executor == NULL); - if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { + if (IS_JIT_TRACING() || _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { opcode = executor->vm_data.opcode; oparg = (oparg & ~255) | executor->vm_data.oparg; next_instr = this_instr; @@ -7430,6 +7430,9 @@ _PyEval_FrameClearAndPop(tstate, dying); stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(frame->return_offset); + #if TIER_TWO + frame->instr_ptr += frame->return_offset; + #endif res = temp; LLTRACE_RESUME_FRAME(); } @@ -7498,6 +7501,9 @@ #endif stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); + #if TIER_TWO + frame->instr_ptr += (1 + INLINE_CACHE_ENTRIES_SEND); + #endif value = PyStackRef_MakeHeapSafe(temp); LLTRACE_RESUME_FRAME(); } @@ -7591,7 +7597,7 @@ { #if ENABLE_SPECIALIZATION if (this_instr->op.code == JUMP_BACKWARD) { - this_instr->op.code = tstate->interp->jit ? JUMP_BACKWARD_JIT : JUMP_BACKWARD_NO_JIT; + this_instr->op.code = (tstate->interp->jit && !PyStackRef_IsNull(frame->f_funcobj)) ? JUMP_BACKWARD_JIT : JUMP_BACKWARD_NO_JIT; next_instr = this_instr; DISPATCH_SAME_OPARG(); } @@ -7608,7 +7614,9 @@ } // _JUMP_BACKWARD_NO_INTERRUPT { + #if TIER_ONE assert(oparg <= INSTR_OFFSET()); + #endif JUMPBY(-oparg); } DISPATCH(); @@ -7637,35 +7645,42 @@ } // _JUMP_BACKWARD_NO_INTERRUPT { + #if TIER_ONE assert(oparg <= INSTR_OFFSET()); + #endif JUMPBY(-oparg); } // _JIT { #ifdef _Py_TIER2 _Py_BackoffCounter counter = this_instr[1].counter; - if (backoff_counter_triggers(counter) && this_instr->op.code == JUMP_BACKWARD_JIT) { + if (!IS_JIT_TRACING() && backoff_counter_triggers(counter) && this_instr->op.code == JUMP_BACKWARD_JIT) { _Py_CODEUNIT *start = this_instr; - while (oparg > 255) { - oparg >>= 8; + int curr_oparg = oparg; + while (curr_oparg > 255) { + curr_oparg >>= 8; start--; } if (tstate->interp->jit_tracer_code_buffer == NULL) { _PyFrame_SetStackPointer(frame, stack_pointer); tstate->interp->jit_tracer_code_buffer = (_Py_CODEUNIT *)_PyObject_VirtualAlloc(TRACER_BUFFER_SIZE); stack_pointer = _PyFrame_GetStackPointer(frame); - tstate->interp->jit_tracer_code_curr_size = 0; if (tstate->interp->jit_tracer_code_buffer == NULL) { DISPATCH(); } - } - if (this_instr == tstate->interp->jit_tracer_initial_instr) { - LEAVE_TRACING(); - DISPATCH(); + tstate->interp->jit_tracer_code_curr_size = 0; } ENTER_TRACING(); if (tstate->interp->jit_tracer_code_curr_size == 0) { - tstate->interp->jit_tracer_initial_instr = this_instr; + tstate->interp->jit_tracer_initial_instr = next_instr; + tstate->interp->jit_tracer_initial_code = _PyFrame_GetCode(frame); + _PyFrame_SetStackPointer(frame, stack_pointer); + tstate->interp->jit_tracer_initial_func = _PyFrame_GetFunction(frame); + stack_pointer = _PyFrame_GetStackPointer(frame); + tstate->interp->jit_tracer_seen_initial_before = 0; + tstate->interp->jit_completed_loop = false; + tstate->interp->jit_tracer_initial_stack_depth = (int)STACK_LEVEL(); + tstate->interp->jit_tracer_initial_chain_depth = 0; } DISPATCH(); } @@ -7685,7 +7700,9 @@ frame->instr_ptr = next_instr; next_instr += 1; INSTRUCTION_STATS(JUMP_BACKWARD_NO_INTERRUPT); + #if TIER_ONE assert(oparg <= INSTR_OFFSET()); + #endif JUMPBY(-oparg); DISPATCH(); } @@ -7711,7 +7728,9 @@ } // _JUMP_BACKWARD_NO_INTERRUPT { + #if TIER_ONE assert(oparg <= INSTR_OFFSET()); + #endif JUMPBY(-oparg); } DISPATCH(); @@ -9967,8 +9986,6 @@ int opcode = POP_JUMP_IF_FALSE; (void)(opcode); #endif - _Py_CODEUNIT* const this_instr = next_instr; - (void)this_instr; frame->instr_ptr = next_instr; next_instr += 2; INSTRUCTION_STATS(POP_JUMP_IF_FALSE); @@ -9977,8 +9994,7 @@ cond = stack_pointer[-1]; assert(PyStackRef_BoolCheck(cond)); int flag = PyStackRef_IsFalse(cond); - RECORD_BRANCH_TAKEN(this_instr[1].cache, flag); - JUMPBY(flag ? oparg : next_instr->op.code == NOT_TAKEN); + JUMPBY(flag ? oparg : 0); stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); @@ -9989,8 +10005,6 @@ int opcode = POP_JUMP_IF_NONE; (void)(opcode); #endif - _Py_CODEUNIT* const this_instr = next_instr; - (void)this_instr; frame->instr_ptr = next_instr; next_instr += 2; INSTRUCTION_STATS(POP_JUMP_IF_NONE); @@ -10019,8 +10033,7 @@ cond = b; assert(PyStackRef_BoolCheck(cond)); int flag = PyStackRef_IsTrue(cond); - RECORD_BRANCH_TAKEN(this_instr[1].cache, flag); - JUMPBY(flag ? oparg : next_instr->op.code == NOT_TAKEN); + JUMPBY(flag ? oparg : 0); } stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); @@ -10032,8 +10045,6 @@ int opcode = POP_JUMP_IF_NOT_NONE; (void)(opcode); #endif - _Py_CODEUNIT* const this_instr = next_instr; - (void)this_instr; frame->instr_ptr = next_instr; next_instr += 2; INSTRUCTION_STATS(POP_JUMP_IF_NOT_NONE); @@ -10062,8 +10073,7 @@ cond = b; assert(PyStackRef_BoolCheck(cond)); int flag = PyStackRef_IsFalse(cond); - RECORD_BRANCH_TAKEN(this_instr[1].cache, flag); - JUMPBY(flag ? oparg : next_instr->op.code == NOT_TAKEN); + JUMPBY(flag ? oparg : 0); } stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); @@ -10075,8 +10085,6 @@ int opcode = POP_JUMP_IF_TRUE; (void)(opcode); #endif - _Py_CODEUNIT* const this_instr = next_instr; - (void)this_instr; frame->instr_ptr = next_instr; next_instr += 2; INSTRUCTION_STATS(POP_JUMP_IF_TRUE); @@ -10085,8 +10093,7 @@ cond = stack_pointer[-1]; assert(PyStackRef_BoolCheck(cond)); int flag = PyStackRef_IsTrue(cond); - RECORD_BRANCH_TAKEN(this_instr[1].cache, flag); - JUMPBY(flag ? oparg : next_instr->op.code == NOT_TAKEN); + JUMPBY(flag ? oparg : 0); stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); DISPATCH(); @@ -10369,6 +10376,9 @@ _PyThreadState_PopFrame(tstate, frame); frame = tstate->current_frame = prev; LOAD_IP(frame->return_offset); + #if TIER_TWO + frame->instr_ptr += (frame->return_offset); + #endif stack_pointer = _PyFrame_GetStackPointer(frame); res = PyStackRef_FromPyObjectStealMortal((PyObject *)gen); LLTRACE_RESUME_FRAME(); @@ -10401,6 +10411,9 @@ _PyEval_FrameClearAndPop(tstate, dying); stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(frame->return_offset); + #if TIER_TWO + frame->instr_ptr += frame->return_offset; + #endif res = temp; LLTRACE_RESUME_FRAME(); stack_pointer[0] = res; @@ -11415,6 +11428,41 @@ DISPATCH(); } + TARGET(TIER1_GUARD_IP) { + #if _Py_TAIL_CALL_INTERP + int opcode = TIER1_GUARD_IP; + (void)(opcode); + #endif + _Py_CODEUNIT* const this_instr = next_instr; + (void)this_instr; + next_instr += 5; + INSTRUCTION_STATS(TIER1_GUARD_IP); + PyObject *func_ptr = read_obj(&this_instr[1].cache); + (void)func_ptr; + _PyFrame_SetStackPointer(frame, stack_pointer); + (void)(func_ptr); + stack_pointer = _PyFrame_GetStackPointer(frame); + DISPATCH(); + } + + TARGET(TIER1_SET_IP) { + #if _Py_TAIL_CALL_INTERP + int opcode = TIER1_SET_IP; + (void)(opcode); + #endif + _Py_CODEUNIT* const this_instr = next_instr; + (void)this_instr; + frame->instr_ptr = next_instr; + next_instr += 5; + INSTRUCTION_STATS(TIER1_SET_IP); + PyObject *ip = read_obj(&this_instr[1].cache); + (void)ip; + _PyFrame_SetStackPointer(frame, stack_pointer); + (void)(ip); + stack_pointer = _PyFrame_GetStackPointer(frame); + DISPATCH(); + } + TARGET(TO_BOOL) { #if _Py_TAIL_CALL_INTERP int opcode = TO_BOOL; @@ -12089,6 +12137,9 @@ #endif stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); + #if TIER_TWO + frame->instr_ptr += (1 + INLINE_CACHE_ENTRIES_SEND); + #endif value = PyStackRef_MakeHeapSafe(temp); LLTRACE_RESUME_FRAME(); stack_pointer[0] = value; @@ -17617,7 +17668,7 @@ assert(executor->vm_data.code == code); assert(executor->vm_data.valid); assert(tstate->current_executor == NULL); - if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { + if (IS_JIT_TRACING() || _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { opcode = executor->vm_data.opcode; oparg = (oparg & ~255) | executor->vm_data.oparg; next_instr = this_instr; @@ -19589,6 +19640,9 @@ _PyEval_FrameClearAndPop(tstate, dying); stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(frame->return_offset); + #if TIER_TWO + frame->instr_ptr += frame->return_offset; + #endif res = temp; LLTRACE_RESUME_FRAME(); } @@ -19657,6 +19711,9 @@ #endif stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); + #if TIER_TWO + frame->instr_ptr += (1 + INLINE_CACHE_ENTRIES_SEND); + #endif value = PyStackRef_MakeHeapSafe(temp); LLTRACE_RESUME_FRAME(); } @@ -19754,7 +19811,7 @@ { #if ENABLE_SPECIALIZATION if (this_instr->op.code == JUMP_BACKWARD) { - this_instr->op.code = tstate->interp->jit ? JUMP_BACKWARD_JIT : JUMP_BACKWARD_NO_JIT; + this_instr->op.code = (tstate->interp->jit && !PyStackRef_IsNull(frame->f_funcobj)) ? JUMP_BACKWARD_JIT : JUMP_BACKWARD_NO_JIT; next_instr = this_instr; DISPATCH_SAME_OPARG(); } @@ -19771,7 +19828,9 @@ } // _JUMP_BACKWARD_NO_INTERRUPT { + #if TIER_ONE assert(oparg <= INSTR_OFFSET()); + #endif JUMPBY(-oparg); } TRACING_DISPATCH(); @@ -19800,35 +19859,42 @@ } // _JUMP_BACKWARD_NO_INTERRUPT { + #if TIER_ONE assert(oparg <= INSTR_OFFSET()); + #endif JUMPBY(-oparg); } // _JIT { #ifdef _Py_TIER2 _Py_BackoffCounter counter = this_instr[1].counter; - if (backoff_counter_triggers(counter) && this_instr->op.code == JUMP_BACKWARD_JIT) { + if (!IS_JIT_TRACING() && backoff_counter_triggers(counter) && this_instr->op.code == JUMP_BACKWARD_JIT) { _Py_CODEUNIT *start = this_instr; - while (oparg > 255) { - oparg >>= 8; + int curr_oparg = oparg; + while (curr_oparg > 255) { + curr_oparg >>= 8; start--; } if (tstate->interp->jit_tracer_code_buffer == NULL) { _PyFrame_SetStackPointer(frame, stack_pointer); tstate->interp->jit_tracer_code_buffer = (_Py_CODEUNIT *)_PyObject_VirtualAlloc(TRACER_BUFFER_SIZE); stack_pointer = _PyFrame_GetStackPointer(frame); - tstate->interp->jit_tracer_code_curr_size = 0; if (tstate->interp->jit_tracer_code_buffer == NULL) { TRACING_DISPATCH(); } - } - if (this_instr == tstate->interp->jit_tracer_initial_instr) { - LEAVE_TRACING(); - TRACING_DISPATCH(); + tstate->interp->jit_tracer_code_curr_size = 0; } ENTER_TRACING(); if (tstate->interp->jit_tracer_code_curr_size == 0) { - tstate->interp->jit_tracer_initial_instr = this_instr; + tstate->interp->jit_tracer_initial_instr = next_instr; + tstate->interp->jit_tracer_initial_code = _PyFrame_GetCode(frame); + _PyFrame_SetStackPointer(frame, stack_pointer); + tstate->interp->jit_tracer_initial_func = _PyFrame_GetFunction(frame); + stack_pointer = _PyFrame_GetStackPointer(frame); + tstate->interp->jit_tracer_seen_initial_before = 0; + tstate->interp->jit_completed_loop = false; + tstate->interp->jit_tracer_initial_stack_depth = (int)STACK_LEVEL(); + tstate->interp->jit_tracer_initial_chain_depth = 0; } TRACING_DISPATCH(); } @@ -19850,7 +19916,9 @@ frame->instr_ptr = next_instr; next_instr += 1; INSTRUCTION_STATS(JUMP_BACKWARD_NO_INTERRUPT); + #if TIER_ONE assert(oparg <= INSTR_OFFSET()); + #endif JUMPBY(-oparg); TRACING_DISPATCH(); } @@ -19878,7 +19946,9 @@ } // _JUMP_BACKWARD_NO_INTERRUPT { + #if TIER_ONE assert(oparg <= INSTR_OFFSET()); + #endif JUMPBY(-oparg); } TRACING_DISPATCH(); @@ -22204,8 +22274,7 @@ cond = stack_pointer[-1]; assert(PyStackRef_BoolCheck(cond)); int flag = PyStackRef_IsFalse(cond); - RECORD_BRANCH_TAKEN(this_instr[1].cache, flag); - JUMPBY(flag ? oparg : next_instr->op.code == NOT_TAKEN); + JUMPBY(flag ? oparg : 0); stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); TRACING_DISPATCH(); @@ -22246,8 +22315,7 @@ cond = b; assert(PyStackRef_BoolCheck(cond)); int flag = PyStackRef_IsTrue(cond); - RECORD_BRANCH_TAKEN(this_instr[1].cache, flag); - JUMPBY(flag ? oparg : next_instr->op.code == NOT_TAKEN); + JUMPBY(flag ? oparg : 0); } stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); @@ -22289,8 +22357,7 @@ cond = b; assert(PyStackRef_BoolCheck(cond)); int flag = PyStackRef_IsFalse(cond); - RECORD_BRANCH_TAKEN(this_instr[1].cache, flag); - JUMPBY(flag ? oparg : next_instr->op.code == NOT_TAKEN); + JUMPBY(flag ? oparg : 0); } stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); @@ -22312,8 +22379,7 @@ cond = stack_pointer[-1]; assert(PyStackRef_BoolCheck(cond)); int flag = PyStackRef_IsTrue(cond); - RECORD_BRANCH_TAKEN(this_instr[1].cache, flag); - JUMPBY(flag ? oparg : next_instr->op.code == NOT_TAKEN); + JUMPBY(flag ? oparg : 0); stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); TRACING_DISPATCH(); @@ -22606,6 +22672,9 @@ _PyThreadState_PopFrame(tstate, frame); frame = tstate->current_frame = prev; LOAD_IP(frame->return_offset); + #if TIER_TWO + frame->instr_ptr += (frame->return_offset); + #endif stack_pointer = _PyFrame_GetStackPointer(frame); res = PyStackRef_FromPyObjectStealMortal((PyObject *)gen); LLTRACE_RESUME_FRAME(); @@ -22640,6 +22709,9 @@ _PyEval_FrameClearAndPop(tstate, dying); stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(frame->return_offset); + #if TIER_TWO + frame->instr_ptr += frame->return_offset; + #endif res = temp; LLTRACE_RESUME_FRAME(); stack_pointer[0] = res; @@ -23678,6 +23750,41 @@ TRACING_DISPATCH(); } + TRACING_TARGET(TIER1_GUARD_IP) { + #if _Py_TAIL_CALL_INTERP + int opcode = TIER1_GUARD_IP; + (void)(opcode); + #endif + _Py_CODEUNIT* const this_instr = next_instr; + (void)this_instr; + next_instr += 5; + INSTRUCTION_STATS(TIER1_GUARD_IP); + PyObject *func_ptr = read_obj(&this_instr[1].cache); + (void)func_ptr; + _PyFrame_SetStackPointer(frame, stack_pointer); + (void)(func_ptr); + stack_pointer = _PyFrame_GetStackPointer(frame); + TRACING_DISPATCH(); + } + + TRACING_TARGET(TIER1_SET_IP) { + #if _Py_TAIL_CALL_INTERP + int opcode = TIER1_SET_IP; + (void)(opcode); + #endif + _Py_CODEUNIT* const this_instr = next_instr; + (void)this_instr; + frame->instr_ptr = next_instr; + next_instr += 5; + INSTRUCTION_STATS(TIER1_SET_IP); + PyObject *ip = read_obj(&this_instr[1].cache); + (void)ip; + _PyFrame_SetStackPointer(frame, stack_pointer); + (void)(ip); + stack_pointer = _PyFrame_GetStackPointer(frame); + TRACING_DISPATCH(); + } + TRACING_TARGET(TO_BOOL) { #if _Py_TAIL_CALL_INTERP int opcode = TO_BOOL; @@ -24364,6 +24471,9 @@ #endif stack_pointer = _PyFrame_GetStackPointer(frame); LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); + #if TIER_TWO + frame->instr_ptr += (1 + INLINE_CACHE_ENTRIES_SEND); + #endif value = PyStackRef_MakeHeapSafe(temp); LLTRACE_RESUME_FRAME(); stack_pointer[0] = value; diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 299739764919..47d6290b0dc1 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -39,6 +39,8 @@ static void *opcode_targets_table[256] = { &&TARGET_SETUP_ANNOTATIONS, &&TARGET_STORE_SLICE, &&TARGET_STORE_SUBSCR, + &&TARGET_TIER1_GUARD_IP, + &&TARGET_TIER1_SET_IP, &&TARGET_TO_BOOL, &&TARGET_UNARY_INVERT, &&TARGET_UNARY_NEGATIVE, @@ -126,8 +128,6 @@ static void *opcode_targets_table[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, &&TARGET_RESUME, &&TARGET_BINARY_OP_ADD_FLOAT, &&TARGET_BINARY_OP_ADD_INT, @@ -297,6 +297,8 @@ static void *opcode_tracing_targets_table[256] = { &&TARGET_TRACING_SETUP_ANNOTATIONS, &&TARGET_TRACING_STORE_SLICE, &&TARGET_TRACING_STORE_SUBSCR, + &&TARGET_TRACING_TIER1_GUARD_IP, + &&TARGET_TRACING_TIER1_SET_IP, &&TARGET_TRACING_TO_BOOL, &&TARGET_TRACING_UNARY_INVERT, &&TARGET_TRACING_UNARY_NEGATIVE, @@ -384,8 +386,6 @@ static void *opcode_tracing_targets_table[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, &&TARGET_TRACING_RESUME, &&TARGET_TRACING_BINARY_OP_ADD_FLOAT, &&TARGET_TRACING_BINARY_OP_ADD_INT, @@ -943,6 +943,10 @@ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_STORE_SUBSCR_LIST_INT(TAIL_CALL_ Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_TRACING_STORE_SUBSCR_LIST_INT(TAIL_CALL_PARAMS); Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_SWAP(TAIL_CALL_PARAMS); Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_TRACING_SWAP(TAIL_CALL_PARAMS); +Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_TIER1_GUARD_IP(TAIL_CALL_PARAMS); +Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_TRACING_TIER1_GUARD_IP(TAIL_CALL_PARAMS); +Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_TIER1_SET_IP(TAIL_CALL_PARAMS); +Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_TRACING_TIER1_SET_IP(TAIL_CALL_PARAMS); Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_TO_BOOL(TAIL_CALL_PARAMS); Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_TRACING_TO_BOOL(TAIL_CALL_PARAMS); Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_TO_BOOL_ALWAYS_TRUE(TAIL_CALL_PARAMS); @@ -1197,6 +1201,8 @@ static py_tail_call_funcptr instruction_funcptr_handler_table[256] = { [STORE_SUBSCR_DICT] = _TAIL_CALL_STORE_SUBSCR_DICT, [STORE_SUBSCR_LIST_INT] = _TAIL_CALL_STORE_SUBSCR_LIST_INT, [SWAP] = _TAIL_CALL_SWAP, + [TIER1_GUARD_IP] = _TAIL_CALL_TIER1_GUARD_IP, + [TIER1_SET_IP] = _TAIL_CALL_TIER1_SET_IP, [TO_BOOL] = _TAIL_CALL_TO_BOOL, [TO_BOOL_ALWAYS_TRUE] = _TAIL_CALL_TO_BOOL_ALWAYS_TRUE, [TO_BOOL_BOOL] = _TAIL_CALL_TO_BOOL_BOOL, @@ -1214,8 +1220,6 @@ static py_tail_call_funcptr instruction_funcptr_handler_table[256] = { [UNPACK_SEQUENCE_TWO_TUPLE] = _TAIL_CALL_UNPACK_SEQUENCE_TWO_TUPLE, [WITH_EXCEPT_START] = _TAIL_CALL_WITH_EXCEPT_START, [YIELD_VALUE] = _TAIL_CALL_YIELD_VALUE, - [121] = _TAIL_CALL_UNKNOWN_OPCODE, - [122] = _TAIL_CALL_UNKNOWN_OPCODE, [123] = _TAIL_CALL_UNKNOWN_OPCODE, [124] = _TAIL_CALL_UNKNOWN_OPCODE, [125] = _TAIL_CALL_UNKNOWN_OPCODE, @@ -1455,6 +1459,8 @@ static py_tail_call_funcptr instruction_funcptr_tracing_table[256] = { [STORE_SUBSCR_DICT] = _TAIL_CALL_TRACING_STORE_SUBSCR_DICT, [STORE_SUBSCR_LIST_INT] = _TAIL_CALL_TRACING_STORE_SUBSCR_LIST_INT, [SWAP] = _TAIL_CALL_TRACING_SWAP, + [TIER1_GUARD_IP] = _TAIL_CALL_TRACING_TIER1_GUARD_IP, + [TIER1_SET_IP] = _TAIL_CALL_TRACING_TIER1_SET_IP, [TO_BOOL] = _TAIL_CALL_TRACING_TO_BOOL, [TO_BOOL_ALWAYS_TRUE] = _TAIL_CALL_TRACING_TO_BOOL_ALWAYS_TRUE, [TO_BOOL_BOOL] = _TAIL_CALL_TRACING_TO_BOOL_BOOL, @@ -1472,8 +1478,6 @@ static py_tail_call_funcptr instruction_funcptr_tracing_table[256] = { [UNPACK_SEQUENCE_TWO_TUPLE] = _TAIL_CALL_TRACING_UNPACK_SEQUENCE_TWO_TUPLE, [WITH_EXCEPT_START] = _TAIL_CALL_TRACING_WITH_EXCEPT_START, [YIELD_VALUE] = _TAIL_CALL_TRACING_YIELD_VALUE, - [121] = _TAIL_CALL_UNKNOWN_OPCODE, - [122] = _TAIL_CALL_UNKNOWN_OPCODE, [123] = _TAIL_CALL_UNKNOWN_OPCODE, [124] = _TAIL_CALL_UNKNOWN_OPCODE, [125] = _TAIL_CALL_UNKNOWN_OPCODE, diff --git a/Python/optimizer.c b/Python/optimizer.c index 53f1500f3989..e4ccca924302 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -33,6 +33,9 @@ static bool has_space_for_executor(PyCodeObject *code, _Py_CODEUNIT *instr) { + if (code == (PyCodeObject *)&_Py_InitCleanup) { + return false; + } if (instr->op.code == ENTER_EXECUTOR) { return true; } @@ -102,8 +105,8 @@ static _PyExecutorObject * make_executor_from_uops(_PyUOpInstruction *buffer, int length, const _PyBloomFilter *dependencies); static int -uop_optimize(_PyInterpreterFrame *frame, _Py_CODEUNIT *instr, - _PyExecutorObject **exec_ptr, int curr_stackentries, +uop_optimize(_PyInterpreterFrame *frame, PyThreadState *tstate, + _PyExecutorObject **exec_ptr, bool progress_needed); /* Returns 1 if optimized, 0 if not optimized, and -1 for an error. @@ -112,13 +115,14 @@ uop_optimize(_PyInterpreterFrame *frame, _Py_CODEUNIT *instr, // gh-137573: inlining this function causes stack overflows Py_NO_INLINE int _PyOptimizer_Optimize( - _PyInterpreterFrame *frame, _Py_CODEUNIT *start, - _PyExecutorObject **executor_ptr, int chain_depth) + _PyInterpreterFrame *frame, PyThreadState *tstate) { _PyStackRef *stack_pointer = frame->stackpointer; PyInterpreterState *interp = _PyInterpreterState_GET(); + int chain_depth = tstate->interp->jit_tracer_initial_chain_depth; assert(interp->jit); assert(!interp->compiling); + assert(tstate->interp->jit_tracer_initial_stack_depth >= 0); interp->compiling = true; // The first executor in a chain and the MAX_CHAIN_DEPTH'th executor *must* // make progress in order to avoid infinite loops or excessively-long @@ -126,18 +130,20 @@ _PyOptimizer_Optimize( // this is true, since a deopt won't infinitely re-enter the executor: chain_depth %= MAX_CHAIN_DEPTH; bool progress_needed = chain_depth == 0; - PyCodeObject *code = _PyFrame_GetCode(frame); + PyCodeObject *code = (PyCodeObject *)tstate->interp->jit_tracer_initial_func->func_code; assert(PyCode_Check(code)); + _Py_CODEUNIT *start = tstate->interp->jit_tracer_initial_instr; if (progress_needed && !has_space_for_executor(code, start)) { interp->compiling = false; return 0; } - int err = uop_optimize(frame, start, executor_ptr, (int)(stack_pointer - _PyFrame_Stackbase(frame)), progress_needed); + _PyExecutorObject *executor; + int err = uop_optimize(frame, tstate, &executor, progress_needed); if (err <= 0) { interp->compiling = false; return err; } - assert(*executor_ptr != NULL); + assert(executor != NULL); if (progress_needed) { int index = get_index_for_executor(code, start); if (index < 0) { @@ -147,17 +153,17 @@ _PyOptimizer_Optimize( * If an optimizer has already produced an executor, * it might get confused by the executor disappearing, * but there is not much we can do about that here. */ - Py_DECREF(*executor_ptr); + Py_DECREF(executor); interp->compiling = false; return 0; } - insert_executor(code, start, index, *executor_ptr); + insert_executor(code, start, index, executor); } else { - (*executor_ptr)->vm_data.code = NULL; + executor->vm_data.code = NULL; } - (*executor_ptr)->vm_data.chain_depth = chain_depth; - assert((*executor_ptr)->vm_data.valid); + executor->vm_data.chain_depth = chain_depth; + assert(executor->vm_data.valid); interp->compiling = false; return 1; } @@ -435,12 +441,12 @@ PyTypeObject _PyUOpExecutor_Type = { /* TO DO -- Generate these tables */ static const uint16_t _PyUOp_Replacements[MAX_UOP_ID + 1] = { + [_CHECK_PERIODIC_AT_END] = _TIER2_RESUME_CHECK, [_ITER_JUMP_RANGE] = _GUARD_NOT_EXHAUSTED_RANGE, [_ITER_JUMP_LIST] = _GUARD_NOT_EXHAUSTED_LIST, [_ITER_JUMP_TUPLE] = _GUARD_NOT_EXHAUSTED_TUPLE, [_FOR_ITER] = _FOR_ITER_TIER_TWO, [_ITER_NEXT_LIST] = _ITER_NEXT_LIST_TIER_TWO, - [_CHECK_PERIODIC_AT_END] = _TIER2_RESUME_CHECK, }; static const uint8_t @@ -451,18 +457,6 @@ is_for_iter_test[MAX_UOP_ID + 1] = { [_FOR_ITER_TIER_TWO] = 1, }; -static const uint16_t -BRANCH_TO_GUARD[4][2] = { - [POP_JUMP_IF_FALSE - POP_JUMP_IF_FALSE][0] = _GUARD_IS_TRUE_POP, - [POP_JUMP_IF_FALSE - POP_JUMP_IF_FALSE][1] = _GUARD_IS_FALSE_POP, - [POP_JUMP_IF_TRUE - POP_JUMP_IF_FALSE][0] = _GUARD_IS_FALSE_POP, - [POP_JUMP_IF_TRUE - POP_JUMP_IF_FALSE][1] = _GUARD_IS_TRUE_POP, - [POP_JUMP_IF_NONE - POP_JUMP_IF_FALSE][0] = _GUARD_IS_NOT_NONE_POP, - [POP_JUMP_IF_NONE - POP_JUMP_IF_FALSE][1] = _GUARD_IS_NONE_POP, - [POP_JUMP_IF_NOT_NONE - POP_JUMP_IF_FALSE][0] = _GUARD_IS_NONE_POP, - [POP_JUMP_IF_NOT_NONE - POP_JUMP_IF_FALSE][1] = _GUARD_IS_NOT_NONE_POP, -}; - #define CONFIDENCE_RANGE 1000 #define CONFIDENCE_CUTOFF 333 @@ -525,27 +519,6 @@ add_to_trace( // Reserve space for N uops, plus 3 for _SET_IP, _CHECK_VALIDITY and _EXIT_TRACE #define RESERVE(needed) RESERVE_RAW((needed) + 3, _PyUOpName(opcode)) -// Trace stack operations (used by _PUSH_FRAME, _RETURN_VALUE) -#define TRACE_STACK_PUSH() \ - if (trace_stack_depth >= TRACE_STACK_SIZE) { \ - DPRINTF(2, "Trace stack overflow\n"); \ - OPT_STAT_INC(trace_stack_overflow); \ - return 0; \ - } \ - assert(func == NULL || func->func_code == (PyObject *)code); \ - trace_stack[trace_stack_depth].func = func; \ - trace_stack[trace_stack_depth].code = code; \ - trace_stack[trace_stack_depth].instr = instr; \ - trace_stack_depth++; -#define TRACE_STACK_POP() \ - if (trace_stack_depth <= 0) { \ - Py_FatalError("Trace stack underflow\n"); \ - } \ - trace_stack_depth--; \ - func = trace_stack[trace_stack_depth].func; \ - code = trace_stack[trace_stack_depth].code; \ - assert(func == NULL || func->func_code == (PyObject *)code); \ - instr = trace_stack[trace_stack_depth].instr; /* Returns the length of the trace on success, * 0 if it failed to produce a worthwhile trace, @@ -554,33 +527,25 @@ add_to_trace( static int translate_bytecode_to_trace( _PyInterpreterFrame *frame, - _Py_CODEUNIT *instr, + PyThreadState *tstate, _PyUOpInstruction *trace, int buffer_size, _PyBloomFilter *dependencies, bool progress_needed) { bool first = true; - PyCodeObject *code = _PyFrame_GetCode(frame); - PyFunctionObject *func = _PyFrame_GetFunction(frame); - assert(PyFunction_Check(func)); + PyCodeObject *code = tstate->interp->jit_tracer_initial_code;; + PyFunctionObject *func = tstate->interp->jit_tracer_initial_func; PyCodeObject *initial_code = code; _Py_BloomFilter_Add(dependencies, initial_code); - _Py_CODEUNIT *initial_instr = instr; + _Py_CODEUNIT *target_instr = tstate->interp->jit_tracer_initial_instr; + _Py_CODEUNIT *initial_instr = tstate->interp->jit_tracer_code_buffer; int trace_length = 0; // Leave space for possible trailing _EXIT_TRACE int max_length = buffer_size-2; - struct { - PyFunctionObject *func; - PyCodeObject *code; - _Py_CODEUNIT *instr; - } trace_stack[TRACE_STACK_SIZE]; - int trace_stack_depth = 0; - int confidence = CONFIDENCE_RANGE; // Adjusted by branch instructions - bool jump_seen = false; #ifdef Py_DEBUG char *python_lltrace = Py_GETENV("PYTHON_LLTRACE"); - int lltrace = 0; + int lltrace = 3; if (python_lltrace != NULL && *python_lltrace >= '0') { lltrace = *python_lltrace - '0'; // TODO: Parse an int and all that } @@ -591,55 +556,40 @@ translate_bytecode_to_trace( PyUnicode_AsUTF8(code->co_qualname), PyUnicode_AsUTF8(code->co_filename), code->co_firstlineno, - 2 * INSTR_IP(initial_instr, code)); - ADD_TO_TRACE(_START_EXECUTOR, 0, (uintptr_t)instr, INSTR_IP(instr, code)); + 2 * INSTR_IP(target_instr, code)); + ADD_TO_TRACE(_START_EXECUTOR, 0, (uintptr_t)target_instr, INSTR_IP(target_instr, code)); ADD_TO_TRACE(_MAKE_WARM, 0, 0, 0); uint32_t target = 0; + bool preceded_by_for_iter = false; - for (;;) { - target = INSTR_IP(instr, code); + for (int x = 0; x < tstate->interp->jit_tracer_code_curr_size;) { + target = INSTR_IP(target_instr, code); // One for possible _DEOPT, one because _CHECK_VALIDITY itself might _DEOPT max_length-=2; - uint32_t opcode = instr->op.code; - uint32_t oparg = instr->op.arg; - - if (!first && instr == initial_instr) { - // We have looped around to the start: - RESERVE(1); - ADD_TO_TRACE(_JUMP_TO_TOP, 0, 0, 0); - goto done; - } + uint32_t opcode = initial_instr[x].op.code; + uint32_t oparg = initial_instr[x].op.arg; DPRINTF(2, "%d: %s(%d)\n", target, _PyOpcode_OpName[opcode], oparg); if (opcode == EXTENDED_ARG) { - instr++; - opcode = instr->op.code; - oparg = (oparg << 8) | instr->op.arg; + x++; + opcode = initial_instr[x].op.code; + oparg = (oparg << 8) | initial_instr[x].op.arg; if (opcode == EXTENDED_ARG) { - instr--; + x--; goto done; } } - if (opcode == ENTER_EXECUTOR) { - // We have a couple of options here. We *could* peek "underneath" - // this executor and continue tracing, which could give us a longer, - // more optimizeable trace (at the expense of lots of duplicated - // tier two code). Instead, we choose to just end here and stitch to - // the other trace, which allows a side-exit traces to rejoin the - // "main" trace periodically (and also helps protect us against - // pathological behavior where the amount of tier two code explodes - // for a medium-length, branchy code path). This seems to work - // better in practice, but in the future we could be smarter about - // what we do here: - goto done; - } assert(opcode != ENTER_EXECUTOR && opcode != EXTENDED_ARG); - RESERVE_RAW(2, "_CHECK_VALIDITY"); - ADD_TO_TRACE(_CHECK_VALIDITY, 0, 0, target); - if (!OPCODE_HAS_NO_SAVE_IP(opcode)) { - RESERVE_RAW(2, "_SET_IP"); - ADD_TO_TRACE(_SET_IP, 0, (uintptr_t)instr, target); + if (opcode != NOP) { + if (opcode != TIER1_GUARD_IP) { + RESERVE_RAW(1, "_CHECK_VALIDITY"); + ADD_TO_TRACE(_CHECK_VALIDITY, 0, 0, target); + } + if (!OPCODE_HAS_NO_SAVE_IP(opcode)) { + RESERVE_RAW(2, "_SET_IP"); + ADD_TO_TRACE(_SET_IP, 0, (uintptr_t)target_instr, target); + } } /* Special case the first instruction, @@ -663,69 +613,56 @@ translate_bytecode_to_trace( RESERVE_RAW(2, "_ERROR_POP_N"); max_length--; } + if (opcode == FOR_ITER_RANGE || opcode == FOR_ITER_LIST || opcode == FOR_ITER_TUPLE) { + preceded_by_for_iter = true; + // assert((initial_instr + x + 1 + _PyOpcode_Caches[FOR_ITER])->op.code == TIER1_GUARD_IP); + // assert((initial_instr + x + 6 + _PyOpcode_Caches[FOR_ITER])->op.code == TIER1_SET_IP); + // PyObject *temp = read_obj(&(initial_instr + x + 2 + _PyOpcode_Caches[FOR_ITER])->cache); + // if (temp != NULL) { + // code = ((PyFunctionObject*)temp)->func_code; + // } + // target_instr = (_Py_CODEUNIT *)(read_obj(&(initial_instr + x + 7 + _PyOpcode_Caches[FOR_ITER])->cache)); + // target = INSTR_IP(target_instr, code); + // + // (initial_instr + x + 1 + _PyOpcode_Caches[FOR_ITER])->op.code = NOP; + // (initial_instr + x + 2 + _PyOpcode_Caches[FOR_ITER])->op.code = NOP; + // (initial_instr + x + 3 + _PyOpcode_Caches[FOR_ITER])->op.code = NOP; + // (initial_instr + x + 4 + _PyOpcode_Caches[FOR_ITER])->op.code = NOP; + // (initial_instr + x + 5 + _PyOpcode_Caches[FOR_ITER])->op.code = NOP; + // + // (initial_instr + x + 6 + _PyOpcode_Caches[FOR_ITER])->op.code = NOP; + // (initial_instr + x + 7 + _PyOpcode_Caches[FOR_ITER])->op.code = NOP; + // (initial_instr + x + 8 + _PyOpcode_Caches[FOR_ITER])->op.code = NOP; + // (initial_instr + x + 9 + _PyOpcode_Caches[FOR_ITER])->op.code = NOP; + // (initial_instr + x + 10 + _PyOpcode_Caches[FOR_ITER])->op.code = NOP; + } switch (opcode) { - case POP_JUMP_IF_NONE: - case POP_JUMP_IF_NOT_NONE: - case POP_JUMP_IF_FALSE: - case POP_JUMP_IF_TRUE: - { - RESERVE(1); - int counter = instr[1].cache; - int bitcount = _Py_popcount32(counter); - int jump_likely = bitcount > 8; - /* If bitcount is 8 (half the jumps were taken), adjust confidence by 50%. - For values in between, adjust proportionally. */ - if (jump_likely) { - confidence = confidence * bitcount / 16; - } - else { - confidence = confidence * (16 - bitcount) / 16; - } - uint32_t uopcode = BRANCH_TO_GUARD[opcode - POP_JUMP_IF_FALSE][jump_likely]; - DPRINTF(2, "%d: %s(%d): counter=%04x, bitcount=%d, likely=%d, confidence=%d, uopcode=%s\n", - target, _PyOpcode_OpName[opcode], oparg, - counter, bitcount, jump_likely, confidence, _PyUOpName(uopcode)); - if (confidence < CONFIDENCE_CUTOFF) { - DPRINTF(2, "Confidence too low (%d < %d)\n", confidence, CONFIDENCE_CUTOFF); - OPT_STAT_INC(low_confidence); - goto done; - } - _Py_CODEUNIT *next_instr = instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]]; - _Py_CODEUNIT *target_instr = next_instr + oparg; - if (jump_likely) { - DPRINTF(2, "Jump likely (%04x = %d bits), continue at byte offset %d\n", - instr[1].cache, bitcount, 2 * INSTR_IP(target_instr, code)); - instr = target_instr; - ADD_TO_TRACE(uopcode, 0, 0, INSTR_IP(next_instr, code)); - goto top; - } - ADD_TO_TRACE(uopcode, 0, 0, INSTR_IP(target_instr, code)); - break; - } - - case JUMP_BACKWARD: case JUMP_BACKWARD_JIT: + case JUMP_BACKWARD: ADD_TO_TRACE(_CHECK_PERIODIC, 0, 0, target); _Py_FALLTHROUGH; case JUMP_BACKWARD_NO_INTERRUPT: - { - instr += 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]] - (int)oparg; - if (jump_seen) { - OPT_STAT_INC(inner_loop); - DPRINTF(2, "JUMP_BACKWARD not to top ends trace\n"); - goto done; + ADD_TO_TRACE(_JUMP_BACKWARD_NO_INTERRUPT, oparg, 0, target); + break; + case TIER1_GUARD_IP: + func = (PyFunctionObject *)read_obj(&(initial_instr + x + 1)->cache); + assert(func == NULL || PyFunction_Check(func)); + if (func != NULL) { + code = (PyCodeObject *)func->func_code; } - jump_seen = true; - goto top; - } + assert((initial_instr + x + 5)->op.code == TIER1_SET_IP); + target_instr = (_Py_CODEUNIT*)read_obj(&(initial_instr + x + 6)->cache); + if (preceded_by_for_iter) {; + preceded_by_for_iter = false; + } + else { + ADD_TO_TRACE(_GUARD_IP, 0, (uintptr_t)target_instr, 0) + } + break; - case JUMP_FORWARD: - { - RESERVE(0); - // This will emit two _SET_IP instructions; leave it to the optimizer - instr += oparg; + case TIER1_SET_IP: + target_instr = (_Py_CODEUNIT*)read_obj(&(initial_instr + x + 1)->cache); break; - } case RESUME: /* Use a special tier 2 version of RESUME_CHECK to allow traces to @@ -740,17 +677,6 @@ translate_bytecode_to_trace( // Reserve space for nuops (+ _SET_IP + _EXIT_TRACE) int nuops = expansion->nuops; RESERVE(nuops + 1); /* One extra for exit */ - int16_t last_op = expansion->uops[nuops-1].uop; - if (last_op == _RETURN_VALUE || last_op == _RETURN_GENERATOR || last_op == _YIELD_VALUE) { - // Check for trace stack underflow now: - // We can't bail e.g. in the middle of - // LOAD_CONST + _RETURN_VALUE. - if (trace_stack_depth == 0) { - DPRINTF(2, "Trace stack underflow\n"); - OPT_STAT_INC(trace_stack_underflow); - return 0; - } - } uint32_t orig_oparg = oparg; // For OPARG_TOP/BOTTOM for (int i = 0; i < nuops; i++) { oparg = orig_oparg; @@ -760,16 +686,16 @@ translate_bytecode_to_trace( int offset = expansion->uops[i].offset + 1; switch (expansion->uops[i].size) { case OPARG_SIMPLE: - assert(opcode != JUMP_BACKWARD_NO_INTERRUPT && opcode != JUMP_BACKWARD); + assert(opcode != _JUMP_BACKWARD_NO_INTERRUPT && opcode != JUMP_BACKWARD); break; case OPARG_CACHE_1: - operand = read_u16(&instr[offset].cache); + operand = read_u16(&(initial_instr + x)[offset].cache); break; case OPARG_CACHE_2: - operand = read_u32(&instr[offset].cache); + operand = read_u32(&(initial_instr + x)[offset].cache); break; case OPARG_CACHE_4: - operand = read_u64(&instr[offset].cache); + operand = read_u64(&(initial_instr + x)[offset].cache); break; case OPARG_TOP: // First half of super-instr oparg = orig_oparg >> 4; @@ -784,6 +710,7 @@ translate_bytecode_to_trace( case OPARG_REPLACED: uop = _PyUOp_Replacements[uop]; assert(uop != 0); + uint32_t next_inst = target + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]] + (oparg > 255); if (uop == _TIER2_RESUME_CHECK) { target = next_inst; @@ -798,17 +725,17 @@ translate_bytecode_to_trace( break; case OPERAND1_1: assert(trace[trace_length-1].opcode == uop); - operand = read_u16(&instr[offset].cache); + operand = read_u16(&(initial_instr + x)[offset].cache); trace[trace_length-1].operand1 = operand; continue; case OPERAND1_2: assert(trace[trace_length-1].opcode == uop); - operand = read_u32(&instr[offset].cache); + operand = read_u32(&(initial_instr + x)[offset].cache); trace[trace_length-1].operand1 = operand; continue; case OPERAND1_4: assert(trace[trace_length-1].opcode == uop); - operand = read_u64(&instr[offset].cache); + operand = read_u64(&(initial_instr + x)[offset].cache); trace[trace_length-1].operand1 = operand; continue; default: @@ -820,116 +747,13 @@ translate_bytecode_to_trace( Py_FatalError("garbled expansion"); } - if (uop == _RETURN_VALUE || uop == _RETURN_GENERATOR || uop == _YIELD_VALUE) { - TRACE_STACK_POP(); - /* Set the operand to the function or code object returned to, - * to assist optimization passes. (See _PUSH_FRAME below.) - */ - if (func != NULL) { - operand = (uintptr_t)func; - } - else if (code != NULL) { - operand = (uintptr_t)code | 1; - } - else { - operand = 0; - } - ADD_TO_TRACE(uop, oparg, operand, target); - DPRINTF(2, - "Returning to %s (%s:%d) at byte offset %d\n", - PyUnicode_AsUTF8(code->co_qualname), - PyUnicode_AsUTF8(code->co_filename), - code->co_firstlineno, - 2 * INSTR_IP(instr, code)); - goto top; - } - - if (uop == _PUSH_FRAME) { - assert(i + 1 == nuops); - if (opcode == FOR_ITER_GEN || - opcode == LOAD_ATTR_PROPERTY || - opcode == BINARY_OP_SUBSCR_GETITEM || - opcode == SEND_GEN) - { - DPRINTF(2, "Bailing due to dynamic target\n"); - OPT_STAT_INC(unknown_callee); - return 0; - } - assert(_PyOpcode_Deopt[opcode] == CALL || _PyOpcode_Deopt[opcode] == CALL_KW); - int func_version_offset = - offsetof(_PyCallCache, func_version)/sizeof(_Py_CODEUNIT) - // Add one to account for the actual opcode/oparg pair: - + 1; - uint32_t func_version = read_u32(&instr[func_version_offset].cache); - PyCodeObject *new_code = NULL; - PyFunctionObject *new_func = - _PyFunction_LookupByVersion(func_version, (PyObject **) &new_code); - DPRINTF(2, "Function: version=%#x; new_func=%p, new_code=%p\n", - (int)func_version, new_func, new_code); - if (new_code != NULL) { - if (new_code == code) { - // Recursive call, bail (we could be here forever). - DPRINTF(2, "Bailing on recursive call to %s (%s:%d)\n", - PyUnicode_AsUTF8(new_code->co_qualname), - PyUnicode_AsUTF8(new_code->co_filename), - new_code->co_firstlineno); - OPT_STAT_INC(recursive_call); - ADD_TO_TRACE(uop, oparg, 0, target); - ADD_TO_TRACE(_EXIT_TRACE, 0, 0, 0); - goto done; - } - if (new_code->co_version != func_version) { - // func.__code__ was updated. - // Perhaps it may happen again, so don't bother tracing. - // TODO: Reason about this -- is it better to bail or not? - DPRINTF(2, "Bailing because co_version != func_version\n"); - ADD_TO_TRACE(uop, oparg, 0, target); - ADD_TO_TRACE(_EXIT_TRACE, 0, 0, 0); - goto done; - } - // Increment IP to the return address - instr += _PyOpcode_Caches[_PyOpcode_Deopt[opcode]] + 1; - TRACE_STACK_PUSH(); - _Py_BloomFilter_Add(dependencies, new_code); - /* Set the operand to the callee's function or code object, - * to assist optimization passes. - * We prefer setting it to the function - * but if that's not available but the code is available, - * use the code, setting the low bit so the optimizer knows. - */ - if (new_func != NULL) { - operand = (uintptr_t)new_func; - } - else if (new_code != NULL) { - operand = (uintptr_t)new_code | 1; - } - else { - operand = 0; - } - ADD_TO_TRACE(uop, oparg, operand, target); - code = new_code; - func = new_func; - instr = _PyCode_CODE(code); - DPRINTF(2, - "Continuing in %s (%s:%d) at byte offset %d\n", - PyUnicode_AsUTF8(code->co_qualname), - PyUnicode_AsUTF8(code->co_filename), - code->co_firstlineno, - 2 * INSTR_IP(instr, code)); - goto top; - } - DPRINTF(2, "Bail, new_code == NULL\n"); - OPT_STAT_INC(unknown_callee); - return 0; - } - if (uop == _BINARY_OP_INPLACE_ADD_UNICODE) { assert(i + 1 == nuops); - _Py_CODEUNIT *next_instr = instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]]; + _Py_CODEUNIT *next_instr = target_instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]]; assert(next_instr->op.code == STORE_FAST); operand = next_instr->op.arg; // Skip the STORE_FAST: - instr++; + x++; } // All other instructions @@ -944,24 +768,27 @@ translate_bytecode_to_trace( } // End switch (opcode) - instr++; + x++; // Add cache size for opcode - instr += _PyOpcode_Caches[_PyOpcode_Deopt[opcode]]; + x += _PyOpcode_Caches[_PyOpcode_Deopt[opcode]]; if (opcode == CALL_LIST_APPEND) { - assert(instr->op.code == POP_TOP); - instr++; + assert(initial_instr[x].op.code == POP_TOP); + x++; + } + + if (x > tstate->interp->jit_tracer_code_curr_size) { + goto done; } - top: // Jump here after _PUSH_FRAME or likely branches. first = false; } // End for (;;) done: - while (trace_stack_depth > 0) { - TRACE_STACK_POP(); + // Looped back to top. + if (!first && tstate->interp->jit_completed_loop && target_instr == tstate->interp->jit_tracer_initial_instr) { + ADD_TO_TRACE(_JUMP_TO_TOP, 0, 0, 0); } - assert(code == initial_code); // Skip short traces where we can't even translate a single instruction: if (first) { OPT_STAT_INC(trace_too_short); @@ -983,7 +810,7 @@ done: PyUnicode_AsUTF8(code->co_qualname), PyUnicode_AsUTF8(code->co_filename), code->co_firstlineno, - 2 * INSTR_IP(initial_instr, code), + 2 * INSTR_IP(tstate->interp->jit_tracer_initial_instr, (PyCodeObject *)tstate->interp->jit_tracer_initial_func->func_code), trace_length); OPT_HIST(trace_length, trace_length_hist); return trace_length; @@ -1063,6 +890,9 @@ prepare_for_execution(_PyUOpInstruction *buffer, int length) else if (exit_flags & HAS_PERIODIC_FLAG) { exit_op = _HANDLE_PENDING_AND_DEOPT; } + if (opcode == _FOR_ITER_TIER_TWO) { + exit_op = _DYNAMIC_EXIT; + } int32_t jump_target = target; if (is_for_iter_test[opcode]) { /* Target the POP_TOP immediately after the END_FOR, @@ -1178,7 +1008,8 @@ sanity_check(_PyExecutorObject *executor) opcode == _DEOPT || opcode == _HANDLE_PENDING_AND_DEOPT || opcode == _EXIT_TRACE || - opcode == _ERROR_POP_N); + opcode == _ERROR_POP_N || + opcode == _DYNAMIC_EXIT); } } @@ -1214,7 +1045,6 @@ make_executor_from_uops(_PyUOpInstruction *buffer, int length, const _PyBloomFil int opcode = buffer[i].opcode; dest--; *dest = buffer[i]; - assert(opcode != _POP_JUMP_IF_FALSE && opcode != _POP_JUMP_IF_TRUE); if (opcode == _EXIT_TRACE) { _PyExitData *exit = &executor->exits[next_exit]; exit->target = buffer[i].target; @@ -1280,9 +1110,8 @@ int effective_trace_length(_PyUOpInstruction *buffer, int length) static int uop_optimize( _PyInterpreterFrame *frame, - _Py_CODEUNIT *instr, + PyThreadState *tstate, _PyExecutorObject **exec_ptr, - int curr_stackentries, bool progress_needed) { _PyBloomFilter dependencies; @@ -1301,7 +1130,16 @@ uop_optimize( if (env_var == NULL || *env_var == '\0' || *env_var > '0') { is_noopt = false; } - int length = translate_bytecode_to_trace(frame, instr, buffer, UOP_MAX_TRACE_LENGTH, &dependencies, progress_needed); + int curr_stackentries = tstate->interp->jit_tracer_initial_stack_depth; +// #ifdef Py_DEBUG +// for (int x = 0; x < tstate->interp->jit_tracer_code_curr_size;) { +// int opcode = tstate->interp->jit_tracer_code_buffer[x].op.code; +// int oparg = tstate->interp->jit_tracer_code_buffer[x].op.arg; +// fprintf(stdout, "%s(%d)\n", _PyOpcode_OpName[opcode], oparg); +// x += 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]]; +// } +// #endif + int length = translate_bytecode_to_trace(frame, tstate, buffer, UOP_MAX_TRACE_LENGTH, &dependencies, progress_needed); if (length <= 0) { // Error or nothing translated return length; @@ -1778,7 +1616,7 @@ executor_to_gv(_PyExecutorObject *executor, FILE *out) else if (flags & HAS_EXIT_FLAG) { assert(inst->format == UOP_FORMAT_JUMP); _PyUOpInstruction const *exit_inst = &executor->trace[inst->jump_target]; - assert(exit_inst->opcode == _EXIT_TRACE); + assert(exit_inst->opcode == _EXIT_TRACE || exit_inst->opcode == _DYNAMIC_EXIT); exit = (_PyExitData *)exit_inst->operand0; } if (exit != NULL && exit->executor != NULL) { diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index a6add301ccb2..21410f1016ad 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -527,13 +527,13 @@ _Py_uop_analyze_and_optimize( { OPT_STAT_INC(optimizer_attempts); - length = optimize_uops( - _PyFrame_GetFunction(frame), buffer, - length, curr_stacklen, dependencies); - - if (length == 0) { - return length; - } + // length = optimize_uops( + // _PyFrame_GetFunction(frame), buffer, + // length, curr_stacklen, dependencies); + // + // if (length == 0) { + // return length; + // } assert(length > 0); diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index b08099d8e2fc..1240be061b78 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -2092,9 +2092,17 @@ break; } - /* _POP_JUMP_IF_FALSE is not a viable micro-op for tier 2 */ + case _POP_JUMP_IF_FALSE: { + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); + break; + } - /* _POP_JUMP_IF_TRUE is not a viable micro-op for tier 2 */ + case _POP_JUMP_IF_TRUE: { + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); + break; + } case _IS_NONE: { JitOptRef b; @@ -2103,6 +2111,10 @@ break; } + case _JUMP_BACKWARD_NO_INTERRUPT: { + break; + } + case _GET_LEN: { JitOptRef obj; JitOptRef len; @@ -2219,7 +2231,14 @@ break; } - /* _ITER_NEXT_LIST is not a viable micro-op for tier 2 */ + case _ITER_NEXT_LIST: { + JitOptRef next; + next = sym_new_not_null(ctx); + stack_pointer[0] = next; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } case _ITER_NEXT_LIST_TIER_TWO: { JitOptRef next; @@ -3418,3 +3437,11 @@ break; } + case _GUARD_IP: { + break; + } + + case _DYNAMIC_EXIT: { + break; + } + diff --git a/Python/pystate.c b/Python/pystate.c index 9fe946023741..33ffc034b441 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -557,6 +557,10 @@ init_interpreter(PyInterpreterState *interp, interp->jit_uop_buffer = NULL; interp->jit_tracer_code_buffer = NULL; interp->jit_tracer_initial_instr = NULL; + interp->jit_tracer_initial_stack_depth = -1; + interp->jit_tracer_initial_chain_depth = -1; + interp->jit_tracer_initial_code = NULL; + interp->jit_tracer_initial_func = NULL; #endif llist_init(&interp->mem_free_queue.head); llist_init(&interp->asyncio_tasks_head); diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index 9dd7e5dbfbae..75bff34aa742 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -34,6 +34,7 @@ class Properties: side_exit: bool pure: bool uses_opcode: bool + needs_guard_ip: bool tier: int | None = None const_oparg: int = -1 needs_prev: bool = False @@ -75,6 +76,7 @@ class Properties: pure=all(p.pure for p in properties), needs_prev=any(p.needs_prev for p in properties), no_save_ip=all(p.no_save_ip for p in properties), + needs_guard_ip=any(p.needs_guard_ip for p in properties) ) @property @@ -102,6 +104,7 @@ SKIP_PROPERTIES = Properties( side_exit=False, pure=True, no_save_ip=False, + needs_guard_ip=False, ) @@ -932,6 +935,7 @@ def compute_properties(op: parser.CodeDef) -> Properties: no_save_ip=no_save_ip, tier=tier_variable(op), needs_prev=variable_used(op, "prev_instr"), + needs_guard_ip=variable_used(op, "JUMPBY") or variable_used(op, "LLTRACE_RESUME_FRAME"), ) def expand(items: list[StackItem], oparg: int) -> list[StackItem]: diff --git a/Tools/cases_generator/opcode_metadata_generator.py b/Tools/cases_generator/opcode_metadata_generator.py index b649b3812338..d17a2431c75b 100644 --- a/Tools/cases_generator/opcode_metadata_generator.py +++ b/Tools/cases_generator/opcode_metadata_generator.py @@ -184,6 +184,16 @@ def generate_cache_table(analysis: Analysis, out: CWriter) -> None: out.emit("#endif\n\n") +def generate_needs_guard_ip_table(analysis: Analysis, out: CWriter) -> None: + out.emit("extern const uint8_t _PyOpcode_NeedsGuardIp[256];\n") + out.emit("#ifdef NEED_OPCODE_METADATA\n") + out.emit("const uint8_t _PyOpcode_NeedsGuardIp[256] = {\n") + for inst in analysis.instructions.values(): + if inst.properties.needs_guard_ip: + out.emit(f"[{inst.name}] = 1,\n") + out.emit("};\n") + out.emit("#endif\n\n") + def generate_name_table(analysis: Analysis, out: CWriter) -> None: table_size = 256 + len(analysis.pseudos) out.emit(f"extern const char *_PyOpcode_OpName[{table_size}];\n") @@ -382,6 +392,7 @@ def generate_opcode_metadata( generate_expansion_table(analysis, out) generate_name_table(analysis, out) generate_cache_table(analysis, out) + generate_needs_guard_ip_table(analysis, out) generate_deopt_table(analysis, out) generate_extra_cases(analysis, out) generate_pseudo_targets(analysis, out) diff --git a/Tools/cases_generator/tier2_generator.py b/Tools/cases_generator/tier2_generator.py index 1bb5f48658dd..35a10e7bebed 100644 --- a/Tools/cases_generator/tier2_generator.py +++ b/Tools/cases_generator/tier2_generator.py @@ -63,6 +63,8 @@ class Tier2Emitter(Emitter): def __init__(self, out: CWriter, labels: dict[str, Label]): super().__init__(out, labels) self._replacers["oparg"] = self.oparg + self._replacers["JUMPBY"] = self.jumpby + self._replacers["DISPATCH"] = self.dispatch def goto_error(self, offset: int, storage: Storage) -> str: # To do: Add jump targets for popping values. @@ -134,6 +136,38 @@ class Tier2Emitter(Emitter): self.out.emit_at(uop.name[-1], tkn) return True + def jumpby( + self, + tkn: Token, + tkn_iter: TokenIterator, + uop: CodeSection, + storage: Storage, + inst: Instruction | None, + ) -> bool: + if storage.spilled: + raise analysis_error("stack_pointer needs reloading before dispatch", tkn) + storage.stack.flush(self.out) + self.emit("TIER2_JUMPBY") + emit_to(self.out, tkn_iter, "SEMI") + self.emit(";\n") + return True + + def dispatch( + self, + tkn: Token, + tkn_iter: TokenIterator, + uop: CodeSection, + storage: Storage, + inst: Instruction | None, + ) -> bool: + if storage.spilled: + raise analysis_error("stack_pointer needs reloading before dispatch", tkn) + storage.stack.flush(self.out) + self.emit("break;\n") + next(tkn_iter) + next(tkn_iter) + next(tkn_iter) + return False def write_uop(uop: Uop, emitter: Emitter, stack: Stack) -> Stack: locals: dict[str, Local] = {} @@ -192,6 +226,16 @@ def generate_tier2( ) continue out.emit(f"case {uop.name}: {{\n") + if uop.properties.jumps: + containing_inst = None + for inst in analysis.instructions.values(): + if uop in inst.parts: + print(uop.name, inst.name) + containing_inst = inst + break + assert containing_inst is not None, uop.name + size = containing_inst.size + out.emit(f"TIER2_JUMPBY({size});\n") declare_variables(uop, out) stack = Stack() stack = write_uop(uop, emitter, stack) diff --git a/Tools/cases_generator/tracer_generator.py b/Tools/cases_generator/tracer_generator.py index 0df435a9e327..e394807518f6 100644 --- a/Tools/cases_generator/tracer_generator.py +++ b/Tools/cases_generator/tracer_generator.py @@ -53,6 +53,7 @@ class TracerEmitter(Emitter): if storage.spilled: raise analysis_error("stack_pointer needs reloading before dispatch", tkn) storage.stack.flush(self.out) + self.out.start_line() self.emit("TRACING_DISPATCH") return False diff --git a/out.txt b/out.txt new file mode 100644 index 000000000000..225b73b0f387 --- /dev/null +++ b/out.txt @@ -0,0 +1,1089 @@ +0 ADD_TO_BYTECODE_TRACE: FOR_ITER_GEN 3 +2 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +7 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5565a +12 ADD_TO_BYTECODE_TRACE: RESUME_CHECK 2 +13 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5565c +18 ADD_TO_BYTECODE_TRACE: JUMP_BACKWARD_NO_INTERRUPT 5 +19 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +24 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55654 +29 ADD_TO_BYTECODE_TRACE: SEND_GEN 3 +31 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +36 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5565a +41 ADD_TO_BYTECODE_TRACE: RESUME_CHECK 2 +42 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5565c +47 ADD_TO_BYTECODE_TRACE: JUMP_BACKWARD_NO_INTERRUPT 5 +48 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +53 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55654 +58 ADD_TO_BYTECODE_TRACE: SEND_GEN 3 +60 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +65 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5565a +70 ADD_TO_BYTECODE_TRACE: RESUME_CHECK 2 +71 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5565c +76 ADD_TO_BYTECODE_TRACE: JUMP_BACKWARD_NO_INTERRUPT 5 +77 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +82 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55654 +87 ADD_TO_BYTECODE_TRACE: SEND_GEN 3 +89 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +94 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5565a +99 ADD_TO_BYTECODE_TRACE: RESUME_CHECK 2 +100 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5565c +105 ADD_TO_BYTECODE_TRACE: JUMP_BACKWARD_NO_INTERRUPT 5 +106 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +111 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55654 +116 ADD_TO_BYTECODE_TRACE: SEND_GEN 3 +118 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +123 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c2 +128 ADD_TO_BYTECODE_TRACE: RESUME_CHECK 2 +129 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c4 +134 ADD_TO_BYTECODE_TRACE: JUMP_BACKWARD_NO_INTERRUPT 5 +135 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +140 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556bc +145 ADD_TO_BYTECODE_TRACE: SEND_GEN 3 +147 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +152 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5565a +157 ADD_TO_BYTECODE_TRACE: RESUME_CHECK 2 +158 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5565c +163 ADD_TO_BYTECODE_TRACE: JUMP_BACKWARD_NO_INTERRUPT 5 +164 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +169 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55654 +174 ADD_TO_BYTECODE_TRACE: SEND_GEN 3 +176 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +181 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c2 +186 ADD_TO_BYTECODE_TRACE: RESUME_CHECK 2 +187 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c4 +192 ADD_TO_BYTECODE_TRACE: JUMP_BACKWARD_NO_INTERRUPT 5 +193 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +198 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556bc +203 ADD_TO_BYTECODE_TRACE: SEND_GEN 3 +205 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +210 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5565a +215 ADD_TO_BYTECODE_TRACE: RESUME_CHECK 2 +216 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5565c +221 ADD_TO_BYTECODE_TRACE: JUMP_BACKWARD_NO_INTERRUPT 5 +222 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +227 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55654 +232 ADD_TO_BYTECODE_TRACE: SEND_GEN 3 +234 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +239 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5565a +244 ADD_TO_BYTECODE_TRACE: RESUME_CHECK 2 +245 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5565c +250 ADD_TO_BYTECODE_TRACE: JUMP_BACKWARD_NO_INTERRUPT 5 +251 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +256 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55654 +261 ADD_TO_BYTECODE_TRACE: SEND_GEN 3 +263 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +268 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c2 +273 ADD_TO_BYTECODE_TRACE: RESUME_CHECK 2 +274 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c4 +279 ADD_TO_BYTECODE_TRACE: JUMP_BACKWARD_NO_INTERRUPT 5 +280 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +285 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556bc +290 ADD_TO_BYTECODE_TRACE: SEND_GEN 3 +292 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +297 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c2 +302 ADD_TO_BYTECODE_TRACE: RESUME_CHECK 2 +303 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c4 +308 ADD_TO_BYTECODE_TRACE: JUMP_BACKWARD_NO_INTERRUPT 5 +309 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +314 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556bc +319 ADD_TO_BYTECODE_TRACE: SEND_GEN 3 +321 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +326 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c2 +331 ADD_TO_BYTECODE_TRACE: RESUME_CHECK 2 +332 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c4 +337 ADD_TO_BYTECODE_TRACE: JUMP_BACKWARD_NO_INTERRUPT 5 +338 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +343 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556bc +348 ADD_TO_BYTECODE_TRACE: SEND_GEN 3 +350 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +355 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c2 +360 ADD_TO_BYTECODE_TRACE: RESUME_CHECK 2 +361 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c4 +366 ADD_TO_BYTECODE_TRACE: JUMP_BACKWARD_NO_INTERRUPT 5 +367 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +372 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556bc +377 ADD_TO_BYTECODE_TRACE: SEND_GEN 3 +379 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +384 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5565a +389 ADD_TO_BYTECODE_TRACE: RESUME_CHECK 2 +390 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5565c +395 ADD_TO_BYTECODE_TRACE: JUMP_BACKWARD_NO_INTERRUPT 5 +396 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +401 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55654 +406 ADD_TO_BYTECODE_TRACE: SEND_GEN 3 +408 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +413 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c2 +418 ADD_TO_BYTECODE_TRACE: RESUME_CHECK 2 +419 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c4 +424 ADD_TO_BYTECODE_TRACE: JUMP_BACKWARD_NO_INTERRUPT 5 +425 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +430 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556bc +435 ADD_TO_BYTECODE_TRACE: SEND_GEN 3 +437 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +442 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5565a +447 ADD_TO_BYTECODE_TRACE: RESUME_CHECK 2 +448 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5565c +453 ADD_TO_BYTECODE_TRACE: JUMP_BACKWARD_NO_INTERRUPT 5 +454 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +459 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55654 +464 ADD_TO_BYTECODE_TRACE: SEND_GEN 3 +466 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +471 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5567a +476 ADD_TO_BYTECODE_TRACE: RESUME_CHECK 5 +477 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5567c +482 ADD_TO_BYTECODE_TRACE: POP_TOP 0 +483 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5567e +488 ADD_TO_BYTECODE_TRACE: LOAD_FAST_BORROW 0 +489 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55680 +494 ADD_TO_BYTECODE_TRACE: LOAD_ATTR_INSTANCE_VALUE 4 +504 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55694 +509 ADD_TO_BYTECODE_TRACE: TO_BOOL_NONE 0 +513 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5569c +518 ADD_TO_BYTECODE_TRACE: POP_JUMP_IF_FALSE 23 +520 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +525 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556ce +530 ADD_TO_BYTECODE_TRACE: LOAD_CONST 0 +531 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556d0 +536 ADD_TO_BYTECODE_TRACE: RETURN_VALUE 0 +537 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +542 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5565e +547 ADD_TO_BYTECODE_TRACE: END_SEND 0 +548 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55660 +553 ADD_TO_BYTECODE_TRACE: POP_TOP 0 +554 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55662 +559 ADD_TO_BYTECODE_TRACE: LOAD_FAST_BORROW 0 +560 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55664 +565 ADD_TO_BYTECODE_TRACE: LOAD_ATTR_INSTANCE_VALUE 2 +575 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55678 +580 ADD_TO_BYTECODE_TRACE: YIELD_VALUE 0 +581 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +586 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c0 +591 ADD_TO_BYTECODE_TRACE: YIELD_VALUE 1 +592 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +597 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55658 +602 ADD_TO_BYTECODE_TRACE: YIELD_VALUE 1 +603 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +608 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c0 +613 ADD_TO_BYTECODE_TRACE: YIELD_VALUE 1 +614 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +619 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c0 +624 ADD_TO_BYTECODE_TRACE: YIELD_VALUE 1 +625 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +630 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c0 +635 ADD_TO_BYTECODE_TRACE: YIELD_VALUE 1 +636 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +641 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c0 +646 ADD_TO_BYTECODE_TRACE: YIELD_VALUE 1 +647 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +652 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55658 +657 ADD_TO_BYTECODE_TRACE: YIELD_VALUE 1 +658 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +663 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55658 +668 ADD_TO_BYTECODE_TRACE: YIELD_VALUE 1 +669 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +674 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c0 +679 ADD_TO_BYTECODE_TRACE: YIELD_VALUE 1 +680 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +685 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55658 +690 ADD_TO_BYTECODE_TRACE: YIELD_VALUE 1 +691 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +696 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db556c0 +701 ADD_TO_BYTECODE_TRACE: YIELD_VALUE 1 +702 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +707 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55658 +712 ADD_TO_BYTECODE_TRACE: YIELD_VALUE 1 +713 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +718 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55658 +723 ADD_TO_BYTECODE_TRACE: YIELD_VALUE 1 +724 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +729 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55658 +734 ADD_TO_BYTECODE_TRACE: YIELD_VALUE 1 +735 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +740 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db55658 +745 ADD_TO_BYTECODE_TRACE: YIELD_VALUE 1 +746 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +751 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5630e +756 ADD_TO_BYTECODE_TRACE: STORE_FAST 3 +757 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db56310 +762 ADD_TO_BYTECODE_TRACE: JUMP_BACKWARD_JIT 5 +764 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +769 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5630a +FOR_ITER_GEN(3) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +RESUME_CHECK(2) +TIER1_SET_IP(0) +JUMP_BACKWARD_NO_INTERRUPT(5) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +SEND_GEN(3) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +RESUME_CHECK(2) +TIER1_SET_IP(0) +JUMP_BACKWARD_NO_INTERRUPT(5) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +SEND_GEN(3) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +RESUME_CHECK(2) +TIER1_SET_IP(0) +JUMP_BACKWARD_NO_INTERRUPT(5) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +SEND_GEN(3) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +RESUME_CHECK(2) +TIER1_SET_IP(0) +JUMP_BACKWARD_NO_INTERRUPT(5) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +SEND_GEN(3) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +RESUME_CHECK(2) +TIER1_SET_IP(0) +JUMP_BACKWARD_NO_INTERRUPT(5) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +SEND_GEN(3) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +RESUME_CHECK(2) +TIER1_SET_IP(0) +JUMP_BACKWARD_NO_INTERRUPT(5) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +SEND_GEN(3) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +RESUME_CHECK(2) +TIER1_SET_IP(0) +JUMP_BACKWARD_NO_INTERRUPT(5) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +SEND_GEN(3) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +RESUME_CHECK(2) +TIER1_SET_IP(0) +JUMP_BACKWARD_NO_INTERRUPT(5) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +SEND_GEN(3) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +RESUME_CHECK(2) +TIER1_SET_IP(0) +JUMP_BACKWARD_NO_INTERRUPT(5) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +SEND_GEN(3) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +RESUME_CHECK(2) +TIER1_SET_IP(0) +JUMP_BACKWARD_NO_INTERRUPT(5) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +SEND_GEN(3) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +RESUME_CHECK(2) +TIER1_SET_IP(0) +JUMP_BACKWARD_NO_INTERRUPT(5) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +SEND_GEN(3) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +RESUME_CHECK(2) +TIER1_SET_IP(0) +JUMP_BACKWARD_NO_INTERRUPT(5) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +SEND_GEN(3) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +RESUME_CHECK(2) +TIER1_SET_IP(0) +JUMP_BACKWARD_NO_INTERRUPT(5) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +SEND_GEN(3) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +RESUME_CHECK(2) +TIER1_SET_IP(0) +JUMP_BACKWARD_NO_INTERRUPT(5) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +SEND_GEN(3) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +RESUME_CHECK(2) +TIER1_SET_IP(0) +JUMP_BACKWARD_NO_INTERRUPT(5) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +SEND_GEN(3) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +RESUME_CHECK(2) +TIER1_SET_IP(0) +JUMP_BACKWARD_NO_INTERRUPT(5) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +SEND_GEN(3) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +RESUME_CHECK(5) +TIER1_SET_IP(0) +POP_TOP(0) +TIER1_SET_IP(0) +LOAD_FAST_BORROW(0) +TIER1_SET_IP(0) +LOAD_ATTR_INSTANCE_VALUE(4) +TIER1_SET_IP(0) +TO_BOOL_NONE(0) +TIER1_SET_IP(0) +POP_JUMP_IF_FALSE(23) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +LOAD_CONST(0) +TIER1_SET_IP(0) +RETURN_VALUE(0) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +END_SEND(0) +TIER1_SET_IP(0) +POP_TOP(0) +TIER1_SET_IP(0) +LOAD_FAST_BORROW(0) +TIER1_SET_IP(0) +LOAD_ATTR_INSTANCE_VALUE(2) +TIER1_SET_IP(0) +YIELD_VALUE(0) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +YIELD_VALUE(1) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +YIELD_VALUE(1) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +YIELD_VALUE(1) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +YIELD_VALUE(1) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +YIELD_VALUE(1) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +YIELD_VALUE(1) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +YIELD_VALUE(1) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +YIELD_VALUE(1) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +YIELD_VALUE(1) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +YIELD_VALUE(1) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +YIELD_VALUE(1) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +YIELD_VALUE(1) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +YIELD_VALUE(1) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +YIELD_VALUE(1) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +YIELD_VALUE(1) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +STORE_FAST(3) +TIER1_SET_IP(0) +JUMP_BACKWARD_JIT(5) +TIER1_GUARD_IP(0) +TIER1_SET_IP(0) +Optimizing bench_generators (/home/ken/Documents/GitHub/cpython/../bm_generators.py:36) at byte offset 186 + 1 ADD_TO_TRACE: _START_EXECUTOR (0, target=93, operand0=0x71448db5630a, operand1=0) + 2 ADD_TO_TRACE: _MAKE_WARM (0, target=0, operand0=0, operand1=0) +93: FOR_ITER_GEN(3) + 3 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=93, operand0=0, operand1=0) + 4 ADD_TO_TRACE: _SET_IP (0, target=93, operand0=0x71448db5630a, operand1=0) + 5 ADD_TO_TRACE: _FOR_ITER (3, target=93, operand0=0, operand1=0, error_target=0) +93: TIER1_GUARD_IP(0) + 6 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=93, operand0=0, operand1=0) + 7 ADD_TO_TRACE: _GUARD_IP (0, target=37, operand0=0x71448db5565a, operand1=0) +37: RESUME_CHECK(2) + 8 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=37, operand0=0, operand1=0) + 9 ADD_TO_TRACE: _SET_IP (0, target=37, operand0=0x71448db5565a, operand1=0) + 10 ADD_TO_TRACE: _RESUME_CHECK (2, target=37, operand0=0, operand1=0) +37: TIER1_SET_IP(0) + 11 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=37, operand0=0, operand1=0) + 12 ADD_TO_TRACE: _SET_IP (0, target=37, operand0=0x71448db5565a, operand1=0) +38: JUMP_BACKWARD_NO_INTERRUPT(5) + 13 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=38, operand0=0, operand1=0) + 14 ADD_TO_TRACE: _SET_IP (0, target=38, operand0=0x71448db5565c, operand1=0) + 15 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=38, operand0=0, operand1=0, error_target=0) +38: TIER1_GUARD_IP(0) + 16 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=38, operand0=0, operand1=0) + 17 ADD_TO_TRACE: _GUARD_IP (0, target=34, operand0=0x71448db55654, operand1=0) +34: SEND_GEN(3) + 18 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=34, operand0=0, operand1=0) + 19 ADD_TO_TRACE: _SET_IP (0, target=34, operand0=0x71448db55654, operand1=0) + 20 ADD_TO_TRACE: _CHECK_PEP_523 (3, target=34, operand0=0, operand1=0) + 21 ADD_TO_TRACE: _SEND_GEN_FRAME (3, target=34, operand0=0, operand1=0) + 22 ADD_TO_TRACE: _PUSH_FRAME (3, target=34, operand0=0, operand1=0) +34: TIER1_GUARD_IP(0) + 23 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=34, operand0=0, operand1=0) + 24 ADD_TO_TRACE: _GUARD_IP (0, target=37, operand0=0x71448db5565a, operand1=0) +37: RESUME_CHECK(2) + 25 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=37, operand0=0, operand1=0) + 26 ADD_TO_TRACE: _SET_IP (0, target=37, operand0=0x71448db5565a, operand1=0) + 27 ADD_TO_TRACE: _RESUME_CHECK (2, target=37, operand0=0, operand1=0) +37: TIER1_SET_IP(0) + 28 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=37, operand0=0, operand1=0) + 29 ADD_TO_TRACE: _SET_IP (0, target=37, operand0=0x71448db5565a, operand1=0) +38: JUMP_BACKWARD_NO_INTERRUPT(5) + 30 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=38, operand0=0, operand1=0) + 31 ADD_TO_TRACE: _SET_IP (0, target=38, operand0=0x71448db5565c, operand1=0) + 32 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=38, operand0=0, operand1=0, error_target=0) +38: TIER1_GUARD_IP(0) + 33 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=38, operand0=0, operand1=0) + 34 ADD_TO_TRACE: _GUARD_IP (0, target=34, operand0=0x71448db55654, operand1=0) +34: SEND_GEN(3) + 35 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=34, operand0=0, operand1=0) + 36 ADD_TO_TRACE: _SET_IP (0, target=34, operand0=0x71448db55654, operand1=0) + 37 ADD_TO_TRACE: _CHECK_PEP_523 (3, target=34, operand0=0, operand1=0) + 38 ADD_TO_TRACE: _SEND_GEN_FRAME (3, target=34, operand0=0, operand1=0) + 39 ADD_TO_TRACE: _PUSH_FRAME (3, target=34, operand0=0, operand1=0) +34: TIER1_GUARD_IP(0) + 40 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=34, operand0=0, operand1=0) + 41 ADD_TO_TRACE: _GUARD_IP (0, target=37, operand0=0x71448db5565a, operand1=0) +37: RESUME_CHECK(2) + 42 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=37, operand0=0, operand1=0) + 43 ADD_TO_TRACE: _SET_IP (0, target=37, operand0=0x71448db5565a, operand1=0) + 44 ADD_TO_TRACE: _RESUME_CHECK (2, target=37, operand0=0, operand1=0) +37: TIER1_SET_IP(0) + 45 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=37, operand0=0, operand1=0) + 46 ADD_TO_TRACE: _SET_IP (0, target=37, operand0=0x71448db5565a, operand1=0) +38: JUMP_BACKWARD_NO_INTERRUPT(5) + 47 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=38, operand0=0, operand1=0) + 48 ADD_TO_TRACE: _SET_IP (0, target=38, operand0=0x71448db5565c, operand1=0) + 49 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=38, operand0=0, operand1=0, error_target=0) +38: TIER1_GUARD_IP(0) + 50 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=38, operand0=0, operand1=0) + 51 ADD_TO_TRACE: _GUARD_IP (0, target=34, operand0=0x71448db55654, operand1=0) +34: SEND_GEN(3) + 52 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=34, operand0=0, operand1=0) + 53 ADD_TO_TRACE: _SET_IP (0, target=34, operand0=0x71448db55654, operand1=0) + 54 ADD_TO_TRACE: _CHECK_PEP_523 (3, target=34, operand0=0, operand1=0) + 55 ADD_TO_TRACE: _SEND_GEN_FRAME (3, target=34, operand0=0, operand1=0) + 56 ADD_TO_TRACE: _PUSH_FRAME (3, target=34, operand0=0, operand1=0) +34: TIER1_GUARD_IP(0) + 57 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=34, operand0=0, operand1=0) + 58 ADD_TO_TRACE: _GUARD_IP (0, target=37, operand0=0x71448db5565a, operand1=0) +37: RESUME_CHECK(2) + 59 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=37, operand0=0, operand1=0) + 60 ADD_TO_TRACE: _SET_IP (0, target=37, operand0=0x71448db5565a, operand1=0) + 61 ADD_TO_TRACE: _RESUME_CHECK (2, target=37, operand0=0, operand1=0) +37: TIER1_SET_IP(0) + 62 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=37, operand0=0, operand1=0) + 63 ADD_TO_TRACE: _SET_IP (0, target=37, operand0=0x71448db5565a, operand1=0) +38: JUMP_BACKWARD_NO_INTERRUPT(5) + 64 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=38, operand0=0, operand1=0) + 65 ADD_TO_TRACE: _SET_IP (0, target=38, operand0=0x71448db5565c, operand1=0) + 66 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=38, operand0=0, operand1=0, error_target=0) +38: TIER1_GUARD_IP(0) + 67 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=38, operand0=0, operand1=0) + 68 ADD_TO_TRACE: _GUARD_IP (0, target=34, operand0=0x71448db55654, operand1=0) +34: SEND_GEN(3) + 69 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=34, operand0=0, operand1=0) + 70 ADD_TO_TRACE: _SET_IP (0, target=34, operand0=0x71448db55654, operand1=0) + 71 ADD_TO_TRACE: _CHECK_PEP_523 (3, target=34, operand0=0, operand1=0) + 72 ADD_TO_TRACE: _SEND_GEN_FRAME (3, target=34, operand0=0, operand1=0) + 73 ADD_TO_TRACE: _PUSH_FRAME (3, target=34, operand0=0, operand1=0) +34: TIER1_GUARD_IP(0) + 74 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=34, operand0=0, operand1=0) + 75 ADD_TO_TRACE: _GUARD_IP (0, target=89, operand0=0x71448db556c2, operand1=0) +89: RESUME_CHECK(2) + 76 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=89, operand0=0, operand1=0) + 77 ADD_TO_TRACE: _SET_IP (0, target=89, operand0=0x71448db556c2, operand1=0) + 78 ADD_TO_TRACE: _RESUME_CHECK (2, target=89, operand0=0, operand1=0) +89: TIER1_SET_IP(0) + 79 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=89, operand0=0, operand1=0) + 80 ADD_TO_TRACE: _SET_IP (0, target=89, operand0=0x71448db556c2, operand1=0) +90: JUMP_BACKWARD_NO_INTERRUPT(5) + 81 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=90, operand0=0, operand1=0) + 82 ADD_TO_TRACE: _SET_IP (0, target=90, operand0=0x71448db556c4, operand1=0) + 83 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=90, operand0=0, operand1=0, error_target=0) +90: TIER1_GUARD_IP(0) + 84 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=90, operand0=0, operand1=0) + 85 ADD_TO_TRACE: _GUARD_IP (0, target=86, operand0=0x71448db556bc, operand1=0) +86: SEND_GEN(3) + 86 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=86, operand0=0, operand1=0) + 87 ADD_TO_TRACE: _SET_IP (0, target=86, operand0=0x71448db556bc, operand1=0) + 88 ADD_TO_TRACE: _CHECK_PEP_523 (3, target=86, operand0=0, operand1=0) + 89 ADD_TO_TRACE: _SEND_GEN_FRAME (3, target=86, operand0=0, operand1=0) + 90 ADD_TO_TRACE: _PUSH_FRAME (3, target=86, operand0=0, operand1=0) +86: TIER1_GUARD_IP(0) + 91 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=86, operand0=0, operand1=0) + 92 ADD_TO_TRACE: _GUARD_IP (0, target=37, operand0=0x71448db5565a, operand1=0) +37: RESUME_CHECK(2) + 93 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=37, operand0=0, operand1=0) + 94 ADD_TO_TRACE: _SET_IP (0, target=37, operand0=0x71448db5565a, operand1=0) + 95 ADD_TO_TRACE: _RESUME_CHECK (2, target=37, operand0=0, operand1=0) +37: TIER1_SET_IP(0) + 96 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=37, operand0=0, operand1=0) + 97 ADD_TO_TRACE: _SET_IP (0, target=37, operand0=0x71448db5565a, operand1=0) +38: JUMP_BACKWARD_NO_INTERRUPT(5) + 98 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=38, operand0=0, operand1=0) + 99 ADD_TO_TRACE: _SET_IP (0, target=38, operand0=0x71448db5565c, operand1=0) + 100 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=38, operand0=0, operand1=0, error_target=0) +38: TIER1_GUARD_IP(0) + 101 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=38, operand0=0, operand1=0) + 102 ADD_TO_TRACE: _GUARD_IP (0, target=34, operand0=0x71448db55654, operand1=0) +34: SEND_GEN(3) + 103 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=34, operand0=0, operand1=0) + 104 ADD_TO_TRACE: _SET_IP (0, target=34, operand0=0x71448db55654, operand1=0) + 105 ADD_TO_TRACE: _CHECK_PEP_523 (3, target=34, operand0=0, operand1=0) + 106 ADD_TO_TRACE: _SEND_GEN_FRAME (3, target=34, operand0=0, operand1=0) + 107 ADD_TO_TRACE: _PUSH_FRAME (3, target=34, operand0=0, operand1=0) +34: TIER1_GUARD_IP(0) + 108 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=34, operand0=0, operand1=0) + 109 ADD_TO_TRACE: _GUARD_IP (0, target=89, operand0=0x71448db556c2, operand1=0) +89: RESUME_CHECK(2) + 110 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=89, operand0=0, operand1=0) + 111 ADD_TO_TRACE: _SET_IP (0, target=89, operand0=0x71448db556c2, operand1=0) + 112 ADD_TO_TRACE: _RESUME_CHECK (2, target=89, operand0=0, operand1=0) +89: TIER1_SET_IP(0) + 113 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=89, operand0=0, operand1=0) + 114 ADD_TO_TRACE: _SET_IP (0, target=89, operand0=0x71448db556c2, operand1=0) +90: JUMP_BACKWARD_NO_INTERRUPT(5) + 115 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=90, operand0=0, operand1=0) + 116 ADD_TO_TRACE: _SET_IP (0, target=90, operand0=0x71448db556c4, operand1=0) + 117 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=90, operand0=0, operand1=0, error_target=0) +90: TIER1_GUARD_IP(0) + 118 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=90, operand0=0, operand1=0) + 119 ADD_TO_TRACE: _GUARD_IP (0, target=86, operand0=0x71448db556bc, operand1=0) +86: SEND_GEN(3) + 120 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=86, operand0=0, operand1=0) + 121 ADD_TO_TRACE: _SET_IP (0, target=86, operand0=0x71448db556bc, operand1=0) + 122 ADD_TO_TRACE: _CHECK_PEP_523 (3, target=86, operand0=0, operand1=0) + 123 ADD_TO_TRACE: _SEND_GEN_FRAME (3, target=86, operand0=0, operand1=0) + 124 ADD_TO_TRACE: _PUSH_FRAME (3, target=86, operand0=0, operand1=0) +86: TIER1_GUARD_IP(0) + 125 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=86, operand0=0, operand1=0) + 126 ADD_TO_TRACE: _GUARD_IP (0, target=37, operand0=0x71448db5565a, operand1=0) +37: RESUME_CHECK(2) + 127 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=37, operand0=0, operand1=0) + 128 ADD_TO_TRACE: _SET_IP (0, target=37, operand0=0x71448db5565a, operand1=0) + 129 ADD_TO_TRACE: _RESUME_CHECK (2, target=37, operand0=0, operand1=0) +37: TIER1_SET_IP(0) + 130 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=37, operand0=0, operand1=0) + 131 ADD_TO_TRACE: _SET_IP (0, target=37, operand0=0x71448db5565a, operand1=0) +38: JUMP_BACKWARD_NO_INTERRUPT(5) + 132 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=38, operand0=0, operand1=0) + 133 ADD_TO_TRACE: _SET_IP (0, target=38, operand0=0x71448db5565c, operand1=0) + 134 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=38, operand0=0, operand1=0, error_target=0) +38: TIER1_GUARD_IP(0) + 135 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=38, operand0=0, operand1=0) + 136 ADD_TO_TRACE: _GUARD_IP (0, target=34, operand0=0x71448db55654, operand1=0) +34: SEND_GEN(3) + 137 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=34, operand0=0, operand1=0) + 138 ADD_TO_TRACE: _SET_IP (0, target=34, operand0=0x71448db55654, operand1=0) + 139 ADD_TO_TRACE: _CHECK_PEP_523 (3, target=34, operand0=0, operand1=0) + 140 ADD_TO_TRACE: _SEND_GEN_FRAME (3, target=34, operand0=0, operand1=0) + 141 ADD_TO_TRACE: _PUSH_FRAME (3, target=34, operand0=0, operand1=0) +34: TIER1_GUARD_IP(0) + 142 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=34, operand0=0, operand1=0) + 143 ADD_TO_TRACE: _GUARD_IP (0, target=37, operand0=0x71448db5565a, operand1=0) +37: RESUME_CHECK(2) + 144 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=37, operand0=0, operand1=0) + 145 ADD_TO_TRACE: _SET_IP (0, target=37, operand0=0x71448db5565a, operand1=0) + 146 ADD_TO_TRACE: _RESUME_CHECK (2, target=37, operand0=0, operand1=0) +37: TIER1_SET_IP(0) + 147 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=37, operand0=0, operand1=0) + 148 ADD_TO_TRACE: _SET_IP (0, target=37, operand0=0x71448db5565a, operand1=0) +38: JUMP_BACKWARD_NO_INTERRUPT(5) + 149 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=38, operand0=0, operand1=0) + 150 ADD_TO_TRACE: _SET_IP (0, target=38, operand0=0x71448db5565c, operand1=0) + 151 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=38, operand0=0, operand1=0, error_target=0) +38: TIER1_GUARD_IP(0) + 152 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=38, operand0=0, operand1=0) + 153 ADD_TO_TRACE: _GUARD_IP (0, target=34, operand0=0x71448db55654, operand1=0) +34: SEND_GEN(3) + 154 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=34, operand0=0, operand1=0) + 155 ADD_TO_TRACE: _SET_IP (0, target=34, operand0=0x71448db55654, operand1=0) + 156 ADD_TO_TRACE: _CHECK_PEP_523 (3, target=34, operand0=0, operand1=0) + 157 ADD_TO_TRACE: _SEND_GEN_FRAME (3, target=34, operand0=0, operand1=0) + 158 ADD_TO_TRACE: _PUSH_FRAME (3, target=34, operand0=0, operand1=0) +34: TIER1_GUARD_IP(0) + 159 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=34, operand0=0, operand1=0) + 160 ADD_TO_TRACE: _GUARD_IP (0, target=89, operand0=0x71448db556c2, operand1=0) +89: RESUME_CHECK(2) + 161 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=89, operand0=0, operand1=0) + 162 ADD_TO_TRACE: _SET_IP (0, target=89, operand0=0x71448db556c2, operand1=0) + 163 ADD_TO_TRACE: _RESUME_CHECK (2, target=89, operand0=0, operand1=0) +89: TIER1_SET_IP(0) + 164 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=89, operand0=0, operand1=0) + 165 ADD_TO_TRACE: _SET_IP (0, target=89, operand0=0x71448db556c2, operand1=0) +90: JUMP_BACKWARD_NO_INTERRUPT(5) + 166 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=90, operand0=0, operand1=0) + 167 ADD_TO_TRACE: _SET_IP (0, target=90, operand0=0x71448db556c4, operand1=0) + 168 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=90, operand0=0, operand1=0, error_target=0) +90: TIER1_GUARD_IP(0) + 169 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=90, operand0=0, operand1=0) + 170 ADD_TO_TRACE: _GUARD_IP (0, target=86, operand0=0x71448db556bc, operand1=0) +86: SEND_GEN(3) + 171 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=86, operand0=0, operand1=0) + 172 ADD_TO_TRACE: _SET_IP (0, target=86, operand0=0x71448db556bc, operand1=0) + 173 ADD_TO_TRACE: _CHECK_PEP_523 (3, target=86, operand0=0, operand1=0) + 174 ADD_TO_TRACE: _SEND_GEN_FRAME (3, target=86, operand0=0, operand1=0) + 175 ADD_TO_TRACE: _PUSH_FRAME (3, target=86, operand0=0, operand1=0) +86: TIER1_GUARD_IP(0) + 176 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=86, operand0=0, operand1=0) + 177 ADD_TO_TRACE: _GUARD_IP (0, target=89, operand0=0x71448db556c2, operand1=0) +89: RESUME_CHECK(2) + 178 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=89, operand0=0, operand1=0) + 179 ADD_TO_TRACE: _SET_IP (0, target=89, operand0=0x71448db556c2, operand1=0) + 180 ADD_TO_TRACE: _RESUME_CHECK (2, target=89, operand0=0, operand1=0) +89: TIER1_SET_IP(0) + 181 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=89, operand0=0, operand1=0) + 182 ADD_TO_TRACE: _SET_IP (0, target=89, operand0=0x71448db556c2, operand1=0) +90: JUMP_BACKWARD_NO_INTERRUPT(5) + 183 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=90, operand0=0, operand1=0) + 184 ADD_TO_TRACE: _SET_IP (0, target=90, operand0=0x71448db556c4, operand1=0) + 185 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=90, operand0=0, operand1=0, error_target=0) +90: TIER1_GUARD_IP(0) + 186 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=90, operand0=0, operand1=0) + 187 ADD_TO_TRACE: _GUARD_IP (0, target=86, operand0=0x71448db556bc, operand1=0) +86: SEND_GEN(3) + 188 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=86, operand0=0, operand1=0) + 189 ADD_TO_TRACE: _SET_IP (0, target=86, operand0=0x71448db556bc, operand1=0) + 190 ADD_TO_TRACE: _CHECK_PEP_523 (3, target=86, operand0=0, operand1=0) + 191 ADD_TO_TRACE: _SEND_GEN_FRAME (3, target=86, operand0=0, operand1=0) + 192 ADD_TO_TRACE: _PUSH_FRAME (3, target=86, operand0=0, operand1=0) +86: TIER1_GUARD_IP(0) + 193 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=86, operand0=0, operand1=0) + 194 ADD_TO_TRACE: _GUARD_IP (0, target=89, operand0=0x71448db556c2, operand1=0) +89: RESUME_CHECK(2) + 195 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=89, operand0=0, operand1=0) + 196 ADD_TO_TRACE: _SET_IP (0, target=89, operand0=0x71448db556c2, operand1=0) + 197 ADD_TO_TRACE: _RESUME_CHECK (2, target=89, operand0=0, operand1=0) +89: TIER1_SET_IP(0) + 198 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=89, operand0=0, operand1=0) + 199 ADD_TO_TRACE: _SET_IP (0, target=89, operand0=0x71448db556c2, operand1=0) +90: JUMP_BACKWARD_NO_INTERRUPT(5) + 200 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=90, operand0=0, operand1=0) + 201 ADD_TO_TRACE: _SET_IP (0, target=90, operand0=0x71448db556c4, operand1=0) + 202 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=90, operand0=0, operand1=0, error_target=0) +90: TIER1_GUARD_IP(0) + 203 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=90, operand0=0, operand1=0) + 204 ADD_TO_TRACE: _GUARD_IP (0, target=86, operand0=0x71448db556bc, operand1=0) +86: SEND_GEN(3) + 205 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=86, operand0=0, operand1=0) + 206 ADD_TO_TRACE: _SET_IP (0, target=86, operand0=0x71448db556bc, operand1=0) + 207 ADD_TO_TRACE: _CHECK_PEP_523 (3, target=86, operand0=0, operand1=0) + 208 ADD_TO_TRACE: _SEND_GEN_FRAME (3, target=86, operand0=0, operand1=0) + 209 ADD_TO_TRACE: _PUSH_FRAME (3, target=86, operand0=0, operand1=0) +86: TIER1_GUARD_IP(0) + 210 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=86, operand0=0, operand1=0) + 211 ADD_TO_TRACE: _GUARD_IP (0, target=89, operand0=0x71448db556c2, operand1=0) +89: RESUME_CHECK(2) + 212 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=89, operand0=0, operand1=0) + 213 ADD_TO_TRACE: _SET_IP (0, target=89, operand0=0x71448db556c2, operand1=0) + 214 ADD_TO_TRACE: _RESUME_CHECK (2, target=89, operand0=0, operand1=0) +89: TIER1_SET_IP(0) + 215 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=89, operand0=0, operand1=0) + 216 ADD_TO_TRACE: _SET_IP (0, target=89, operand0=0x71448db556c2, operand1=0) +90: JUMP_BACKWARD_NO_INTERRUPT(5) + 217 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=90, operand0=0, operand1=0) + 218 ADD_TO_TRACE: _SET_IP (0, target=90, operand0=0x71448db556c4, operand1=0) + 219 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=90, operand0=0, operand1=0, error_target=0) +90: TIER1_GUARD_IP(0) + 220 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=90, operand0=0, operand1=0) + 221 ADD_TO_TRACE: _GUARD_IP (0, target=86, operand0=0x71448db556bc, operand1=0) +86: SEND_GEN(3) + 222 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=86, operand0=0, operand1=0) + 223 ADD_TO_TRACE: _SET_IP (0, target=86, operand0=0x71448db556bc, operand1=0) + 224 ADD_TO_TRACE: _CHECK_PEP_523 (3, target=86, operand0=0, operand1=0) + 225 ADD_TO_TRACE: _SEND_GEN_FRAME (3, target=86, operand0=0, operand1=0) + 226 ADD_TO_TRACE: _PUSH_FRAME (3, target=86, operand0=0, operand1=0) +86: TIER1_GUARD_IP(0) + 227 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=86, operand0=0, operand1=0) + 228 ADD_TO_TRACE: _GUARD_IP (0, target=37, operand0=0x71448db5565a, operand1=0) +37: RESUME_CHECK(2) + 229 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=37, operand0=0, operand1=0) + 230 ADD_TO_TRACE: _SET_IP (0, target=37, operand0=0x71448db5565a, operand1=0) + 231 ADD_TO_TRACE: _RESUME_CHECK (2, target=37, operand0=0, operand1=0) +37: TIER1_SET_IP(0) + 232 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=37, operand0=0, operand1=0) + 233 ADD_TO_TRACE: _SET_IP (0, target=37, operand0=0x71448db5565a, operand1=0) +38: JUMP_BACKWARD_NO_INTERRUPT(5) + 234 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=38, operand0=0, operand1=0) + 235 ADD_TO_TRACE: _SET_IP (0, target=38, operand0=0x71448db5565c, operand1=0) + 236 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=38, operand0=0, operand1=0, error_target=0) +38: TIER1_GUARD_IP(0) + 237 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=38, operand0=0, operand1=0) + 238 ADD_TO_TRACE: _GUARD_IP (0, target=34, operand0=0x71448db55654, operand1=0) +34: SEND_GEN(3) + 239 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=34, operand0=0, operand1=0) + 240 ADD_TO_TRACE: _SET_IP (0, target=34, operand0=0x71448db55654, operand1=0) + 241 ADD_TO_TRACE: _CHECK_PEP_523 (3, target=34, operand0=0, operand1=0) + 242 ADD_TO_TRACE: _SEND_GEN_FRAME (3, target=34, operand0=0, operand1=0) + 243 ADD_TO_TRACE: _PUSH_FRAME (3, target=34, operand0=0, operand1=0) +34: TIER1_GUARD_IP(0) + 244 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=34, operand0=0, operand1=0) + 245 ADD_TO_TRACE: _GUARD_IP (0, target=89, operand0=0x71448db556c2, operand1=0) +89: RESUME_CHECK(2) + 246 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=89, operand0=0, operand1=0) + 247 ADD_TO_TRACE: _SET_IP (0, target=89, operand0=0x71448db556c2, operand1=0) + 248 ADD_TO_TRACE: _RESUME_CHECK (2, target=89, operand0=0, operand1=0) +89: TIER1_SET_IP(0) + 249 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=89, operand0=0, operand1=0) + 250 ADD_TO_TRACE: _SET_IP (0, target=89, operand0=0x71448db556c2, operand1=0) +90: JUMP_BACKWARD_NO_INTERRUPT(5) + 251 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=90, operand0=0, operand1=0) + 252 ADD_TO_TRACE: _SET_IP (0, target=90, operand0=0x71448db556c4, operand1=0) + 253 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=90, operand0=0, operand1=0, error_target=0) +90: TIER1_GUARD_IP(0) + 254 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=90, operand0=0, operand1=0) + 255 ADD_TO_TRACE: _GUARD_IP (0, target=86, operand0=0x71448db556bc, operand1=0) +86: SEND_GEN(3) + 256 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=86, operand0=0, operand1=0) + 257 ADD_TO_TRACE: _SET_IP (0, target=86, operand0=0x71448db556bc, operand1=0) + 258 ADD_TO_TRACE: _CHECK_PEP_523 (3, target=86, operand0=0, operand1=0) + 259 ADD_TO_TRACE: _SEND_GEN_FRAME (3, target=86, operand0=0, operand1=0) + 260 ADD_TO_TRACE: _PUSH_FRAME (3, target=86, operand0=0, operand1=0) +86: TIER1_GUARD_IP(0) + 261 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=86, operand0=0, operand1=0) + 262 ADD_TO_TRACE: _GUARD_IP (0, target=37, operand0=0x71448db5565a, operand1=0) +37: RESUME_CHECK(2) + 263 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=37, operand0=0, operand1=0) + 264 ADD_TO_TRACE: _SET_IP (0, target=37, operand0=0x71448db5565a, operand1=0) + 265 ADD_TO_TRACE: _RESUME_CHECK (2, target=37, operand0=0, operand1=0) +37: TIER1_SET_IP(0) + 266 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=37, operand0=0, operand1=0) + 267 ADD_TO_TRACE: _SET_IP (0, target=37, operand0=0x71448db5565a, operand1=0) +38: JUMP_BACKWARD_NO_INTERRUPT(5) + 268 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=38, operand0=0, operand1=0) + 269 ADD_TO_TRACE: _SET_IP (0, target=38, operand0=0x71448db5565c, operand1=0) + 270 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=38, operand0=0, operand1=0, error_target=0) +38: TIER1_GUARD_IP(0) + 271 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=38, operand0=0, operand1=0) + 272 ADD_TO_TRACE: _GUARD_IP (0, target=34, operand0=0x71448db55654, operand1=0) +34: SEND_GEN(3) + 273 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=34, operand0=0, operand1=0) + 274 ADD_TO_TRACE: _SET_IP (0, target=34, operand0=0x71448db55654, operand1=0) + 275 ADD_TO_TRACE: _CHECK_PEP_523 (3, target=34, operand0=0, operand1=0) + 276 ADD_TO_TRACE: _SEND_GEN_FRAME (3, target=34, operand0=0, operand1=0) + 277 ADD_TO_TRACE: _PUSH_FRAME (3, target=34, operand0=0, operand1=0) +34: TIER1_GUARD_IP(0) + 278 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=34, operand0=0, operand1=0) + 279 ADD_TO_TRACE: _GUARD_IP (0, target=53, operand0=0x71448db5567a, operand1=0) +53: RESUME_CHECK(5) + 280 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=53, operand0=0, operand1=0) + 281 ADD_TO_TRACE: _SET_IP (0, target=53, operand0=0x71448db5567a, operand1=0) + 282 ADD_TO_TRACE: _RESUME_CHECK (5, target=53, operand0=0, operand1=0) +53: TIER1_SET_IP(0) + 283 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=53, operand0=0, operand1=0) + 284 ADD_TO_TRACE: _SET_IP (0, target=53, operand0=0x71448db5567a, operand1=0) +54: POP_TOP(0) + 285 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=54, operand0=0, operand1=0) + 286 ADD_TO_TRACE: _SET_IP (0, target=54, operand0=0x71448db5567c, operand1=0) + 287 ADD_TO_TRACE: _POP_TOP (0, target=54, operand0=0, operand1=0) +54: TIER1_SET_IP(0) + 288 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=54, operand0=0, operand1=0) + 289 ADD_TO_TRACE: _SET_IP (0, target=54, operand0=0x71448db5567c, operand1=0) +55: LOAD_FAST_BORROW(0) + 290 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=55, operand0=0, operand1=0) + 291 ADD_TO_TRACE: _SET_IP (0, target=55, operand0=0x71448db5567e, operand1=0) + 292 ADD_TO_TRACE: _LOAD_FAST_BORROW (0, target=55, operand0=0, operand1=0) +55: TIER1_SET_IP(0) + 293 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=55, operand0=0, operand1=0) + 294 ADD_TO_TRACE: _SET_IP (0, target=55, operand0=0x71448db5567e, operand1=0) +56: LOAD_ATTR_INSTANCE_VALUE(4) + 295 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=56, operand0=0, operand1=0) + 296 ADD_TO_TRACE: _SET_IP (0, target=56, operand0=0x71448db55680, operand1=0) + 297 ADD_TO_TRACE: _GUARD_TYPE_VERSION (4, target=56, operand0=0x2004a, operand1=0) + 298 ADD_TO_TRACE: _CHECK_MANAGED_OBJECT_HAS_VALUES (4, target=56, operand0=0, operand1=0) + 299 ADD_TO_TRACE: _LOAD_ATTR_INSTANCE_VALUE (4, target=56, operand0=0x20, operand1=0) + 300 ADD_TO_TRACE: _PUSH_NULL_CONDITIONAL (4, target=56, operand0=0, operand1=0) +56: TIER1_SET_IP(0) + 301 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=56, operand0=0, operand1=0) + 302 ADD_TO_TRACE: _SET_IP (0, target=56, operand0=0x71448db55680, operand1=0) +66: TO_BOOL_NONE(0) + 303 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=66, operand0=0, operand1=0) + 304 ADD_TO_TRACE: _SET_IP (0, target=66, operand0=0x71448db55694, operand1=0) + 305 ADD_TO_TRACE: _TO_BOOL_NONE (0, target=66, operand0=0, operand1=0) +66: TIER1_SET_IP(0) + 306 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=66, operand0=0, operand1=0) + 307 ADD_TO_TRACE: _SET_IP (0, target=66, operand0=0x71448db55694, operand1=0) +70: POP_JUMP_IF_FALSE(23) + 308 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=70, operand0=0, operand1=0) + 309 ADD_TO_TRACE: _SET_IP (0, target=70, operand0=0x71448db5569c, operand1=0) + 310 ADD_TO_TRACE: _POP_JUMP_IF_FALSE (23, target=70, operand0=0, operand1=0) +70: TIER1_GUARD_IP(0) + 311 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=70, operand0=0, operand1=0) + 312 ADD_TO_TRACE: _GUARD_IP (0, target=95, operand0=0x71448db556ce, operand1=0) +95: LOAD_CONST(0) + 313 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=95, operand0=0, operand1=0) + 314 ADD_TO_TRACE: _SET_IP (0, target=95, operand0=0x71448db556ce, operand1=0) + 315 ADD_TO_TRACE: _LOAD_CONST (0, target=95, operand0=0, operand1=0) +95: TIER1_SET_IP(0) + 316 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=95, operand0=0, operand1=0) + 317 ADD_TO_TRACE: _SET_IP (0, target=95, operand0=0x71448db556ce, operand1=0) +96: RETURN_VALUE(0) + 318 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=96, operand0=0, operand1=0) + 319 ADD_TO_TRACE: _SET_IP (0, target=96, operand0=0x71448db556d0, operand1=0) + 320 ADD_TO_TRACE: _RETURN_VALUE (0, target=96, operand0=0, operand1=0) +96: TIER1_GUARD_IP(0) + 321 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=96, operand0=0, operand1=0) + 322 ADD_TO_TRACE: _GUARD_IP (0, target=39, operand0=0x71448db5565e, operand1=0) +39: END_SEND(0) + 323 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=39, operand0=0, operand1=0) + 324 ADD_TO_TRACE: _SET_IP (0, target=39, operand0=0x71448db5565e, operand1=0) + 325 ADD_TO_TRACE: _END_SEND (0, target=39, operand0=0, operand1=0) +39: TIER1_SET_IP(0) + 326 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=39, operand0=0, operand1=0) + 327 ADD_TO_TRACE: _SET_IP (0, target=39, operand0=0x71448db5565e, operand1=0) +40: POP_TOP(0) + 328 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=40, operand0=0, operand1=0) + 329 ADD_TO_TRACE: _SET_IP (0, target=40, operand0=0x71448db55660, operand1=0) + 330 ADD_TO_TRACE: _POP_TOP (0, target=40, operand0=0, operand1=0) +40: TIER1_SET_IP(0) + 331 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=40, operand0=0, operand1=0) + 332 ADD_TO_TRACE: _SET_IP (0, target=40, operand0=0x71448db55660, operand1=0) +41: LOAD_FAST_BORROW(0) + 333 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=41, operand0=0, operand1=0) + 334 ADD_TO_TRACE: _SET_IP (0, target=41, operand0=0x71448db55662, operand1=0) + 335 ADD_TO_TRACE: _LOAD_FAST_BORROW (0, target=41, operand0=0, operand1=0) +41: TIER1_SET_IP(0) + 336 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=41, operand0=0, operand1=0) + 337 ADD_TO_TRACE: _SET_IP (0, target=41, operand0=0x71448db55662, operand1=0) +42: LOAD_ATTR_INSTANCE_VALUE(2) + 338 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=42, operand0=0, operand1=0) + 339 ADD_TO_TRACE: _SET_IP (0, target=42, operand0=0x71448db55664, operand1=0) + 340 ADD_TO_TRACE: _GUARD_TYPE_VERSION (2, target=42, operand0=0x2004a, operand1=0) + 341 ADD_TO_TRACE: _CHECK_MANAGED_OBJECT_HAS_VALUES (2, target=42, operand0=0, operand1=0) + 342 ADD_TO_TRACE: _LOAD_ATTR_INSTANCE_VALUE (2, target=42, operand0=0x28, operand1=0) + 343 ADD_TO_TRACE: _PUSH_NULL_CONDITIONAL (2, target=42, operand0=0, operand1=0) +42: TIER1_SET_IP(0) + 344 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=42, operand0=0, operand1=0) + 345 ADD_TO_TRACE: _SET_IP (0, target=42, operand0=0x71448db55664, operand1=0) +52: YIELD_VALUE(0) + 346 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=52, operand0=0, operand1=0) + 347 ADD_TO_TRACE: _SET_IP (0, target=52, operand0=0x71448db55678, operand1=0) + 348 ADD_TO_TRACE: _YIELD_VALUE (0, target=52, operand0=0, operand1=0) +52: TIER1_GUARD_IP(0) + 349 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=52, operand0=0, operand1=0) + 350 ADD_TO_TRACE: _GUARD_IP (0, target=88, operand0=0x71448db556c0, operand1=0) +88: YIELD_VALUE(1) + 351 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=88, operand0=0, operand1=0) + 352 ADD_TO_TRACE: _SET_IP (0, target=88, operand0=0x71448db556c0, operand1=0) + 353 ADD_TO_TRACE: _YIELD_VALUE (1, target=88, operand0=0, operand1=0) +88: TIER1_GUARD_IP(0) + 354 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=88, operand0=0, operand1=0) + 355 ADD_TO_TRACE: _GUARD_IP (0, target=36, operand0=0x71448db55658, operand1=0) +36: YIELD_VALUE(1) + 356 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=36, operand0=0, operand1=0) + 357 ADD_TO_TRACE: _SET_IP (0, target=36, operand0=0x71448db55658, operand1=0) + 358 ADD_TO_TRACE: _YIELD_VALUE (1, target=36, operand0=0, operand1=0) +36: TIER1_GUARD_IP(0) + 359 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=36, operand0=0, operand1=0) + 360 ADD_TO_TRACE: _GUARD_IP (0, target=88, operand0=0x71448db556c0, operand1=0) +88: YIELD_VALUE(1) + 361 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=88, operand0=0, operand1=0) + 362 ADD_TO_TRACE: _SET_IP (0, target=88, operand0=0x71448db556c0, operand1=0) + 363 ADD_TO_TRACE: _YIELD_VALUE (1, target=88, operand0=0, operand1=0) +88: TIER1_GUARD_IP(0) + 364 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=88, operand0=0, operand1=0) + 365 ADD_TO_TRACE: _GUARD_IP (0, target=88, operand0=0x71448db556c0, operand1=0) +88: YIELD_VALUE(1) + 366 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=88, operand0=0, operand1=0) + 367 ADD_TO_TRACE: _SET_IP (0, target=88, operand0=0x71448db556c0, operand1=0) + 368 ADD_TO_TRACE: _YIELD_VALUE (1, target=88, operand0=0, operand1=0) +88: TIER1_GUARD_IP(0) + 369 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=88, operand0=0, operand1=0) + 370 ADD_TO_TRACE: _GUARD_IP (0, target=88, operand0=0x71448db556c0, operand1=0) +88: YIELD_VALUE(1) + 371 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=88, operand0=0, operand1=0) + 372 ADD_TO_TRACE: _SET_IP (0, target=88, operand0=0x71448db556c0, operand1=0) + 373 ADD_TO_TRACE: _YIELD_VALUE (1, target=88, operand0=0, operand1=0) +88: TIER1_GUARD_IP(0) + 374 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=88, operand0=0, operand1=0) + 375 ADD_TO_TRACE: _GUARD_IP (0, target=88, operand0=0x71448db556c0, operand1=0) +88: YIELD_VALUE(1) + 376 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=88, operand0=0, operand1=0) + 377 ADD_TO_TRACE: _SET_IP (0, target=88, operand0=0x71448db556c0, operand1=0) + 378 ADD_TO_TRACE: _YIELD_VALUE (1, target=88, operand0=0, operand1=0) +88: TIER1_GUARD_IP(0) + 379 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=88, operand0=0, operand1=0) + 380 ADD_TO_TRACE: _GUARD_IP (0, target=36, operand0=0x71448db55658, operand1=0) +36: YIELD_VALUE(1) + 381 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=36, operand0=0, operand1=0) + 382 ADD_TO_TRACE: _SET_IP (0, target=36, operand0=0x71448db55658, operand1=0) + 383 ADD_TO_TRACE: _YIELD_VALUE (1, target=36, operand0=0, operand1=0) +36: TIER1_GUARD_IP(0) + 384 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=36, operand0=0, operand1=0) + 385 ADD_TO_TRACE: _GUARD_IP (0, target=36, operand0=0x71448db55658, operand1=0) +36: YIELD_VALUE(1) + 386 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=36, operand0=0, operand1=0) + 387 ADD_TO_TRACE: _SET_IP (0, target=36, operand0=0x71448db55658, operand1=0) + 388 ADD_TO_TRACE: _YIELD_VALUE (1, target=36, operand0=0, operand1=0) +36: TIER1_GUARD_IP(0) + 389 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=36, operand0=0, operand1=0) + 390 ADD_TO_TRACE: _GUARD_IP (0, target=88, operand0=0x71448db556c0, operand1=0) +88: YIELD_VALUE(1) + 391 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=88, operand0=0, operand1=0) + 392 ADD_TO_TRACE: _SET_IP (0, target=88, operand0=0x71448db556c0, operand1=0) + 393 ADD_TO_TRACE: _YIELD_VALUE (1, target=88, operand0=0, operand1=0) +88: TIER1_GUARD_IP(0) + 394 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=88, operand0=0, operand1=0) + 395 ADD_TO_TRACE: _GUARD_IP (0, target=36, operand0=0x71448db55658, operand1=0) +36: YIELD_VALUE(1) + 396 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=36, operand0=0, operand1=0) + 397 ADD_TO_TRACE: _SET_IP (0, target=36, operand0=0x71448db55658, operand1=0) + 398 ADD_TO_TRACE: _YIELD_VALUE (1, target=36, operand0=0, operand1=0) +36: TIER1_GUARD_IP(0) + 399 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=36, operand0=0, operand1=0) + 400 ADD_TO_TRACE: _GUARD_IP (0, target=88, operand0=0x71448db556c0, operand1=0) +88: YIELD_VALUE(1) + 401 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=88, operand0=0, operand1=0) + 402 ADD_TO_TRACE: _SET_IP (0, target=88, operand0=0x71448db556c0, operand1=0) + 403 ADD_TO_TRACE: _YIELD_VALUE (1, target=88, operand0=0, operand1=0) +88: TIER1_GUARD_IP(0) + 404 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=88, operand0=0, operand1=0) + 405 ADD_TO_TRACE: _GUARD_IP (0, target=36, operand0=0x71448db55658, operand1=0) +36: YIELD_VALUE(1) + 406 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=36, operand0=0, operand1=0) + 407 ADD_TO_TRACE: _SET_IP (0, target=36, operand0=0x71448db55658, operand1=0) + 408 ADD_TO_TRACE: _YIELD_VALUE (1, target=36, operand0=0, operand1=0) +36: TIER1_GUARD_IP(0) + 409 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=36, operand0=0, operand1=0) + 410 ADD_TO_TRACE: _GUARD_IP (0, target=36, operand0=0x71448db55658, operand1=0) +36: YIELD_VALUE(1) + 411 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=36, operand0=0, operand1=0) + 412 ADD_TO_TRACE: _SET_IP (0, target=36, operand0=0x71448db55658, operand1=0) + 413 ADD_TO_TRACE: _YIELD_VALUE (1, target=36, operand0=0, operand1=0) +36: TIER1_GUARD_IP(0) + 414 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=36, operand0=0, operand1=0) + 415 ADD_TO_TRACE: _GUARD_IP (0, target=36, operand0=0x71448db55658, operand1=0) +36: YIELD_VALUE(1) + 416 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=36, operand0=0, operand1=0) + 417 ADD_TO_TRACE: _SET_IP (0, target=36, operand0=0x71448db55658, operand1=0) + 418 ADD_TO_TRACE: _YIELD_VALUE (1, target=36, operand0=0, operand1=0) +36: TIER1_GUARD_IP(0) + 419 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=36, operand0=0, operand1=0) + 420 ADD_TO_TRACE: _GUARD_IP (0, target=36, operand0=0x71448db55658, operand1=0) +36: YIELD_VALUE(1) + 421 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=36, operand0=0, operand1=0) + 422 ADD_TO_TRACE: _SET_IP (0, target=36, operand0=0x71448db55658, operand1=0) + 423 ADD_TO_TRACE: _YIELD_VALUE (1, target=36, operand0=0, operand1=0) +36: TIER1_GUARD_IP(0) + 424 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=36, operand0=0, operand1=0) + 425 ADD_TO_TRACE: _GUARD_IP (0, target=95, operand0=0x71448db5630e, operand1=0) +95: STORE_FAST(3) + 426 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=95, operand0=0, operand1=0) + 427 ADD_TO_TRACE: _SET_IP (0, target=95, operand0=0x71448db5630e, operand1=0) + 428 ADD_TO_TRACE: _STORE_FAST (3, target=95, operand0=0, operand1=0) +95: TIER1_SET_IP(0) + 429 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=95, operand0=0, operand1=0) + 430 ADD_TO_TRACE: _SET_IP (0, target=95, operand0=0x71448db5630e, operand1=0) +96: JUMP_BACKWARD_JIT(5) + 431 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=96, operand0=0, operand1=0) + 432 ADD_TO_TRACE: _SET_IP (0, target=96, operand0=0x71448db56310, operand1=0) + 433 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=96, operand0=0, operand1=0, error_target=0) +96: TIER1_GUARD_IP(0) + 434 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=96, operand0=0, operand1=0) + 435 ADD_TO_TRACE: _GUARD_IP (0, target=93, operand0=0x71448db5630a, operand1=0) + 436 ADD_TO_TRACE: _JUMP_TO_TOP (0, target=0, operand0=0, operand1=0) +Created a proto-trace for bench_generators (/home/ken/Documents/GitHub/cpython/../bm_generators.py:36) at byte offset 186 -- length 436 + locals=[, , , ] + stack=[, , , ] + 0 uop: _START_EXECUTOR (0, jump_target=238, operand0=0x64d708ad28e0, operand1=0) + locals=[, , , ] + stack=[, , , ] + 1 uop: _MAKE_WARM (0, target=0, operand0=0, operand1=0) + locals=[, , , ] + stack=[, , , ] + 2 uop: _SET_IP (0, target=93, operand0=0x71448db5630a, operand1=0) + locals=[, , , ] + stack=[, , , ] + 3 uop: _FOR_ITER (3, jump_target=0, operand0=0, operand1=0, error_target=239) + locals=[, , , ] + stack=[, , , , ] + 4 uop: _CHECK_VALIDITY (0, jump_target=238, operand0=0, operand1=0) + locals=[, , , ] + stack=[, , , , ] + 5 uop: _GUARD_IP (0, target=37, operand0=0x71448db5565a, operand1=0) +0 ADD_TO_BYTECODE_TRACE: STORE_FAST 3 +1 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db56310 +6 ADD_TO_BYTECODE_TRACE: JUMP_BACKWARD_JIT 5 +8 ADD_TO_BYTECODE_TRACE: TIER1_GUARD_IP 0 +13 ADD_TO_BYTECODE_TRACE: TIER1_SET_IP 0x71448db5630a +STORE_FAST(3) +TIER1_SET_IP(3) +JUMP_BACKWARD_JIT(5) +TIER1_GUARD_IP(86) +TIER1_SET_IP(0) +Optimizing bench_generators (/home/ken/Documents/GitHub/cpython/../bm_generators.py:36) at byte offset 186 + 1 ADD_TO_TRACE: _START_EXECUTOR (0, target=93, operand0=0x71448db5630a, operand1=0) + 2 ADD_TO_TRACE: _MAKE_WARM (0, target=0, operand0=0, operand1=0) +93: STORE_FAST(3) + 3 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=93, operand0=0, operand1=0) + 4 ADD_TO_TRACE: _SET_IP (0, target=93, operand0=0x71448db5630a, operand1=0) + 5 ADD_TO_TRACE: _STORE_FAST (3, target=93, operand0=0, operand1=0) +93: TIER1_SET_IP(3) + 6 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=93, operand0=0, operand1=0) + 7 ADD_TO_TRACE: _SET_IP (0, target=93, operand0=0x71448db5630a, operand1=0) +96: JUMP_BACKWARD_JIT(5) + 8 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=96, operand0=0, operand1=0) + 9 ADD_TO_TRACE: _SET_IP (0, target=96, operand0=0x71448db56310, operand1=0) + 10 ADD_TO_TRACE: _CHECK_PERIODIC (0, target=96, operand0=0, operand1=0, error_target=0) +96: TIER1_GUARD_IP(86) + 11 ADD_TO_TRACE: _CHECK_VALIDITY (0, target=96, operand0=0, operand1=0) + 12 ADD_TO_TRACE: _GUARD_IP (0, target=93, operand0=0x71448db5630a, operand1=0) + 13 ADD_TO_TRACE: _JUMP_TO_TOP (0, target=0, operand0=0, operand1=0) +Created a proto-trace for bench_generators (/home/ken/Documents/GitHub/cpython/../bm_generators.py:36) at byte offset 186 -- length 13 + locals=[, , , ] + stack=[, , , ] + 0 uop: _START_EXECUTOR (0, jump_target=10, operand0=0x71448db814f0, operand1=0) + locals=[, , , ] + stack=[, , , ] + 1 uop: _MAKE_WARM (0, target=0, operand0=0, operand1=0) + locals=[, , , ] + stack=[, , , ] + 2 uop: _SET_IP (0, target=93, operand0=0x71448db5630a, operand1=0) + locals=[, , , ] + stack=[, , , ] + 3 uop: _STORE_FAST_3 (3, target=93, operand0=0, operand1=0) + locals=[, , , ] + stack=[, , ] + 4 uop: _CHECK_VALIDITY (0, jump_target=10, operand0=0, operand1=0) + locals=[, , , ] + stack=[, , ] + 5 uop: _SET_IP (0, target=96, operand0=0x71448db56310, operand1=0) + locals=[, , , ] + stack=[, , ] + 6 uop: _CHECK_PERIODIC (0, jump_target=0, operand0=0, operand1=0, error_target=11) + locals=[, , , ] + stack=[, , ] + 7 uop: _CHECK_VALIDITY (0, jump_target=12, operand0=0, operand1=0) + locals=[, , , ] + stack=[, , ] -- 2.47.3