mirror of
https://github.com/python/cpython.git
synced 2026-10-28 10:25:05 +08:00
GH-144179: Add value recording to JIT tracing front-end (GH-144303)
This commit is contained in:
1 parent
5f91577cdd
commit
141fd8b894
23 files changed
+1702
-1274
No files matched your search
@@ -106,6 +106,7 @@ Python/executor_cases.c.h generated
|
||||
Python/generated_cases.c.h generated
|
||||
Python/optimizer_cases.c.h generated
|
||||
Python/opcode_targets.h generated
|
||||
Python/record_functions.c.h generated
|
||||
Python/stdlib_module_names.h generated
|
||||
Tools/peg_generator/pegen/grammar_parser.py generated
|
||||
aclocal.m4 generated
|
||||
|
||||
+67
-65
@@ -1050,6 +1050,7 @@ enum InstructionFormat {
|
||||
#define HAS_PERIODIC_FLAG (32768)
|
||||
#define HAS_UNPREDICTABLE_JUMP_FLAG (65536)
|
||||
#define HAS_NEEDS_GUARD_IP_FLAG (131072)
|
||||
#define HAS_RECORDS_VALUE_FLAG (262144)
|
||||
#define OPCODE_HAS_ARG(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ARG_FLAG))
|
||||
#define OPCODE_HAS_CONST(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_CONST_FLAG))
|
||||
#define OPCODE_HAS_NAME(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_NAME_FLAG))
|
||||
@@ -1068,6 +1069,7 @@ enum InstructionFormat {
|
||||
#define OPCODE_HAS_PERIODIC(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_PERIODIC_FLAG))
|
||||
#define OPCODE_HAS_UNPREDICTABLE_JUMP(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_UNPREDICTABLE_JUMP_FLAG))
|
||||
#define OPCODE_HAS_NEEDS_GUARD_IP(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_NEEDS_GUARD_IP_FLAG))
|
||||
#define OPCODE_HAS_RECORDS_VALUE(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_RECORDS_VALUE_FLAG))
|
||||
|
||||
#define OPARG_SIMPLE 0
|
||||
#define OPARG_CACHE_1 1
|
||||
@@ -1099,7 +1101,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
|
||||
[BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG },
|
||||
[BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG },
|
||||
[BINARY_OP_SUBSCR_DICT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||
[BINARY_OP_SUBSCR_GETITEM] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
|
||||
[BINARY_OP_SUBSCR_GETITEM] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[BINARY_OP_SUBSCR_LIST_INT] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
|
||||
[BINARY_OP_SUBSCR_LIST_SLICE] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[BINARY_OP_SUBSCR_STR_INT] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
|
||||
@@ -1118,15 +1120,15 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
|
||||
[BUILD_TUPLE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG },
|
||||
[CACHE] = { true, INSTR_FMT_IX, 0 },
|
||||
[CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
|
||||
[CALL_ALLOC_AND_ENTER_INIT] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
|
||||
[CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
|
||||
[CALL_BOUND_METHOD_GENERAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
|
||||
[CALL_BUILTIN_CLASS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_BUILTIN_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_BUILTIN_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_ALLOC_AND_ENTER_INIT] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[CALL_BOUND_METHOD_GENERAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[CALL_BUILTIN_CLASS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[CALL_BUILTIN_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[CALL_BUILTIN_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[CALL_EX_NON_PY_GENERAL] = { true, INSTR_FMT_IXC, HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_EX_PY] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
|
||||
[CALL_EX_PY] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[CALL_FUNCTION_EX] = { true, INSTR_FMT_IXC, HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
|
||||
[CALL_INTRINSIC_1] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_INTRINSIC_2] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
@@ -1138,12 +1140,12 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
|
||||
[CALL_LEN] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_LIST_APPEND] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_METHOD_DESCRIPTOR_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_METHOD_DESCRIPTOR_NOARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_METHOD_DESCRIPTOR_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_NON_PY_GENERAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
|
||||
[CALL_PY_GENERAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
|
||||
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[CALL_METHOD_DESCRIPTOR_NOARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[CALL_METHOD_DESCRIPTOR_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[CALL_NON_PY_GENERAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[CALL_PY_GENERAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[CALL_STR_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_TUPLE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_TYPE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
||||
@@ -1177,7 +1179,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
|
||||
[FORMAT_SIMPLE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[FORMAT_WITH_SPEC] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG },
|
||||
[FOR_ITER_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
|
||||
[FOR_ITER_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[FOR_ITER_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG },
|
||||
[FOR_ITER_RANGE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG },
|
||||
[FOR_ITER_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EXIT_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG },
|
||||
@@ -1221,18 +1223,18 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
|
||||
[LIST_EXTEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[LOAD_ATTR] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[LOAD_ATTR_CLASS] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
|
||||
[LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
|
||||
[LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
|
||||
[LOAD_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
|
||||
[LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
|
||||
[LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG },
|
||||
[LOAD_ATTR_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
|
||||
[LOAD_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[LOAD_ATTR_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[LOAD_ATTR_MODULE] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
||||
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
|
||||
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
|
||||
[LOAD_ATTR_PROPERTY] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
|
||||
[LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
|
||||
[LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
|
||||
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[LOAD_ATTR_PROPERTY] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[LOAD_BUILD_CLASS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[LOAD_COMMON_CONSTANT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
||||
[LOAD_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG },
|
||||
@@ -1278,8 +1280,8 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
|
||||
[RESERVED] = { true, INSTR_FMT_IX, 0 },
|
||||
[RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||
[RESUME_CHECK] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
||||
[RETURN_GENERATOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
|
||||
[RETURN_VALUE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
|
||||
[RETURN_GENERATOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[RETURN_VALUE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[SEND] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
|
||||
[SEND_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
|
||||
[SETUP_ANNOTATIONS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
@@ -1288,8 +1290,8 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
|
||||
[SET_UPDATE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[STORE_ATTR] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[STORE_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IXC000, HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
|
||||
[STORE_ATTR_SLOT] = { true, INSTR_FMT_IXC000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
|
||||
[STORE_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
|
||||
[STORE_ATTR_SLOT] = { true, INSTR_FMT_IXC000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[STORE_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[STORE_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ESCAPES_FLAG },
|
||||
[STORE_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ESCAPES_FLAG },
|
||||
[STORE_FAST_LOAD_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ESCAPES_FLAG },
|
||||
@@ -1302,7 +1304,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
|
||||
[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 },
|
||||
[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_ALWAYS_TRUE] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[TO_BOOL_BOOL] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG },
|
||||
[TO_BOOL_INT] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG },
|
||||
[TO_BOOL_LIST] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
|
||||
@@ -1318,7 +1320,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
|
||||
[UNPACK_SEQUENCE_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
|
||||
[UNPACK_SEQUENCE_TWO_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
|
||||
[WITH_EXCEPT_START] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
|
||||
[YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG },
|
||||
[ANNOTATIONS_PLACEHOLDER] = { true, -1, HAS_PURE_FLAG },
|
||||
[JUMP] = { true, -1, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[JUMP_IF_FALSE] = { true, -1, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
@@ -1333,7 +1335,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#define MAX_UOP_PER_EXPANSION 10
|
||||
#define MAX_UOP_PER_EXPANSION 11
|
||||
struct opcode_macro_expansion {
|
||||
int nuops;
|
||||
struct { int16_t uop; int8_t size; int8_t offset; } uops[MAX_UOP_PER_EXPANSION];
|
||||
@@ -1352,7 +1354,7 @@ _PyOpcode_macro_expansion[256] = {
|
||||
[BINARY_OP_MULTIPLY_FLOAT] = { .nuops = 5, .uops = { { _GUARD_TOS_FLOAT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_FLOAT, OPARG_SIMPLE, 0 }, { _BINARY_OP_MULTIPLY_FLOAT, OPARG_SIMPLE, 5 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 5 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 5 } } },
|
||||
[BINARY_OP_MULTIPLY_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _BINARY_OP_MULTIPLY_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 } } },
|
||||
[BINARY_OP_SUBSCR_DICT] = { .nuops = 4, .uops = { { _GUARD_NOS_DICT, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_DICT, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 } } },
|
||||
[BINARY_OP_SUBSCR_GETITEM] = { .nuops = 4, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 5 }, { _BINARY_OP_SUBSCR_CHECK_FUNC, OPARG_SIMPLE, 5 }, { _BINARY_OP_SUBSCR_INIT_CALL, OPARG_SIMPLE, 5 }, { _PUSH_FRAME, OPARG_SIMPLE, 5 } } },
|
||||
[BINARY_OP_SUBSCR_GETITEM] = { .nuops = 5, .uops = { { _RECORD_TOS, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 5 }, { _BINARY_OP_SUBSCR_CHECK_FUNC, OPARG_SIMPLE, 5 }, { _BINARY_OP_SUBSCR_INIT_CALL, OPARG_SIMPLE, 5 }, { _PUSH_FRAME, OPARG_SIMPLE, 5 } } },
|
||||
[BINARY_OP_SUBSCR_LIST_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_LIST_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP, OPARG_SIMPLE, 5 } } },
|
||||
[BINARY_OP_SUBSCR_LIST_SLICE] = { .nuops = 3, .uops = { { _GUARD_TOS_SLICE, OPARG_SIMPLE, 0 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_LIST_SLICE, OPARG_SIMPLE, 5 } } },
|
||||
[BINARY_OP_SUBSCR_STR_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_COMPACT_ASCII, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_STR_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_UNICODE, OPARG_SIMPLE, 5 } } },
|
||||
@@ -1369,15 +1371,15 @@ _PyOpcode_macro_expansion[256] = {
|
||||
[BUILD_STRING] = { .nuops = 1, .uops = { { _BUILD_STRING, OPARG_SIMPLE, 0 } } },
|
||||
[BUILD_TEMPLATE] = { .nuops = 1, .uops = { { _BUILD_TEMPLATE, OPARG_SIMPLE, 0 } } },
|
||||
[BUILD_TUPLE] = { .nuops = 1, .uops = { { _BUILD_TUPLE, OPARG_SIMPLE, 0 } } },
|
||||
[CALL_ALLOC_AND_ENTER_INIT] = { .nuops = 4, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_AND_ALLOCATE_OBJECT, 2, 1 }, { _CREATE_INIT_FRAME, OPARG_SIMPLE, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } },
|
||||
[CALL_BOUND_METHOD_EXACT_ARGS] = { .nuops = 10, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_CALL_BOUND_METHOD_EXACT_ARGS, OPARG_SIMPLE, 1 }, { _INIT_CALL_BOUND_METHOD_EXACT_ARGS, OPARG_SIMPLE, 1 }, { _CHECK_FUNCTION_VERSION, 2, 1 }, { _CHECK_FUNCTION_EXACT_ARGS, OPARG_SIMPLE, 3 }, { _CHECK_STACK_SPACE, OPARG_SIMPLE, 3 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _INIT_CALL_PY_EXACT_ARGS, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } },
|
||||
[CALL_BOUND_METHOD_GENERAL] = { .nuops = 7, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_METHOD_VERSION, 2, 1 }, { _EXPAND_METHOD, OPARG_SIMPLE, 3 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _PY_FRAME_GENERAL, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } },
|
||||
[CALL_BUILTIN_CLASS] = { .nuops = 2, .uops = { { _CALL_BUILTIN_CLASS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
|
||||
[CALL_BUILTIN_FAST] = { .nuops = 2, .uops = { { _CALL_BUILTIN_FAST, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
|
||||
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = { .nuops = 2, .uops = { { _CALL_BUILTIN_FAST_WITH_KEYWORDS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
|
||||
[CALL_BUILTIN_O] = { .nuops = 4, .uops = { { _CALL_BUILTIN_O, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
|
||||
[CALL_ALLOC_AND_ENTER_INIT] = { .nuops = 5, .uops = { { _RECORD_CALLABLE, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_AND_ALLOCATE_OBJECT, 2, 1 }, { _CREATE_INIT_FRAME, OPARG_SIMPLE, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } },
|
||||
[CALL_BOUND_METHOD_EXACT_ARGS] = { .nuops = 11, .uops = { { _RECORD_BOUND_METHOD, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_CALL_BOUND_METHOD_EXACT_ARGS, OPARG_SIMPLE, 1 }, { _INIT_CALL_BOUND_METHOD_EXACT_ARGS, OPARG_SIMPLE, 1 }, { _CHECK_FUNCTION_VERSION, 2, 1 }, { _CHECK_FUNCTION_EXACT_ARGS, OPARG_SIMPLE, 3 }, { _CHECK_STACK_SPACE, OPARG_SIMPLE, 3 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _INIT_CALL_PY_EXACT_ARGS, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } },
|
||||
[CALL_BOUND_METHOD_GENERAL] = { .nuops = 8, .uops = { { _RECORD_BOUND_METHOD, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_METHOD_VERSION, 2, 1 }, { _EXPAND_METHOD, OPARG_SIMPLE, 3 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _PY_FRAME_GENERAL, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } },
|
||||
[CALL_BUILTIN_CLASS] = { .nuops = 3, .uops = { { _RECORD_CALLABLE, OPARG_SIMPLE, 0 }, { _CALL_BUILTIN_CLASS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
|
||||
[CALL_BUILTIN_FAST] = { .nuops = 3, .uops = { { _RECORD_CALLABLE, OPARG_SIMPLE, 0 }, { _CALL_BUILTIN_FAST, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
|
||||
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = { .nuops = 3, .uops = { { _RECORD_CALLABLE, OPARG_SIMPLE, 0 }, { _CALL_BUILTIN_FAST_WITH_KEYWORDS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
|
||||
[CALL_BUILTIN_O] = { .nuops = 5, .uops = { { _RECORD_CALLABLE, OPARG_SIMPLE, 0 }, { _CALL_BUILTIN_O, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
|
||||
[CALL_EX_NON_PY_GENERAL] = { .nuops = 4, .uops = { { _CHECK_IS_NOT_PY_CALLABLE_EX, OPARG_SIMPLE, 1 }, { _MAKE_CALLARGS_A_TUPLE, OPARG_SIMPLE, 1 }, { _CALL_FUNCTION_EX_NON_PY_GENERAL, OPARG_SIMPLE, 1 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 1 } } },
|
||||
[CALL_EX_PY] = { .nuops = 6, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _MAKE_CALLARGS_A_TUPLE, OPARG_SIMPLE, 1 }, { _CHECK_IS_PY_CALLABLE_EX, OPARG_SIMPLE, 1 }, { _PY_FRAME_EX, OPARG_SIMPLE, 1 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 1 }, { _PUSH_FRAME, OPARG_SIMPLE, 1 } } },
|
||||
[CALL_EX_PY] = { .nuops = 7, .uops = { { _RECORD_4OS, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _MAKE_CALLARGS_A_TUPLE, OPARG_SIMPLE, 1 }, { _CHECK_IS_PY_CALLABLE_EX, OPARG_SIMPLE, 1 }, { _PY_FRAME_EX, OPARG_SIMPLE, 1 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 1 }, { _PUSH_FRAME, OPARG_SIMPLE, 1 } } },
|
||||
[CALL_INTRINSIC_1] = { .nuops = 1, .uops = { { _CALL_INTRINSIC_1, OPARG_SIMPLE, 0 } } },
|
||||
[CALL_INTRINSIC_2] = { .nuops = 1, .uops = { { _CALL_INTRINSIC_2, OPARG_SIMPLE, 0 } } },
|
||||
[CALL_ISINSTANCE] = { .nuops = 3, .uops = { { _GUARD_THIRD_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_ISINSTANCE, OPARG_SIMPLE, 3 }, { _CALL_ISINSTANCE, OPARG_SIMPLE, 3 } } },
|
||||
@@ -1387,12 +1389,12 @@ _PyOpcode_macro_expansion[256] = {
|
||||
[CALL_LEN] = { .nuops = 5, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_LEN, OPARG_SIMPLE, 3 }, { _CALL_LEN, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 } } },
|
||||
[CALL_LIST_APPEND] = { .nuops = 6, .uops = { { _GUARD_CALLABLE_LIST_APPEND, OPARG_SIMPLE, 3 }, { _GUARD_NOS_NOT_NULL, OPARG_SIMPLE, 3 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 3 }, { _CALL_LIST_APPEND, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 } } },
|
||||
[CALL_METHOD_DESCRIPTOR_FAST] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_FAST, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
|
||||
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
|
||||
[CALL_METHOD_DESCRIPTOR_NOARGS] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_NOARGS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
|
||||
[CALL_METHOD_DESCRIPTOR_O] = { .nuops = 5, .uops = { { _CALL_METHOD_DESCRIPTOR_O, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
|
||||
[CALL_NON_PY_GENERAL] = { .nuops = 3, .uops = { { _CHECK_IS_NOT_PY_CALLABLE, OPARG_SIMPLE, 3 }, { _CALL_NON_PY_GENERAL, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
|
||||
[CALL_PY_EXACT_ARGS] = { .nuops = 8, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_FUNCTION_VERSION, 2, 1 }, { _CHECK_FUNCTION_EXACT_ARGS, OPARG_SIMPLE, 3 }, { _CHECK_STACK_SPACE, OPARG_SIMPLE, 3 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _INIT_CALL_PY_EXACT_ARGS, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } },
|
||||
[CALL_PY_GENERAL] = { .nuops = 6, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_FUNCTION_VERSION, 2, 1 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _PY_FRAME_GENERAL, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } },
|
||||
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { .nuops = 3, .uops = { { _RECORD_CALLABLE, OPARG_SIMPLE, 0 }, { _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
|
||||
[CALL_METHOD_DESCRIPTOR_NOARGS] = { .nuops = 3, .uops = { { _RECORD_CALLABLE, OPARG_SIMPLE, 0 }, { _CALL_METHOD_DESCRIPTOR_NOARGS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
|
||||
[CALL_METHOD_DESCRIPTOR_O] = { .nuops = 6, .uops = { { _RECORD_CALLABLE, OPARG_SIMPLE, 0 }, { _CALL_METHOD_DESCRIPTOR_O, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
|
||||
[CALL_NON_PY_GENERAL] = { .nuops = 4, .uops = { { _RECORD_CALLABLE, OPARG_SIMPLE, 0 }, { _CHECK_IS_NOT_PY_CALLABLE, OPARG_SIMPLE, 3 }, { _CALL_NON_PY_GENERAL, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
|
||||
[CALL_PY_EXACT_ARGS] = { .nuops = 9, .uops = { { _RECORD_CALLABLE, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_FUNCTION_VERSION, 2, 1 }, { _CHECK_FUNCTION_EXACT_ARGS, OPARG_SIMPLE, 3 }, { _CHECK_STACK_SPACE, OPARG_SIMPLE, 3 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _INIT_CALL_PY_EXACT_ARGS, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } },
|
||||
[CALL_PY_GENERAL] = { .nuops = 7, .uops = { { _RECORD_CALLABLE, OPARG_SIMPLE, 0 }, { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_FUNCTION_VERSION, 2, 1 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _PY_FRAME_GENERAL, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } },
|
||||
[CALL_STR_1] = { .nuops = 5, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_STR_1, OPARG_SIMPLE, 3 }, { _CALL_STR_1, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
|
||||
[CALL_TUPLE_1] = { .nuops = 5, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_TUPLE_1, OPARG_SIMPLE, 3 }, { _CALL_TUPLE_1, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } },
|
||||
[CALL_TYPE_1] = { .nuops = 4, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_TYPE_1, OPARG_SIMPLE, 3 }, { _CALL_TYPE_1, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 } } },
|
||||
@@ -1422,7 +1424,7 @@ _PyOpcode_macro_expansion[256] = {
|
||||
[FORMAT_SIMPLE] = { .nuops = 1, .uops = { { _FORMAT_SIMPLE, OPARG_SIMPLE, 0 } } },
|
||||
[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_GEN] = { .nuops = 4, .uops = { { _RECORD_NOS, OPARG_SIMPLE, 0 }, { _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_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 } } },
|
||||
@@ -1442,17 +1444,17 @@ _PyOpcode_macro_expansion[256] = {
|
||||
[LIST_EXTEND] = { .nuops = 1, .uops = { { _LIST_EXTEND, OPARG_SIMPLE, 0 } } },
|
||||
[LOAD_ATTR] = { .nuops = 1, .uops = { { _LOAD_ATTR, OPARG_SIMPLE, 8 } } },
|
||||
[LOAD_ATTR_CLASS] = { .nuops = 3, .uops = { { _CHECK_ATTR_CLASS, 2, 1 }, { _LOAD_ATTR_CLASS, 4, 5 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
|
||||
[LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = { .nuops = 4, .uops = { { _CHECK_ATTR_CLASS, 2, 1 }, { _GUARD_TYPE_VERSION, 2, 3 }, { _LOAD_ATTR_CLASS, 4, 5 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
|
||||
[LOAD_ATTR_INSTANCE_VALUE] = { .nuops = 5, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_MANAGED_OBJECT_HAS_VALUES, OPARG_SIMPLE, 3 }, { _LOAD_ATTR_INSTANCE_VALUE, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
|
||||
[LOAD_ATTR_METHOD_LAZY_DICT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_METHOD_LAZY_DICT, 1, 3 }, { _LOAD_ATTR_METHOD_LAZY_DICT, 4, 5 } } },
|
||||
[LOAD_ATTR_METHOD_NO_DICT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_METHOD_NO_DICT, 4, 5 } } },
|
||||
[LOAD_ATTR_METHOD_WITH_VALUES] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, OPARG_SIMPLE, 3 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_METHOD_WITH_VALUES, 4, 5 } } },
|
||||
[LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = { .nuops = 5, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_CLASS, 2, 3 }, { _LOAD_ATTR_CLASS, 4, 5 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
|
||||
[LOAD_ATTR_INSTANCE_VALUE] = { .nuops = 6, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_MANAGED_OBJECT_HAS_VALUES, OPARG_SIMPLE, 3 }, { _LOAD_ATTR_INSTANCE_VALUE, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
|
||||
[LOAD_ATTR_METHOD_LAZY_DICT] = { .nuops = 4, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_METHOD_LAZY_DICT, 1, 3 }, { _LOAD_ATTR_METHOD_LAZY_DICT, 4, 5 } } },
|
||||
[LOAD_ATTR_METHOD_NO_DICT] = { .nuops = 3, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_METHOD_NO_DICT, 4, 5 } } },
|
||||
[LOAD_ATTR_METHOD_WITH_VALUES] = { .nuops = 5, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, OPARG_SIMPLE, 3 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_METHOD_WITH_VALUES, 4, 5 } } },
|
||||
[LOAD_ATTR_MODULE] = { .nuops = 4, .uops = { { _LOAD_ATTR_MODULE, 2, 1 }, { _LOAD_ATTR_MODULE, OPERAND1_1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
|
||||
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_NONDESCRIPTOR_NO_DICT, 4, 5 } } },
|
||||
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, OPARG_SIMPLE, 3 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, 4, 5 } } },
|
||||
[LOAD_ATTR_PROPERTY] = { .nuops = 5, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_PROPERTY_FRAME, 4, 5 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 9 }, { _PUSH_FRAME, OPARG_SIMPLE, 9 } } },
|
||||
[LOAD_ATTR_SLOT] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_SLOT, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
|
||||
[LOAD_ATTR_WITH_HINT] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_WITH_HINT, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
|
||||
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { .nuops = 3, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_NONDESCRIPTOR_NO_DICT, 4, 5 } } },
|
||||
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { .nuops = 5, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, OPARG_SIMPLE, 3 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, 4, 5 } } },
|
||||
[LOAD_ATTR_PROPERTY] = { .nuops = 6, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_PEP_523, OPARG_SIMPLE, 3 }, { _LOAD_ATTR_PROPERTY_FRAME, 4, 5 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 9 }, { _PUSH_FRAME, OPARG_SIMPLE, 9 } } },
|
||||
[LOAD_ATTR_SLOT] = { .nuops = 5, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_SLOT, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
|
||||
[LOAD_ATTR_WITH_HINT] = { .nuops = 5, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_WITH_HINT, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } },
|
||||
[LOAD_BUILD_CLASS] = { .nuops = 1, .uops = { { _LOAD_BUILD_CLASS, OPARG_SIMPLE, 0 } } },
|
||||
[LOAD_COMMON_CONSTANT] = { .nuops = 1, .uops = { { _LOAD_COMMON_CONSTANT, OPARG_SIMPLE, 0 } } },
|
||||
[LOAD_CONST] = { .nuops = 1, .uops = { { _LOAD_CONST, OPARG_SIMPLE, 0 } } },
|
||||
@@ -1492,8 +1494,8 @@ _PyOpcode_macro_expansion[256] = {
|
||||
[PUSH_EXC_INFO] = { .nuops = 1, .uops = { { _PUSH_EXC_INFO, OPARG_SIMPLE, 0 } } },
|
||||
[PUSH_NULL] = { .nuops = 1, .uops = { { _PUSH_NULL, OPARG_SIMPLE, 0 } } },
|
||||
[RESUME_CHECK] = { .nuops = 1, .uops = { { _RESUME_CHECK, OPARG_SIMPLE, 0 } } },
|
||||
[RETURN_GENERATOR] = { .nuops = 1, .uops = { { _RETURN_GENERATOR, OPARG_SIMPLE, 0 } } },
|
||||
[RETURN_VALUE] = { .nuops = 1, .uops = { { _RETURN_VALUE, OPARG_SIMPLE, 0 } } },
|
||||
[RETURN_GENERATOR] = { .nuops = 2, .uops = { { _RECORD_CALLER_CODE, OPARG_SIMPLE, 0 }, { _RETURN_GENERATOR, OPARG_SIMPLE, 0 } } },
|
||||
[RETURN_VALUE] = { .nuops = 2, .uops = { { _RECORD_CALLER_CODE, OPARG_SIMPLE, 0 }, { _RETURN_VALUE, OPARG_SIMPLE, 0 } } },
|
||||
[SEND_GEN] = { .nuops = 3, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _SEND_GEN_FRAME, OPARG_SIMPLE, 1 }, { _PUSH_FRAME, OPARG_SIMPLE, 1 } } },
|
||||
[SETUP_ANNOTATIONS] = { .nuops = 1, .uops = { { _SETUP_ANNOTATIONS, OPARG_SIMPLE, 0 } } },
|
||||
[SET_ADD] = { .nuops = 1, .uops = { { _SET_ADD, OPARG_SIMPLE, 0 } } },
|
||||
@@ -1501,8 +1503,8 @@ _PyOpcode_macro_expansion[256] = {
|
||||
[SET_UPDATE] = { .nuops = 1, .uops = { { _SET_UPDATE, OPARG_SIMPLE, 0 } } },
|
||||
[STORE_ATTR] = { .nuops = 1, .uops = { { _STORE_ATTR, OPARG_SIMPLE, 3 } } },
|
||||
[STORE_ATTR_INSTANCE_VALUE] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION_AND_LOCK, 2, 1 }, { _GUARD_DORV_NO_DICT, OPARG_SIMPLE, 3 }, { _STORE_ATTR_INSTANCE_VALUE, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 } } },
|
||||
[STORE_ATTR_SLOT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _STORE_ATTR_SLOT, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 } } },
|
||||
[STORE_ATTR_WITH_HINT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _STORE_ATTR_WITH_HINT, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 } } },
|
||||
[STORE_ATTR_SLOT] = { .nuops = 4, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _STORE_ATTR_SLOT, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 } } },
|
||||
[STORE_ATTR_WITH_HINT] = { .nuops = 4, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _STORE_ATTR_WITH_HINT, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 } } },
|
||||
[STORE_DEREF] = { .nuops = 1, .uops = { { _STORE_DEREF, OPARG_SIMPLE, 0 } } },
|
||||
[STORE_FAST] = { .nuops = 2, .uops = { { _SWAP_FAST, OPARG_SIMPLE, 0 }, { _POP_TOP, OPARG_SIMPLE, 0 } } },
|
||||
[STORE_FAST_LOAD_FAST] = { .nuops = 3, .uops = { { _SWAP_FAST, OPARG_TOP, 0 }, { _POP_TOP, OPARG_TOP, 0 }, { _LOAD_FAST, OPARG_BOTTOM, 0 } } },
|
||||
@@ -1515,7 +1517,7 @@ _PyOpcode_macro_expansion[256] = {
|
||||
[STORE_SUBSCR_LIST_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 0 }, { _STORE_SUBSCR_LIST_INT, OPARG_SIMPLE, 1 }, { _POP_TOP_INT, OPARG_SIMPLE, 1 }, { _POP_TOP, OPARG_SIMPLE, 1 } } },
|
||||
[SWAP] = { .nuops = 1, .uops = { { _SWAP, OPARG_SIMPLE, 0 } } },
|
||||
[TO_BOOL] = { .nuops = 1, .uops = { { _TO_BOOL, OPARG_SIMPLE, 2 } } },
|
||||
[TO_BOOL_ALWAYS_TRUE] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _REPLACE_WITH_TRUE, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 } } },
|
||||
[TO_BOOL_ALWAYS_TRUE] = { .nuops = 4, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _REPLACE_WITH_TRUE, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 } } },
|
||||
[TO_BOOL_BOOL] = { .nuops = 1, .uops = { { _TO_BOOL_BOOL, OPARG_SIMPLE, 3 } } },
|
||||
[TO_BOOL_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _TO_BOOL_INT, OPARG_SIMPLE, 3 }, { _POP_TOP_INT, OPARG_SIMPLE, 3 } } },
|
||||
[TO_BOOL_LIST] = { .nuops = 3, .uops = { { _GUARD_TOS_LIST, OPARG_SIMPLE, 0 }, { _TO_BOOL_LIST, OPARG_SIMPLE, 3 }, { _POP_TOP, OPARG_SIMPLE, 3 } } },
|
||||
@@ -1530,7 +1532,7 @@ _PyOpcode_macro_expansion[256] = {
|
||||
[UNPACK_SEQUENCE_TUPLE] = { .nuops = 2, .uops = { { _GUARD_TOS_TUPLE, OPARG_SIMPLE, 0 }, { _UNPACK_SEQUENCE_TUPLE, OPARG_SIMPLE, 1 } } },
|
||||
[UNPACK_SEQUENCE_TWO_TUPLE] = { .nuops = 2, .uops = { { _GUARD_TOS_TUPLE, OPARG_SIMPLE, 0 }, { _UNPACK_SEQUENCE_TWO_TUPLE, OPARG_SIMPLE, 1 } } },
|
||||
[WITH_EXCEPT_START] = { .nuops = 1, .uops = { { _WITH_EXCEPT_START, OPARG_SIMPLE, 0 } } },
|
||||
[YIELD_VALUE] = { .nuops = 1, .uops = { { _YIELD_VALUE, OPARG_SIMPLE, 0 } } },
|
||||
[YIELD_VALUE] = { .nuops = 2, .uops = { { _RECORD_CALLER_CODE, OPARG_SIMPLE, 0 }, { _YIELD_VALUE, OPARG_SIMPLE, 0 } } },
|
||||
};
|
||||
#endif // NEED_OPCODE_METADATA
|
||||
|
||||
|
||||
@@ -90,6 +90,7 @@ typedef struct _PyJitTracerPreviousState {
|
||||
PyCodeObject *instr_code; // Strong
|
||||
struct _PyInterpreterFrame *instr_frame;
|
||||
_PyBloomFilter dependencies;
|
||||
PyObject *recorded_value; // Strong, may be NULL
|
||||
} _PyJitTracerPreviousState;
|
||||
|
||||
typedef struct _PyJitTracerTranslatorState {
|
||||
@@ -336,7 +337,7 @@ PyAPI_FUNC(int) _PyJit_translate_single_bytecode_to_trace(PyThreadState *tstate,
|
||||
PyAPI_FUNC(int)
|
||||
_PyJit_TryInitializeTracing(PyThreadState *tstate, _PyInterpreterFrame *frame,
|
||||
_Py_CODEUNIT *curr_instr, _Py_CODEUNIT *start_instr,
|
||||
_Py_CODEUNIT *close_loop_instr, int curr_stackdepth, int chain_depth, _PyExitData *exit,
|
||||
_Py_CODEUNIT *close_loop_instr, _PyStackRef *stack_pointer, int chain_depth, _PyExitData *exit,
|
||||
int oparg, _PyExecutorObject *current_executor);
|
||||
|
||||
PyAPI_FUNC(void) _PyJit_FinalizeTracing(PyThreadState *tstate, int err);
|
||||
@@ -344,6 +345,12 @@ void _PyJit_TracerFree(_PyThreadStateImpl *_tstate);
|
||||
|
||||
void _PyJit_Tracer_InvalidateDependency(PyThreadState *old_tstate, void *obj);
|
||||
|
||||
#ifdef _Py_TIER2
|
||||
typedef void (*_Py_RecordFuncPtr)(_PyInterpreterFrame *frame, _PyStackRef *stackpointer, int oparg, PyObject **recorded_value);
|
||||
PyAPI_DATA(const _Py_RecordFuncPtr) _PyOpcode_RecordFunctions[];
|
||||
PyAPI_DATA(const uint8_t) _PyOpcode_RecordFunctionIndices[256];
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Generated
+909
-902
File diff suppressed because it is too large.
Load diff
Generated
+28
@@ -374,6 +374,13 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = {
|
||||
[_GUARD_IP_YIELD_VALUE] = HAS_EXIT_FLAG,
|
||||
[_GUARD_IP_RETURN_VALUE] = HAS_EXIT_FLAG,
|
||||
[_GUARD_IP_RETURN_GENERATOR] = HAS_EXIT_FLAG,
|
||||
[_RECORD_TOS] = HAS_RECORDS_VALUE_FLAG,
|
||||
[_RECORD_TOS_TYPE] = HAS_RECORDS_VALUE_FLAG,
|
||||
[_RECORD_NOS] = HAS_RECORDS_VALUE_FLAG,
|
||||
[_RECORD_4OS] = HAS_RECORDS_VALUE_FLAG,
|
||||
[_RECORD_CALLABLE] = HAS_ARG_FLAG | HAS_RECORDS_VALUE_FLAG,
|
||||
[_RECORD_BOUND_METHOD] = HAS_ARG_FLAG | HAS_RECORDS_VALUE_FLAG,
|
||||
[_RECORD_CALLER_CODE] = HAS_RECORDS_VALUE_FLAG,
|
||||
};
|
||||
|
||||
const ReplicationRange _PyUop_Replication[MAX_UOP_ID+1] = {
|
||||
@@ -5169,6 +5176,13 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
|
||||
[_PY_FRAME_GENERAL_r01] = "_PY_FRAME_GENERAL_r01",
|
||||
[_PY_FRAME_KW] = "_PY_FRAME_KW",
|
||||
[_PY_FRAME_KW_r11] = "_PY_FRAME_KW_r11",
|
||||
[_RECORD_4OS] = "_RECORD_4OS",
|
||||
[_RECORD_BOUND_METHOD] = "_RECORD_BOUND_METHOD",
|
||||
[_RECORD_CALLABLE] = "_RECORD_CALLABLE",
|
||||
[_RECORD_CALLER_CODE] = "_RECORD_CALLER_CODE",
|
||||
[_RECORD_NOS] = "_RECORD_NOS",
|
||||
[_RECORD_TOS] = "_RECORD_TOS",
|
||||
[_RECORD_TOS_TYPE] = "_RECORD_TOS_TYPE",
|
||||
[_REPLACE_WITH_TRUE] = "_REPLACE_WITH_TRUE",
|
||||
[_REPLACE_WITH_TRUE_r02] = "_REPLACE_WITH_TRUE_r02",
|
||||
[_REPLACE_WITH_TRUE_r12] = "_REPLACE_WITH_TRUE_r12",
|
||||
@@ -6043,6 +6057,20 @@ int _PyUop_num_popped(int opcode, int oparg)
|
||||
return 0;
|
||||
case _GUARD_IP_RETURN_GENERATOR:
|
||||
return 0;
|
||||
case _RECORD_TOS:
|
||||
return 0;
|
||||
case _RECORD_TOS_TYPE:
|
||||
return 0;
|
||||
case _RECORD_NOS:
|
||||
return 0;
|
||||
case _RECORD_4OS:
|
||||
return 0;
|
||||
case _RECORD_CALLABLE:
|
||||
return 0;
|
||||
case _RECORD_BOUND_METHOD:
|
||||
return 0;
|
||||
case _RECORD_CALLER_CODE:
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
+9
-2
@@ -2149,7 +2149,7 @@ Objects/mimalloc/page.o: $(srcdir)/Objects/mimalloc/page-queue.c
|
||||
.PHONY: regen-cases
|
||||
regen-cases: \
|
||||
regen-opcode-ids regen-opcode-targets regen-uop-ids regen-opcode-metadata-py \
|
||||
regen-generated-cases regen-executor-cases regen-optimizer-cases \
|
||||
regen-generated-cases regen-executor-cases regen-optimizer-cases regen-record-functions \
|
||||
regen-opcode-metadata regen-uop-metadata regen-test-cases regen-test-opcode-targets
|
||||
|
||||
.PHONY: regen-opcode-ids
|
||||
@@ -2182,6 +2182,12 @@ regen-generated-cases:
|
||||
-o $(srcdir)/Python/generated_cases.c.h.new $(srcdir)/Python/bytecodes.c
|
||||
$(UPDATE_FILE) $(srcdir)/Python/generated_cases.c.h $(srcdir)/Python/generated_cases.c.h.new
|
||||
|
||||
.PHONY: regen-record-functions
|
||||
regen-record-functions:
|
||||
$(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/record_function_generator.py \
|
||||
-o $(srcdir)/Python/record_functions.c.h.new $(srcdir)/Python/bytecodes.c
|
||||
$(UPDATE_FILE) $(srcdir)/Python/record_functions.c.h $(srcdir)/Python/record_functions.c.h.new
|
||||
|
||||
.PHONY: regen-test-cases
|
||||
regen-test-cases:
|
||||
$(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/tier1_generator.py \
|
||||
@@ -2234,7 +2240,8 @@ Python/ceval.o: \
|
||||
$(srcdir)/Python/condvar.h \
|
||||
$(srcdir)/Python/generated_cases.c.h \
|
||||
$(srcdir)/Python/executor_cases.c.h \
|
||||
$(srcdir)/Python/opcode_targets.h
|
||||
$(srcdir)/Python/opcode_targets.h \
|
||||
$(srcdir)/Python/record_functions.c.h
|
||||
|
||||
Python/flowgraph.o: \
|
||||
$(srcdir)/Include/internal/pycore_opcode_metadata.h
|
||||
|
||||
Generated
+105
-88
@@ -7724,7 +7724,7 @@
|
||||
oparg >>= 8;
|
||||
insert_exec_at--;
|
||||
}
|
||||
int succ = _PyJit_TryInitializeTracing(tstate, frame, this_instr, insert_exec_at, next_instr, STACK_LEVEL(), 0, NULL, oparg, NULL);
|
||||
int succ = _PyJit_TryInitializeTracing(tstate, frame, this_instr, insert_exec_at, next_instr, stack_pointer, 0, NULL, oparg, NULL);
|
||||
if (succ) {
|
||||
ENTER_TRACING();
|
||||
}
|
||||
@@ -8018,10 +8018,21 @@
|
||||
_PyStackRef attr;
|
||||
_PyStackRef *null;
|
||||
/* Skip 1 cache entry */
|
||||
// _CHECK_ATTR_CLASS
|
||||
// _GUARD_TYPE_VERSION
|
||||
{
|
||||
owner = stack_pointer[-1];
|
||||
uint32_t type_version = read_u32(&this_instr[2].cache);
|
||||
PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
|
||||
assert(type_version != 0);
|
||||
if (FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version) {
|
||||
UPDATE_MISS_STATS(LOAD_ATTR);
|
||||
assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR));
|
||||
JUMP_TO_PREDICTED(LOAD_ATTR);
|
||||
}
|
||||
}
|
||||
// _CHECK_ATTR_CLASS
|
||||
{
|
||||
uint32_t type_version = read_u32(&this_instr[4].cache);
|
||||
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
|
||||
if (!PyType_Check(owner_o)) {
|
||||
UPDATE_MISS_STATS(LOAD_ATTR);
|
||||
@@ -8035,17 +8046,6 @@
|
||||
JUMP_TO_PREDICTED(LOAD_ATTR);
|
||||
}
|
||||
}
|
||||
// _GUARD_TYPE_VERSION
|
||||
{
|
||||
uint32_t type_version = read_u32(&this_instr[4].cache);
|
||||
PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
|
||||
assert(type_version != 0);
|
||||
if (FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version) {
|
||||
UPDATE_MISS_STATS(LOAD_ATTR);
|
||||
assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR));
|
||||
JUMP_TO_PREDICTED(LOAD_ATTR);
|
||||
}
|
||||
}
|
||||
// _LOAD_ATTR_CLASS
|
||||
{
|
||||
PyObject *descr = read_obj(&this_instr[6].cache);
|
||||
@@ -8595,14 +8595,6 @@
|
||||
_PyStackRef owner;
|
||||
_PyStackRef new_frame;
|
||||
/* Skip 1 cache entry */
|
||||
// _CHECK_PEP_523
|
||||
{
|
||||
if (IS_PEP523_HOOKED(tstate)) {
|
||||
UPDATE_MISS_STATS(LOAD_ATTR);
|
||||
assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR));
|
||||
JUMP_TO_PREDICTED(LOAD_ATTR);
|
||||
}
|
||||
}
|
||||
// _GUARD_TYPE_VERSION
|
||||
{
|
||||
owner = stack_pointer[-1];
|
||||
@@ -8615,6 +8607,14 @@
|
||||
JUMP_TO_PREDICTED(LOAD_ATTR);
|
||||
}
|
||||
}
|
||||
// _CHECK_PEP_523
|
||||
{
|
||||
if (IS_PEP523_HOOKED(tstate)) {
|
||||
UPDATE_MISS_STATS(LOAD_ATTR);
|
||||
assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR));
|
||||
JUMP_TO_PREDICTED(LOAD_ATTR);
|
||||
}
|
||||
}
|
||||
/* Skip 2 cache entries */
|
||||
// _LOAD_ATTR_PROPERTY_FRAME
|
||||
{
|
||||
@@ -10449,30 +10449,33 @@
|
||||
next_instr += 1;
|
||||
INSTRUCTION_STATS(RETURN_GENERATOR);
|
||||
_PyStackRef res;
|
||||
assert(PyStackRef_FunctionCheck(frame->f_funcobj));
|
||||
PyFunctionObject *func = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
if (gen == NULL) {
|
||||
JUMP_TO_LABEL(error);
|
||||
// _RETURN_GENERATOR
|
||||
{
|
||||
assert(PyStackRef_FunctionCheck(frame->f_funcobj));
|
||||
PyFunctionObject *func = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
if (gen == NULL) {
|
||||
JUMP_TO_LABEL(error);
|
||||
}
|
||||
assert(STACK_LEVEL() <= 2);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
_PyInterpreterFrame *gen_frame = &gen->gi_iframe;
|
||||
frame->instr_ptr++;
|
||||
_PyFrame_Copy(frame, gen_frame);
|
||||
assert(frame->frame_obj == NULL);
|
||||
gen->gi_frame_state = FRAME_CREATED;
|
||||
gen_frame->owner = FRAME_OWNED_BY_GENERATOR;
|
||||
_Py_LeaveRecursiveCallPy(tstate);
|
||||
_PyInterpreterFrame *prev = frame->previous;
|
||||
_PyThreadState_PopFrame(tstate, frame);
|
||||
frame = tstate->current_frame = prev;
|
||||
LOAD_IP(frame->return_offset);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
res = PyStackRef_FromPyObjectStealMortal((PyObject *)gen);
|
||||
LLTRACE_RESUME_FRAME();
|
||||
}
|
||||
assert(STACK_LEVEL() <= 2);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
_PyInterpreterFrame *gen_frame = &gen->gi_iframe;
|
||||
frame->instr_ptr++;
|
||||
_PyFrame_Copy(frame, gen_frame);
|
||||
assert(frame->frame_obj == NULL);
|
||||
gen->gi_frame_state = FRAME_CREATED;
|
||||
gen_frame->owner = FRAME_OWNED_BY_GENERATOR;
|
||||
_Py_LeaveRecursiveCallPy(tstate);
|
||||
_PyInterpreterFrame *prev = frame->previous;
|
||||
_PyThreadState_PopFrame(tstate, frame);
|
||||
frame = tstate->current_frame = prev;
|
||||
LOAD_IP(frame->return_offset);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
res = PyStackRef_FromPyObjectStealMortal((PyObject *)gen);
|
||||
LLTRACE_RESUME_FRAME();
|
||||
stack_pointer[0] = res;
|
||||
stack_pointer += 1;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
@@ -10489,21 +10492,24 @@
|
||||
INSTRUCTION_STATS(RETURN_VALUE);
|
||||
_PyStackRef retval;
|
||||
_PyStackRef res;
|
||||
retval = stack_pointer[-1];
|
||||
assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
|
||||
_PyStackRef temp = PyStackRef_MakeHeapSafe(retval);
|
||||
stack_pointer += -1;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
assert(STACK_LEVEL() == 0);
|
||||
_Py_LeaveRecursiveCallPy(tstate);
|
||||
_PyInterpreterFrame *dying = frame;
|
||||
frame = tstate->current_frame = dying->previous;
|
||||
_PyEval_FrameClearAndPop(tstate, dying);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
LOAD_IP(frame->return_offset);
|
||||
res = temp;
|
||||
LLTRACE_RESUME_FRAME();
|
||||
// _RETURN_VALUE
|
||||
{
|
||||
retval = stack_pointer[-1];
|
||||
assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
|
||||
_PyStackRef temp = PyStackRef_MakeHeapSafe(retval);
|
||||
stack_pointer += -1;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
assert(STACK_LEVEL() == 0);
|
||||
_Py_LeaveRecursiveCallPy(tstate);
|
||||
_PyInterpreterFrame *dying = frame;
|
||||
frame = tstate->current_frame = dying->previous;
|
||||
_PyEval_FrameClearAndPop(tstate, dying);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
LOAD_IP(frame->return_offset);
|
||||
res = temp;
|
||||
LLTRACE_RESUME_FRAME();
|
||||
}
|
||||
stack_pointer[0] = res;
|
||||
stack_pointer += 1;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
@@ -11892,6 +11898,9 @@
|
||||
opcode == INTERPRETER_EXIT ||
|
||||
(opcode >= MIN_INSTRUMENTED_OPCODE && opcode != ENTER_EXECUTOR)
|
||||
);
|
||||
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
|
||||
_PyJitTracerState *tracer = _tstate->jit_tracer_state;
|
||||
assert(tracer != NULL);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
int full = !_PyJit_translate_single_bytecode_to_trace(tstate, frame, next_instr, stop_tracing ? _DEOPT : 0);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
@@ -11905,9 +11914,9 @@
|
||||
}
|
||||
DISPATCH();
|
||||
}
|
||||
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
|
||||
_PyJitTracerState *tracer = _tstate->jit_tracer_state;
|
||||
assert(tracer != NULL);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
Py_CLEAR(tracer->prev_state.recorded_value);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
tracer->prev_state.instr = next_instr;
|
||||
PyObject *prev_code = PyStackRef_AsPyObjectBorrow(frame->f_executable);
|
||||
if (tracer->prev_state.instr_code != (PyCodeObject *)prev_code) {
|
||||
@@ -11921,6 +11930,11 @@
|
||||
if (_PyOpcode_Caches[_PyOpcode_Deopt[opcode]]) {
|
||||
(&next_instr[1])->counter = trigger_backoff_counter();
|
||||
}
|
||||
uint8_t record_func_index = _PyOpcode_RecordFunctionIndices[opcode];
|
||||
if (record_func_index) {
|
||||
_Py_RecordFuncPtr doesnt_escape = _PyOpcode_RecordFunctions[record_func_index];
|
||||
doesnt_escape(frame, stack_pointer, oparg, &tracer->prev_state.recorded_value);
|
||||
}
|
||||
DISPATCH_GOTO_NON_TRACING();
|
||||
#else
|
||||
(void)prev_instr;
|
||||
@@ -12312,37 +12326,40 @@
|
||||
INSTRUCTION_STATS(YIELD_VALUE);
|
||||
_PyStackRef retval;
|
||||
_PyStackRef value;
|
||||
retval = stack_pointer[-1];
|
||||
assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
|
||||
frame->instr_ptr++;
|
||||
PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame);
|
||||
assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1);
|
||||
assert(oparg == 0 || oparg == 1);
|
||||
_PyStackRef temp = retval;
|
||||
stack_pointer += -1;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
tstate->exc_info = gen->gi_exc_state.previous_item;
|
||||
gen->gi_exc_state.previous_item = NULL;
|
||||
_Py_LeaveRecursiveCallPy(tstate);
|
||||
_PyInterpreterFrame *gen_frame = frame;
|
||||
frame = tstate->current_frame = frame->previous;
|
||||
gen_frame->previous = NULL;
|
||||
((_PyThreadStateImpl *)tstate)->generator_return_kind = GENERATOR_YIELD;
|
||||
FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_SUSPENDED + oparg);
|
||||
assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER);
|
||||
#if TIER_ONE
|
||||
assert(frame->instr_ptr->op.code == INSTRUMENTED_LINE ||
|
||||
// _YIELD_VALUE
|
||||
{
|
||||
retval = stack_pointer[-1];
|
||||
assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
|
||||
frame->instr_ptr++;
|
||||
PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame);
|
||||
assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1);
|
||||
assert(oparg == 0 || oparg == 1);
|
||||
_PyStackRef temp = retval;
|
||||
stack_pointer += -1;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
tstate->exc_info = gen->gi_exc_state.previous_item;
|
||||
gen->gi_exc_state.previous_item = NULL;
|
||||
_Py_LeaveRecursiveCallPy(tstate);
|
||||
_PyInterpreterFrame *gen_frame = frame;
|
||||
frame = tstate->current_frame = frame->previous;
|
||||
gen_frame->previous = NULL;
|
||||
((_PyThreadStateImpl *)tstate)->generator_return_kind = GENERATOR_YIELD;
|
||||
FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_SUSPENDED + oparg);
|
||||
assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER);
|
||||
#if TIER_ONE
|
||||
assert(frame->instr_ptr->op.code == INSTRUMENTED_LINE ||
|
||||
frame->instr_ptr->op.code == INSTRUMENTED_INSTRUCTION ||
|
||||
_PyOpcode_Deopt[frame->instr_ptr->op.code] == SEND ||
|
||||
_PyOpcode_Deopt[frame->instr_ptr->op.code] == FOR_ITER ||
|
||||
_PyOpcode_Deopt[frame->instr_ptr->op.code] == INTERPRETER_EXIT ||
|
||||
_PyOpcode_Deopt[frame->instr_ptr->op.code] == ENTER_EXECUTOR);
|
||||
#endif
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND);
|
||||
value = PyStackRef_MakeHeapSafe(temp);
|
||||
LLTRACE_RESUME_FRAME();
|
||||
#endif
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND);
|
||||
value = PyStackRef_MakeHeapSafe(temp);
|
||||
LLTRACE_RESUME_FRAME();
|
||||
}
|
||||
stack_pointer[0] = value;
|
||||
stack_pointer += 1;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
|
||||
+108
-24
@@ -568,6 +568,7 @@ dummy_func(
|
||||
|
||||
macro(TO_BOOL_ALWAYS_TRUE) =
|
||||
unused/1 +
|
||||
_RECORD_TOS_TYPE +
|
||||
_GUARD_TYPE_VERSION +
|
||||
_REPLACE_WITH_TRUE +
|
||||
POP_TOP;
|
||||
@@ -1107,6 +1108,7 @@ dummy_func(
|
||||
}
|
||||
|
||||
macro(BINARY_OP_SUBSCR_GETITEM) =
|
||||
_RECORD_TOS +
|
||||
unused/5 + // Skip over the counter and cache
|
||||
_CHECK_PEP_523 +
|
||||
_BINARY_OP_SUBSCR_CHECK_FUNC +
|
||||
@@ -1267,7 +1269,7 @@ dummy_func(
|
||||
// The stack effect here is a bit misleading.
|
||||
// retval is popped from the stack, but res
|
||||
// is pushed to a different frame, the callers' frame.
|
||||
inst(RETURN_VALUE, (retval -- res)) {
|
||||
op(_RETURN_VALUE, (retval -- res)) {
|
||||
assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
|
||||
_PyStackRef temp = PyStackRef_MakeHeapSafe(retval);
|
||||
DEAD(retval);
|
||||
@@ -1291,9 +1293,13 @@ dummy_func(
|
||||
ERROR_IF(err);
|
||||
}
|
||||
|
||||
macro(RETURN_VALUE) =
|
||||
_RECORD_CALLER_CODE +
|
||||
_RETURN_VALUE;
|
||||
|
||||
macro(INSTRUMENTED_RETURN_VALUE) =
|
||||
_RETURN_VALUE_EVENT +
|
||||
RETURN_VALUE;
|
||||
_RETURN_VALUE;
|
||||
|
||||
inst(GET_AITER, (obj -- iter)) {
|
||||
unaryfunc getter = NULL;
|
||||
@@ -1434,7 +1440,7 @@ dummy_func(
|
||||
_SEND_GEN_FRAME +
|
||||
_PUSH_FRAME;
|
||||
|
||||
inst(YIELD_VALUE, (retval -- value)) {
|
||||
op(_YIELD_VALUE, (retval -- value)) {
|
||||
// NOTE: It's important that YIELD_VALUE never raises an exception!
|
||||
// The compiler treats any exception raised here as a failed close()
|
||||
// or throw() call.
|
||||
@@ -1470,6 +1476,10 @@ dummy_func(
|
||||
LLTRACE_RESUME_FRAME();
|
||||
}
|
||||
|
||||
macro(YIELD_VALUE) =
|
||||
_RECORD_CALLER_CODE +
|
||||
_YIELD_VALUE;
|
||||
|
||||
tier1 op(_YIELD_VALUE_EVENT, (val -- val)) {
|
||||
int err = _Py_call_instrumentation_arg(
|
||||
tstate, PY_MONITORING_EVENT_PY_YIELD,
|
||||
@@ -1485,7 +1495,7 @@ dummy_func(
|
||||
|
||||
macro(INSTRUMENTED_YIELD_VALUE) =
|
||||
_YIELD_VALUE_EVENT +
|
||||
YIELD_VALUE;
|
||||
_YIELD_VALUE;
|
||||
|
||||
inst(POP_EXCEPT, (exc_value -- )) {
|
||||
_PyErr_StackItem *exc_info = tstate->exc_info;
|
||||
@@ -2445,6 +2455,7 @@ dummy_func(
|
||||
|
||||
macro(LOAD_ATTR_INSTANCE_VALUE) =
|
||||
unused/1 + // Skip over the counter
|
||||
_RECORD_TOS_TYPE +
|
||||
_GUARD_TYPE_VERSION +
|
||||
_CHECK_MANAGED_OBJECT_HAS_VALUES +
|
||||
_LOAD_ATTR_INSTANCE_VALUE +
|
||||
@@ -2526,6 +2537,7 @@ dummy_func(
|
||||
|
||||
macro(LOAD_ATTR_WITH_HINT) =
|
||||
unused/1 +
|
||||
_RECORD_TOS_TYPE +
|
||||
_GUARD_TYPE_VERSION +
|
||||
_LOAD_ATTR_WITH_HINT +
|
||||
POP_TOP +
|
||||
@@ -2551,6 +2563,7 @@ dummy_func(
|
||||
|
||||
macro(LOAD_ATTR_SLOT) =
|
||||
unused/1 +
|
||||
_RECORD_TOS_TYPE +
|
||||
_GUARD_TYPE_VERSION +
|
||||
_LOAD_ATTR_SLOT + // NOTE: This action may also deopt
|
||||
POP_TOP +
|
||||
@@ -2581,8 +2594,9 @@ dummy_func(
|
||||
|
||||
macro(LOAD_ATTR_CLASS_WITH_METACLASS_CHECK) =
|
||||
unused/1 +
|
||||
_CHECK_ATTR_CLASS +
|
||||
_RECORD_TOS_TYPE +
|
||||
_GUARD_TYPE_VERSION +
|
||||
_CHECK_ATTR_CLASS +
|
||||
_LOAD_ATTR_CLASS +
|
||||
_PUSH_NULL_CONDITIONAL;
|
||||
|
||||
@@ -2604,8 +2618,9 @@ dummy_func(
|
||||
|
||||
macro(LOAD_ATTR_PROPERTY) =
|
||||
unused/1 +
|
||||
_CHECK_PEP_523 +
|
||||
_RECORD_TOS_TYPE +
|
||||
_GUARD_TYPE_VERSION +
|
||||
_CHECK_PEP_523 +
|
||||
unused/2 +
|
||||
_LOAD_ATTR_PROPERTY_FRAME +
|
||||
_SAVE_RETURN_OFFSET +
|
||||
@@ -2715,6 +2730,7 @@ dummy_func(
|
||||
|
||||
macro(STORE_ATTR_WITH_HINT) =
|
||||
unused/1 +
|
||||
_RECORD_TOS_TYPE +
|
||||
_GUARD_TYPE_VERSION +
|
||||
_STORE_ATTR_WITH_HINT +
|
||||
POP_TOP;
|
||||
@@ -2735,6 +2751,7 @@ dummy_func(
|
||||
|
||||
macro(STORE_ATTR_SLOT) =
|
||||
unused/1 +
|
||||
_RECORD_TOS_TYPE +
|
||||
_GUARD_TYPE_VERSION +
|
||||
_STORE_ATTR_SLOT +
|
||||
POP_TOP;
|
||||
@@ -3021,7 +3038,7 @@ dummy_func(
|
||||
oparg >>= 8;
|
||||
insert_exec_at--;
|
||||
}
|
||||
int succ = _PyJit_TryInitializeTracing(tstate, frame, this_instr, insert_exec_at, next_instr, STACK_LEVEL(), 0, NULL, oparg, NULL);
|
||||
int succ = _PyJit_TryInitializeTracing(tstate, frame, this_instr, insert_exec_at, next_instr, stack_pointer, 0, NULL, oparg, NULL);
|
||||
if (succ) {
|
||||
ENTER_TRACING();
|
||||
}
|
||||
@@ -3506,6 +3523,7 @@ dummy_func(
|
||||
}
|
||||
|
||||
macro(FOR_ITER_GEN) =
|
||||
_RECORD_NOS +
|
||||
unused/1 +
|
||||
_CHECK_PEP_523 +
|
||||
_FOR_ITER_GEN_FRAME +
|
||||
@@ -3640,6 +3658,7 @@ dummy_func(
|
||||
|
||||
macro(LOAD_ATTR_METHOD_WITH_VALUES) =
|
||||
unused/1 +
|
||||
_RECORD_TOS_TYPE +
|
||||
_GUARD_TYPE_VERSION +
|
||||
_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT +
|
||||
_GUARD_KEYS_VERSION +
|
||||
@@ -3658,6 +3677,7 @@ dummy_func(
|
||||
|
||||
macro(LOAD_ATTR_METHOD_NO_DICT) =
|
||||
unused/1 +
|
||||
_RECORD_TOS_TYPE +
|
||||
_GUARD_TYPE_VERSION +
|
||||
unused/2 +
|
||||
_LOAD_ATTR_METHOD_NO_DICT;
|
||||
@@ -3672,6 +3692,7 @@ dummy_func(
|
||||
|
||||
macro(LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES) =
|
||||
unused/1 +
|
||||
_RECORD_TOS_TYPE +
|
||||
_GUARD_TYPE_VERSION +
|
||||
_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT +
|
||||
_GUARD_KEYS_VERSION +
|
||||
@@ -3688,6 +3709,7 @@ dummy_func(
|
||||
|
||||
macro(LOAD_ATTR_NONDESCRIPTOR_NO_DICT) =
|
||||
unused/1 +
|
||||
_RECORD_TOS_TYPE +
|
||||
_GUARD_TYPE_VERSION +
|
||||
unused/2 +
|
||||
_LOAD_ATTR_NONDESCRIPTOR_NO_DICT;
|
||||
@@ -3711,6 +3733,7 @@ dummy_func(
|
||||
|
||||
macro(LOAD_ATTR_METHOD_LAZY_DICT) =
|
||||
unused/1 +
|
||||
_RECORD_TOS_TYPE +
|
||||
_GUARD_TYPE_VERSION +
|
||||
_CHECK_ATTR_METHOD_LAZY_DICT +
|
||||
unused/1 +
|
||||
@@ -3879,6 +3902,7 @@ dummy_func(
|
||||
}
|
||||
|
||||
macro(CALL_PY_GENERAL) =
|
||||
_RECORD_CALLABLE +
|
||||
unused/1 + // Skip over the counter
|
||||
_CHECK_PEP_523 +
|
||||
_CHECK_FUNCTION_VERSION +
|
||||
@@ -3909,6 +3933,7 @@ dummy_func(
|
||||
}
|
||||
|
||||
macro(CALL_BOUND_METHOD_GENERAL) =
|
||||
_RECORD_BOUND_METHOD +
|
||||
unused/1 + // Skip over the counter
|
||||
_CHECK_PEP_523 +
|
||||
_CHECK_METHOD_VERSION +
|
||||
@@ -3948,6 +3973,7 @@ dummy_func(
|
||||
}
|
||||
|
||||
macro(CALL_NON_PY_GENERAL) =
|
||||
_RECORD_CALLABLE +
|
||||
unused/1 + // Skip over the counter
|
||||
unused/2 +
|
||||
_CHECK_IS_NOT_PY_CALLABLE +
|
||||
@@ -4021,6 +4047,7 @@ dummy_func(
|
||||
}
|
||||
|
||||
macro(CALL_BOUND_METHOD_EXACT_ARGS) =
|
||||
_RECORD_BOUND_METHOD +
|
||||
unused/1 + // Skip over the counter
|
||||
_CHECK_PEP_523 +
|
||||
_CHECK_CALL_BOUND_METHOD_EXACT_ARGS +
|
||||
@@ -4035,6 +4062,7 @@ dummy_func(
|
||||
_PUSH_FRAME;
|
||||
|
||||
macro(CALL_PY_EXACT_ARGS) =
|
||||
_RECORD_CALLABLE +
|
||||
unused/1 + // Skip over the counter
|
||||
_CHECK_PEP_523 +
|
||||
_CHECK_FUNCTION_VERSION +
|
||||
@@ -4187,6 +4215,7 @@ dummy_func(
|
||||
}
|
||||
|
||||
macro(CALL_ALLOC_AND_ENTER_INIT) =
|
||||
_RECORD_CALLABLE +
|
||||
unused/1 +
|
||||
_CHECK_PEP_523 +
|
||||
_CHECK_AND_ALLOCATE_OBJECT +
|
||||
@@ -4227,6 +4256,7 @@ dummy_func(
|
||||
}
|
||||
|
||||
macro(CALL_BUILTIN_CLASS) =
|
||||
_RECORD_CALLABLE +
|
||||
unused/1 +
|
||||
unused/2 +
|
||||
_CALL_BUILTIN_CLASS +
|
||||
@@ -4262,6 +4292,7 @@ dummy_func(
|
||||
}
|
||||
|
||||
macro(CALL_BUILTIN_O) =
|
||||
_RECORD_CALLABLE +
|
||||
unused/1 +
|
||||
unused/2 +
|
||||
_CALL_BUILTIN_O +
|
||||
@@ -4294,6 +4325,7 @@ dummy_func(
|
||||
}
|
||||
|
||||
macro(CALL_BUILTIN_FAST) =
|
||||
_RECORD_CALLABLE +
|
||||
unused/1 +
|
||||
unused/2 +
|
||||
_CALL_BUILTIN_FAST +
|
||||
@@ -4320,6 +4352,7 @@ dummy_func(
|
||||
}
|
||||
|
||||
macro(CALL_BUILTIN_FAST_WITH_KEYWORDS) =
|
||||
_RECORD_CALLABLE +
|
||||
unused/1 +
|
||||
unused/2 +
|
||||
_CALL_BUILTIN_FAST_WITH_KEYWORDS +
|
||||
@@ -4463,6 +4496,7 @@ dummy_func(
|
||||
}
|
||||
|
||||
macro(CALL_METHOD_DESCRIPTOR_O) =
|
||||
_RECORD_CALLABLE +
|
||||
unused/1 +
|
||||
unused/2 +
|
||||
_CALL_METHOD_DESCRIPTOR_O +
|
||||
@@ -4505,6 +4539,7 @@ dummy_func(
|
||||
}
|
||||
|
||||
macro(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS) =
|
||||
_RECORD_CALLABLE +
|
||||
unused/1 +
|
||||
unused/2 +
|
||||
_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS +
|
||||
@@ -4543,6 +4578,7 @@ dummy_func(
|
||||
}
|
||||
|
||||
macro(CALL_METHOD_DESCRIPTOR_NOARGS) =
|
||||
_RECORD_CALLABLE +
|
||||
unused/1 +
|
||||
unused/2 +
|
||||
_CALL_METHOD_DESCRIPTOR_NOARGS +
|
||||
@@ -4968,6 +5004,7 @@ dummy_func(
|
||||
}
|
||||
|
||||
macro(CALL_EX_PY) =
|
||||
_RECORD_4OS +
|
||||
unused/1 +
|
||||
_CHECK_PEP_523 +
|
||||
_MAKE_CALLARGS_A_TUPLE +
|
||||
@@ -5037,7 +5074,7 @@ dummy_func(
|
||||
*ptr = attr;
|
||||
}
|
||||
|
||||
inst(RETURN_GENERATOR, (-- res)) {
|
||||
op(_RETURN_GENERATOR, (-- res)) {
|
||||
assert(PyStackRef_FunctionCheck(frame->f_funcobj));
|
||||
PyFunctionObject *func = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj);
|
||||
PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func);
|
||||
@@ -5060,6 +5097,10 @@ dummy_func(
|
||||
LLTRACE_RESUME_FRAME();
|
||||
}
|
||||
|
||||
macro(RETURN_GENERATOR) =
|
||||
_RECORD_CALLER_CODE +
|
||||
_RETURN_GENERATOR;
|
||||
|
||||
inst(BUILD_SLICE, (args[oparg] -- slice)) {
|
||||
PyObject *start_o = PyStackRef_AsPyObjectBorrow(args[0]);
|
||||
PyObject *stop_o = PyStackRef_AsPyObjectBorrow(args[1]);
|
||||
@@ -5588,7 +5629,7 @@ dummy_func(
|
||||
// Note: it's safe to use target->op.arg here instead of the oparg given by EXTENDED_ARG.
|
||||
// The invariant in the optimizer is the deopt target always points back to the first EXTENDED_ARG.
|
||||
// So setting it to anything else is wrong.
|
||||
int succ = _PyJit_TryInitializeTracing(tstate, frame, target, target, target, STACK_LEVEL(), chain_depth, exit, target->op.arg, previous_executor);
|
||||
int succ = _PyJit_TryInitializeTracing(tstate, frame, target, target, target, stack_pointer, chain_depth, exit, target->op.arg, previous_executor);
|
||||
exit->temperature = restart_backoff_counter(exit->temperature);
|
||||
if (succ) {
|
||||
GOTO_TIER_ONE_CONTINUE_TRACING(target);
|
||||
@@ -5607,37 +5648,77 @@ dummy_func(
|
||||
}
|
||||
|
||||
tier2 op(_GUARD_IP__PUSH_FRAME, (ip/4 --)) {
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + IP_OFFSET_OF(_PUSH_FRAME);
|
||||
_Py_CODEUNIT *target = frame->instr_ptr;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += IP_OFFSET_OF(_PUSH_FRAME);
|
||||
EXIT_IF(true);
|
||||
}
|
||||
}
|
||||
|
||||
tier2 op(_GUARD_IP_YIELD_VALUE, (ip/4 --)) {
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + IP_OFFSET_OF(YIELD_VALUE);
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + 1 + INLINE_CACHE_ENTRIES_SEND;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += IP_OFFSET_OF(YIELD_VALUE);
|
||||
frame->instr_ptr += 1 + INLINE_CACHE_ENTRIES_SEND;
|
||||
EXIT_IF(true);
|
||||
}
|
||||
}
|
||||
|
||||
tier2 op(_GUARD_IP_RETURN_VALUE, (ip/4 --)) {
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + IP_OFFSET_OF(RETURN_VALUE);
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + frame->return_offset;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += IP_OFFSET_OF(RETURN_VALUE);
|
||||
frame->instr_ptr += frame->return_offset;
|
||||
EXIT_IF(true);
|
||||
}
|
||||
}
|
||||
|
||||
tier2 op(_GUARD_IP_RETURN_GENERATOR, (ip/4 --)) {
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + IP_OFFSET_OF(RETURN_GENERATOR);
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + frame->return_offset;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += IP_OFFSET_OF(RETURN_GENERATOR);
|
||||
frame->instr_ptr += frame->return_offset;
|
||||
EXIT_IF(true);
|
||||
}
|
||||
}
|
||||
|
||||
/* Record ops for jit tracer.
|
||||
*
|
||||
* NOTE: These uops are NOPs for normal evaluation.
|
||||
* They are only executed during trace recording */
|
||||
|
||||
tier2 op(_RECORD_TOS, (tos -- tos)) {
|
||||
RECORD_VALUE(PyStackRef_AsPyObjectBorrow(tos));
|
||||
}
|
||||
|
||||
tier2 op(_RECORD_TOS_TYPE, (tos -- tos)) {
|
||||
RECORD_VALUE(Py_TYPE(PyStackRef_AsPyObjectBorrow(tos)));
|
||||
}
|
||||
|
||||
tier2 op(_RECORD_NOS, (nos, tos -- nos, tos)) {
|
||||
RECORD_VALUE(PyStackRef_AsPyObjectBorrow(nos));
|
||||
}
|
||||
|
||||
tier2 op(_RECORD_4OS, (value, _3os, nos, tos -- value, _3os, nos, tos)) {
|
||||
RECORD_VALUE(PyStackRef_AsPyObjectBorrow(value));
|
||||
}
|
||||
|
||||
tier2 op(_RECORD_CALLABLE, (func, self, args[oparg] -- func, self, args[oparg])) {
|
||||
RECORD_VALUE(PyStackRef_AsPyObjectBorrow(func));
|
||||
}
|
||||
|
||||
tier2 op(_RECORD_BOUND_METHOD, (callable, self, args[oparg] -- callable, self, args[oparg])) {
|
||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||
if (Py_TYPE(callable_o) == &PyMethod_Type) {
|
||||
PyObject *func = ((PyMethodObject *)callable_o)->im_func;
|
||||
RECORD_VALUE(func);
|
||||
}
|
||||
}
|
||||
|
||||
tier2 op(_RECORD_CALLER_CODE, ( -- )) {
|
||||
_PyInterpreterFrame *caller_frame = frame->previous;
|
||||
if (caller_frame->owner < FRAME_OWNED_BY_INTERPRETER) {
|
||||
PyCodeObject *code = _PyFrame_GetCode(frame->previous);
|
||||
RECORD_VALUE(code);
|
||||
}
|
||||
}
|
||||
|
||||
label(pop_2_error) {
|
||||
stack_pointer -= 2;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
@@ -5802,6 +5883,9 @@ dummy_func(
|
||||
opcode == INTERPRETER_EXIT ||
|
||||
(opcode >= MIN_INSTRUMENTED_OPCODE && opcode != ENTER_EXECUTOR)
|
||||
);
|
||||
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
|
||||
_PyJitTracerState *tracer = _tstate->jit_tracer_state;
|
||||
assert(tracer != NULL);
|
||||
int full = !_PyJit_translate_single_bytecode_to_trace(tstate, frame, next_instr, stop_tracing ? _DEOPT : 0);
|
||||
if (full) {
|
||||
LEAVE_TRACING();
|
||||
@@ -5809,13 +5893,7 @@ dummy_func(
|
||||
ERROR_IF(err < 0);
|
||||
DISPATCH();
|
||||
}
|
||||
// Super instructions. Instruction deopted. There's a mismatch in what the stack expects
|
||||
// in the optimizer. So we have to reflect in the trace correctly.
|
||||
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
|
||||
// JIT should have disabled super instructions, as we can
|
||||
// do these optimizations ourselves in the JIT.
|
||||
_PyJitTracerState *tracer = _tstate->jit_tracer_state;
|
||||
assert(tracer != NULL);
|
||||
Py_CLEAR(tracer->prev_state.recorded_value);
|
||||
tracer->prev_state.instr = next_instr;
|
||||
PyObject *prev_code = PyStackRef_AsPyObjectBorrow(frame->f_executable);
|
||||
if (tracer->prev_state.instr_code != (PyCodeObject *)prev_code) {
|
||||
@@ -5828,6 +5906,12 @@ dummy_func(
|
||||
if (_PyOpcode_Caches[_PyOpcode_Deopt[opcode]]) {
|
||||
(&next_instr[1])->counter = trigger_backoff_counter();
|
||||
}
|
||||
|
||||
uint8_t record_func_index = _PyOpcode_RecordFunctionIndices[opcode];
|
||||
if (record_func_index) {
|
||||
_Py_RecordFuncPtr doesnt_escape = _PyOpcode_RecordFunctions[record_func_index];
|
||||
doesnt_escape(frame, stack_pointer, oparg, &tracer->prev_state.recorded_value);
|
||||
}
|
||||
DISPATCH_GOTO_NON_TRACING();
|
||||
#else
|
||||
(void)prev_instr;
|
||||
|
||||
Generated
+29
-65
@@ -20150,7 +20150,7 @@
|
||||
_PyExecutorObject *previous_executor = _PyExecutor_FromExit(exit);
|
||||
assert(tstate->current_executor == (PyObject *)previous_executor);
|
||||
int chain_depth = previous_executor->vm_data.chain_depth + !exit->is_control_flow;
|
||||
int succ = _PyJit_TryInitializeTracing(tstate, frame, target, target, target, STACK_LEVEL(), chain_depth, exit, target->op.arg, previous_executor);
|
||||
int succ = _PyJit_TryInitializeTracing(tstate, frame, target, target, target, stack_pointer, chain_depth, exit, target->op.arg, previous_executor);
|
||||
exit->temperature = restart_backoff_counter(exit->temperature);
|
||||
if (succ) {
|
||||
GOTO_TIER_ONE_CONTINUE_TRACING(target);
|
||||
@@ -20171,11 +20171,9 @@
|
||||
case _GUARD_IP__PUSH_FRAME_r00: {
|
||||
CHECK_CURRENT_CACHED_VALUES(0);
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
#define OFFSET_OF__PUSH_FRAME ((0))
|
||||
PyObject *ip = (PyObject *)CURRENT_OPERAND0_64();
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + OFFSET_OF__PUSH_FRAME;
|
||||
_Py_CODEUNIT *target = frame->instr_ptr;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += OFFSET_OF__PUSH_FRAME;
|
||||
if (true) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
SET_CURRENT_CACHED_VALUES(0);
|
||||
@@ -20183,7 +20181,6 @@
|
||||
}
|
||||
}
|
||||
SET_CURRENT_CACHED_VALUES(0);
|
||||
#undef OFFSET_OF__PUSH_FRAME
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
break;
|
||||
}
|
||||
@@ -20192,11 +20189,9 @@
|
||||
CHECK_CURRENT_CACHED_VALUES(1);
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
_PyStackRef _stack_item_0 = _tos_cache0;
|
||||
#define OFFSET_OF__PUSH_FRAME ((0))
|
||||
PyObject *ip = (PyObject *)CURRENT_OPERAND0_64();
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + OFFSET_OF__PUSH_FRAME;
|
||||
_Py_CODEUNIT *target = frame->instr_ptr;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += OFFSET_OF__PUSH_FRAME;
|
||||
if (true) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache0 = _stack_item_0;
|
||||
@@ -20206,7 +20201,6 @@
|
||||
}
|
||||
_tos_cache0 = _stack_item_0;
|
||||
SET_CURRENT_CACHED_VALUES(1);
|
||||
#undef OFFSET_OF__PUSH_FRAME
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
break;
|
||||
}
|
||||
@@ -20216,11 +20210,9 @@
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
_PyStackRef _stack_item_0 = _tos_cache0;
|
||||
_PyStackRef _stack_item_1 = _tos_cache1;
|
||||
#define OFFSET_OF__PUSH_FRAME ((0))
|
||||
PyObject *ip = (PyObject *)CURRENT_OPERAND0_64();
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + OFFSET_OF__PUSH_FRAME;
|
||||
_Py_CODEUNIT *target = frame->instr_ptr;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += OFFSET_OF__PUSH_FRAME;
|
||||
if (true) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache1 = _stack_item_1;
|
||||
@@ -20232,7 +20224,6 @@
|
||||
_tos_cache1 = _stack_item_1;
|
||||
_tos_cache0 = _stack_item_0;
|
||||
SET_CURRENT_CACHED_VALUES(2);
|
||||
#undef OFFSET_OF__PUSH_FRAME
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
break;
|
||||
}
|
||||
@@ -20243,11 +20234,9 @@
|
||||
_PyStackRef _stack_item_0 = _tos_cache0;
|
||||
_PyStackRef _stack_item_1 = _tos_cache1;
|
||||
_PyStackRef _stack_item_2 = _tos_cache2;
|
||||
#define OFFSET_OF__PUSH_FRAME ((0))
|
||||
PyObject *ip = (PyObject *)CURRENT_OPERAND0_64();
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + OFFSET_OF__PUSH_FRAME;
|
||||
_Py_CODEUNIT *target = frame->instr_ptr;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += OFFSET_OF__PUSH_FRAME;
|
||||
if (true) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache2 = _stack_item_2;
|
||||
@@ -20261,7 +20250,6 @@
|
||||
_tos_cache1 = _stack_item_1;
|
||||
_tos_cache0 = _stack_item_0;
|
||||
SET_CURRENT_CACHED_VALUES(3);
|
||||
#undef OFFSET_OF__PUSH_FRAME
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
break;
|
||||
}
|
||||
@@ -20269,11 +20257,10 @@
|
||||
case _GUARD_IP_YIELD_VALUE_r00: {
|
||||
CHECK_CURRENT_CACHED_VALUES(0);
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
#define OFFSET_OF_YIELD_VALUE ((1+INLINE_CACHE_ENTRIES_SEND))
|
||||
PyObject *ip = (PyObject *)CURRENT_OPERAND0_64();
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + OFFSET_OF_YIELD_VALUE;
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + 1 + INLINE_CACHE_ENTRIES_SEND;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += OFFSET_OF_YIELD_VALUE;
|
||||
frame->instr_ptr += 1 + INLINE_CACHE_ENTRIES_SEND;
|
||||
if (true) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
SET_CURRENT_CACHED_VALUES(0);
|
||||
@@ -20281,7 +20268,6 @@
|
||||
}
|
||||
}
|
||||
SET_CURRENT_CACHED_VALUES(0);
|
||||
#undef OFFSET_OF_YIELD_VALUE
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
break;
|
||||
}
|
||||
@@ -20290,11 +20276,10 @@
|
||||
CHECK_CURRENT_CACHED_VALUES(1);
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
_PyStackRef _stack_item_0 = _tos_cache0;
|
||||
#define OFFSET_OF_YIELD_VALUE ((1+INLINE_CACHE_ENTRIES_SEND))
|
||||
PyObject *ip = (PyObject *)CURRENT_OPERAND0_64();
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + OFFSET_OF_YIELD_VALUE;
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + 1 + INLINE_CACHE_ENTRIES_SEND;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += OFFSET_OF_YIELD_VALUE;
|
||||
frame->instr_ptr += 1 + INLINE_CACHE_ENTRIES_SEND;
|
||||
if (true) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache0 = _stack_item_0;
|
||||
@@ -20304,7 +20289,6 @@
|
||||
}
|
||||
_tos_cache0 = _stack_item_0;
|
||||
SET_CURRENT_CACHED_VALUES(1);
|
||||
#undef OFFSET_OF_YIELD_VALUE
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
break;
|
||||
}
|
||||
@@ -20314,11 +20298,10 @@
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
_PyStackRef _stack_item_0 = _tos_cache0;
|
||||
_PyStackRef _stack_item_1 = _tos_cache1;
|
||||
#define OFFSET_OF_YIELD_VALUE ((1+INLINE_CACHE_ENTRIES_SEND))
|
||||
PyObject *ip = (PyObject *)CURRENT_OPERAND0_64();
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + OFFSET_OF_YIELD_VALUE;
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + 1 + INLINE_CACHE_ENTRIES_SEND;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += OFFSET_OF_YIELD_VALUE;
|
||||
frame->instr_ptr += 1 + INLINE_CACHE_ENTRIES_SEND;
|
||||
if (true) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache1 = _stack_item_1;
|
||||
@@ -20330,7 +20313,6 @@
|
||||
_tos_cache1 = _stack_item_1;
|
||||
_tos_cache0 = _stack_item_0;
|
||||
SET_CURRENT_CACHED_VALUES(2);
|
||||
#undef OFFSET_OF_YIELD_VALUE
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
break;
|
||||
}
|
||||
@@ -20341,11 +20323,10 @@
|
||||
_PyStackRef _stack_item_0 = _tos_cache0;
|
||||
_PyStackRef _stack_item_1 = _tos_cache1;
|
||||
_PyStackRef _stack_item_2 = _tos_cache2;
|
||||
#define OFFSET_OF_YIELD_VALUE ((1+INLINE_CACHE_ENTRIES_SEND))
|
||||
PyObject *ip = (PyObject *)CURRENT_OPERAND0_64();
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + OFFSET_OF_YIELD_VALUE;
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + 1 + INLINE_CACHE_ENTRIES_SEND;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += OFFSET_OF_YIELD_VALUE;
|
||||
frame->instr_ptr += 1 + INLINE_CACHE_ENTRIES_SEND;
|
||||
if (true) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache2 = _stack_item_2;
|
||||
@@ -20359,7 +20340,6 @@
|
||||
_tos_cache1 = _stack_item_1;
|
||||
_tos_cache0 = _stack_item_0;
|
||||
SET_CURRENT_CACHED_VALUES(3);
|
||||
#undef OFFSET_OF_YIELD_VALUE
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
break;
|
||||
}
|
||||
@@ -20367,11 +20347,10 @@
|
||||
case _GUARD_IP_RETURN_VALUE_r00: {
|
||||
CHECK_CURRENT_CACHED_VALUES(0);
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
#define OFFSET_OF_RETURN_VALUE ((frame->return_offset))
|
||||
PyObject *ip = (PyObject *)CURRENT_OPERAND0_64();
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + OFFSET_OF_RETURN_VALUE;
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + frame->return_offset;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += OFFSET_OF_RETURN_VALUE;
|
||||
frame->instr_ptr += frame->return_offset;
|
||||
if (true) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
SET_CURRENT_CACHED_VALUES(0);
|
||||
@@ -20379,7 +20358,6 @@
|
||||
}
|
||||
}
|
||||
SET_CURRENT_CACHED_VALUES(0);
|
||||
#undef OFFSET_OF_RETURN_VALUE
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
break;
|
||||
}
|
||||
@@ -20388,11 +20366,10 @@
|
||||
CHECK_CURRENT_CACHED_VALUES(1);
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
_PyStackRef _stack_item_0 = _tos_cache0;
|
||||
#define OFFSET_OF_RETURN_VALUE ((frame->return_offset))
|
||||
PyObject *ip = (PyObject *)CURRENT_OPERAND0_64();
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + OFFSET_OF_RETURN_VALUE;
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + frame->return_offset;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += OFFSET_OF_RETURN_VALUE;
|
||||
frame->instr_ptr += frame->return_offset;
|
||||
if (true) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache0 = _stack_item_0;
|
||||
@@ -20402,7 +20379,6 @@
|
||||
}
|
||||
_tos_cache0 = _stack_item_0;
|
||||
SET_CURRENT_CACHED_VALUES(1);
|
||||
#undef OFFSET_OF_RETURN_VALUE
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
break;
|
||||
}
|
||||
@@ -20412,11 +20388,10 @@
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
_PyStackRef _stack_item_0 = _tos_cache0;
|
||||
_PyStackRef _stack_item_1 = _tos_cache1;
|
||||
#define OFFSET_OF_RETURN_VALUE ((frame->return_offset))
|
||||
PyObject *ip = (PyObject *)CURRENT_OPERAND0_64();
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + OFFSET_OF_RETURN_VALUE;
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + frame->return_offset;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += OFFSET_OF_RETURN_VALUE;
|
||||
frame->instr_ptr += frame->return_offset;
|
||||
if (true) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache1 = _stack_item_1;
|
||||
@@ -20428,7 +20403,6 @@
|
||||
_tos_cache1 = _stack_item_1;
|
||||
_tos_cache0 = _stack_item_0;
|
||||
SET_CURRENT_CACHED_VALUES(2);
|
||||
#undef OFFSET_OF_RETURN_VALUE
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
break;
|
||||
}
|
||||
@@ -20439,11 +20413,10 @@
|
||||
_PyStackRef _stack_item_0 = _tos_cache0;
|
||||
_PyStackRef _stack_item_1 = _tos_cache1;
|
||||
_PyStackRef _stack_item_2 = _tos_cache2;
|
||||
#define OFFSET_OF_RETURN_VALUE ((frame->return_offset))
|
||||
PyObject *ip = (PyObject *)CURRENT_OPERAND0_64();
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + OFFSET_OF_RETURN_VALUE;
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + frame->return_offset;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += OFFSET_OF_RETURN_VALUE;
|
||||
frame->instr_ptr += frame->return_offset;
|
||||
if (true) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache2 = _stack_item_2;
|
||||
@@ -20457,7 +20430,6 @@
|
||||
_tos_cache1 = _stack_item_1;
|
||||
_tos_cache0 = _stack_item_0;
|
||||
SET_CURRENT_CACHED_VALUES(3);
|
||||
#undef OFFSET_OF_RETURN_VALUE
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
break;
|
||||
}
|
||||
@@ -20465,11 +20437,10 @@
|
||||
case _GUARD_IP_RETURN_GENERATOR_r00: {
|
||||
CHECK_CURRENT_CACHED_VALUES(0);
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
#define OFFSET_OF_RETURN_GENERATOR ((frame->return_offset))
|
||||
PyObject *ip = (PyObject *)CURRENT_OPERAND0_64();
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + OFFSET_OF_RETURN_GENERATOR;
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + frame->return_offset;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += OFFSET_OF_RETURN_GENERATOR;
|
||||
frame->instr_ptr += frame->return_offset;
|
||||
if (true) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
SET_CURRENT_CACHED_VALUES(0);
|
||||
@@ -20477,7 +20448,6 @@
|
||||
}
|
||||
}
|
||||
SET_CURRENT_CACHED_VALUES(0);
|
||||
#undef OFFSET_OF_RETURN_GENERATOR
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
break;
|
||||
}
|
||||
@@ -20486,11 +20456,10 @@
|
||||
CHECK_CURRENT_CACHED_VALUES(1);
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
_PyStackRef _stack_item_0 = _tos_cache0;
|
||||
#define OFFSET_OF_RETURN_GENERATOR ((frame->return_offset))
|
||||
PyObject *ip = (PyObject *)CURRENT_OPERAND0_64();
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + OFFSET_OF_RETURN_GENERATOR;
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + frame->return_offset;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += OFFSET_OF_RETURN_GENERATOR;
|
||||
frame->instr_ptr += frame->return_offset;
|
||||
if (true) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache0 = _stack_item_0;
|
||||
@@ -20500,7 +20469,6 @@
|
||||
}
|
||||
_tos_cache0 = _stack_item_0;
|
||||
SET_CURRENT_CACHED_VALUES(1);
|
||||
#undef OFFSET_OF_RETURN_GENERATOR
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
break;
|
||||
}
|
||||
@@ -20510,11 +20478,10 @@
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
_PyStackRef _stack_item_0 = _tos_cache0;
|
||||
_PyStackRef _stack_item_1 = _tos_cache1;
|
||||
#define OFFSET_OF_RETURN_GENERATOR ((frame->return_offset))
|
||||
PyObject *ip = (PyObject *)CURRENT_OPERAND0_64();
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + OFFSET_OF_RETURN_GENERATOR;
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + frame->return_offset;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += OFFSET_OF_RETURN_GENERATOR;
|
||||
frame->instr_ptr += frame->return_offset;
|
||||
if (true) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache1 = _stack_item_1;
|
||||
@@ -20526,7 +20493,6 @@
|
||||
_tos_cache1 = _stack_item_1;
|
||||
_tos_cache0 = _stack_item_0;
|
||||
SET_CURRENT_CACHED_VALUES(2);
|
||||
#undef OFFSET_OF_RETURN_GENERATOR
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
break;
|
||||
}
|
||||
@@ -20537,11 +20503,10 @@
|
||||
_PyStackRef _stack_item_0 = _tos_cache0;
|
||||
_PyStackRef _stack_item_1 = _tos_cache1;
|
||||
_PyStackRef _stack_item_2 = _tos_cache2;
|
||||
#define OFFSET_OF_RETURN_GENERATOR ((frame->return_offset))
|
||||
PyObject *ip = (PyObject *)CURRENT_OPERAND0_64();
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + OFFSET_OF_RETURN_GENERATOR;
|
||||
_Py_CODEUNIT *target = frame->instr_ptr + frame->return_offset;
|
||||
if (target != (_Py_CODEUNIT *)ip) {
|
||||
frame->instr_ptr += OFFSET_OF_RETURN_GENERATOR;
|
||||
frame->instr_ptr += frame->return_offset;
|
||||
if (true) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache2 = _stack_item_2;
|
||||
@@ -20555,7 +20520,6 @@
|
||||
_tos_cache1 = _stack_item_1;
|
||||
_tos_cache0 = _stack_item_0;
|
||||
SET_CURRENT_CACHED_VALUES(3);
|
||||
#undef OFFSET_OF_RETURN_GENERATOR
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
break;
|
||||
}
|
||||
|
||||
Generated
+105
-88
@@ -7723,7 +7723,7 @@
|
||||
oparg >>= 8;
|
||||
insert_exec_at--;
|
||||
}
|
||||
int succ = _PyJit_TryInitializeTracing(tstate, frame, this_instr, insert_exec_at, next_instr, STACK_LEVEL(), 0, NULL, oparg, NULL);
|
||||
int succ = _PyJit_TryInitializeTracing(tstate, frame, this_instr, insert_exec_at, next_instr, stack_pointer, 0, NULL, oparg, NULL);
|
||||
if (succ) {
|
||||
ENTER_TRACING();
|
||||
}
|
||||
@@ -8017,10 +8017,21 @@
|
||||
_PyStackRef attr;
|
||||
_PyStackRef *null;
|
||||
/* Skip 1 cache entry */
|
||||
// _CHECK_ATTR_CLASS
|
||||
// _GUARD_TYPE_VERSION
|
||||
{
|
||||
owner = stack_pointer[-1];
|
||||
uint32_t type_version = read_u32(&this_instr[2].cache);
|
||||
PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
|
||||
assert(type_version != 0);
|
||||
if (FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version) {
|
||||
UPDATE_MISS_STATS(LOAD_ATTR);
|
||||
assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR));
|
||||
JUMP_TO_PREDICTED(LOAD_ATTR);
|
||||
}
|
||||
}
|
||||
// _CHECK_ATTR_CLASS
|
||||
{
|
||||
uint32_t type_version = read_u32(&this_instr[4].cache);
|
||||
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
|
||||
if (!PyType_Check(owner_o)) {
|
||||
UPDATE_MISS_STATS(LOAD_ATTR);
|
||||
@@ -8034,17 +8045,6 @@
|
||||
JUMP_TO_PREDICTED(LOAD_ATTR);
|
||||
}
|
||||
}
|
||||
// _GUARD_TYPE_VERSION
|
||||
{
|
||||
uint32_t type_version = read_u32(&this_instr[4].cache);
|
||||
PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
|
||||
assert(type_version != 0);
|
||||
if (FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version) {
|
||||
UPDATE_MISS_STATS(LOAD_ATTR);
|
||||
assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR));
|
||||
JUMP_TO_PREDICTED(LOAD_ATTR);
|
||||
}
|
||||
}
|
||||
// _LOAD_ATTR_CLASS
|
||||
{
|
||||
PyObject *descr = read_obj(&this_instr[6].cache);
|
||||
@@ -8594,14 +8594,6 @@
|
||||
_PyStackRef owner;
|
||||
_PyStackRef new_frame;
|
||||
/* Skip 1 cache entry */
|
||||
// _CHECK_PEP_523
|
||||
{
|
||||
if (IS_PEP523_HOOKED(tstate)) {
|
||||
UPDATE_MISS_STATS(LOAD_ATTR);
|
||||
assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR));
|
||||
JUMP_TO_PREDICTED(LOAD_ATTR);
|
||||
}
|
||||
}
|
||||
// _GUARD_TYPE_VERSION
|
||||
{
|
||||
owner = stack_pointer[-1];
|
||||
@@ -8614,6 +8606,14 @@
|
||||
JUMP_TO_PREDICTED(LOAD_ATTR);
|
||||
}
|
||||
}
|
||||
// _CHECK_PEP_523
|
||||
{
|
||||
if (IS_PEP523_HOOKED(tstate)) {
|
||||
UPDATE_MISS_STATS(LOAD_ATTR);
|
||||
assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR));
|
||||
JUMP_TO_PREDICTED(LOAD_ATTR);
|
||||
}
|
||||
}
|
||||
/* Skip 2 cache entries */
|
||||
// _LOAD_ATTR_PROPERTY_FRAME
|
||||
{
|
||||
@@ -10446,30 +10446,33 @@
|
||||
next_instr += 1;
|
||||
INSTRUCTION_STATS(RETURN_GENERATOR);
|
||||
_PyStackRef res;
|
||||
assert(PyStackRef_FunctionCheck(frame->f_funcobj));
|
||||
PyFunctionObject *func = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
if (gen == NULL) {
|
||||
JUMP_TO_LABEL(error);
|
||||
// _RETURN_GENERATOR
|
||||
{
|
||||
assert(PyStackRef_FunctionCheck(frame->f_funcobj));
|
||||
PyFunctionObject *func = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
if (gen == NULL) {
|
||||
JUMP_TO_LABEL(error);
|
||||
}
|
||||
assert(STACK_LEVEL() <= 2);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
_PyInterpreterFrame *gen_frame = &gen->gi_iframe;
|
||||
frame->instr_ptr++;
|
||||
_PyFrame_Copy(frame, gen_frame);
|
||||
assert(frame->frame_obj == NULL);
|
||||
gen->gi_frame_state = FRAME_CREATED;
|
||||
gen_frame->owner = FRAME_OWNED_BY_GENERATOR;
|
||||
_Py_LeaveRecursiveCallPy(tstate);
|
||||
_PyInterpreterFrame *prev = frame->previous;
|
||||
_PyThreadState_PopFrame(tstate, frame);
|
||||
frame = tstate->current_frame = prev;
|
||||
LOAD_IP(frame->return_offset);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
res = PyStackRef_FromPyObjectStealMortal((PyObject *)gen);
|
||||
LLTRACE_RESUME_FRAME();
|
||||
}
|
||||
assert(STACK_LEVEL() <= 2);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
_PyInterpreterFrame *gen_frame = &gen->gi_iframe;
|
||||
frame->instr_ptr++;
|
||||
_PyFrame_Copy(frame, gen_frame);
|
||||
assert(frame->frame_obj == NULL);
|
||||
gen->gi_frame_state = FRAME_CREATED;
|
||||
gen_frame->owner = FRAME_OWNED_BY_GENERATOR;
|
||||
_Py_LeaveRecursiveCallPy(tstate);
|
||||
_PyInterpreterFrame *prev = frame->previous;
|
||||
_PyThreadState_PopFrame(tstate, frame);
|
||||
frame = tstate->current_frame = prev;
|
||||
LOAD_IP(frame->return_offset);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
res = PyStackRef_FromPyObjectStealMortal((PyObject *)gen);
|
||||
LLTRACE_RESUME_FRAME();
|
||||
stack_pointer[0] = res;
|
||||
stack_pointer += 1;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
@@ -10486,21 +10489,24 @@
|
||||
INSTRUCTION_STATS(RETURN_VALUE);
|
||||
_PyStackRef retval;
|
||||
_PyStackRef res;
|
||||
retval = stack_pointer[-1];
|
||||
assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
|
||||
_PyStackRef temp = PyStackRef_MakeHeapSafe(retval);
|
||||
stack_pointer += -1;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
assert(STACK_LEVEL() == 0);
|
||||
_Py_LeaveRecursiveCallPy(tstate);
|
||||
_PyInterpreterFrame *dying = frame;
|
||||
frame = tstate->current_frame = dying->previous;
|
||||
_PyEval_FrameClearAndPop(tstate, dying);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
LOAD_IP(frame->return_offset);
|
||||
res = temp;
|
||||
LLTRACE_RESUME_FRAME();
|
||||
// _RETURN_VALUE
|
||||
{
|
||||
retval = stack_pointer[-1];
|
||||
assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
|
||||
_PyStackRef temp = PyStackRef_MakeHeapSafe(retval);
|
||||
stack_pointer += -1;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
assert(STACK_LEVEL() == 0);
|
||||
_Py_LeaveRecursiveCallPy(tstate);
|
||||
_PyInterpreterFrame *dying = frame;
|
||||
frame = tstate->current_frame = dying->previous;
|
||||
_PyEval_FrameClearAndPop(tstate, dying);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
LOAD_IP(frame->return_offset);
|
||||
res = temp;
|
||||
LLTRACE_RESUME_FRAME();
|
||||
}
|
||||
stack_pointer[0] = res;
|
||||
stack_pointer += 1;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
@@ -11889,6 +11895,9 @@
|
||||
opcode == INTERPRETER_EXIT ||
|
||||
(opcode >= MIN_INSTRUMENTED_OPCODE && opcode != ENTER_EXECUTOR)
|
||||
);
|
||||
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
|
||||
_PyJitTracerState *tracer = _tstate->jit_tracer_state;
|
||||
assert(tracer != NULL);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
int full = !_PyJit_translate_single_bytecode_to_trace(tstate, frame, next_instr, stop_tracing ? _DEOPT : 0);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
@@ -11902,9 +11911,9 @@
|
||||
}
|
||||
DISPATCH();
|
||||
}
|
||||
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
|
||||
_PyJitTracerState *tracer = _tstate->jit_tracer_state;
|
||||
assert(tracer != NULL);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
Py_CLEAR(tracer->prev_state.recorded_value);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
tracer->prev_state.instr = next_instr;
|
||||
PyObject *prev_code = PyStackRef_AsPyObjectBorrow(frame->f_executable);
|
||||
if (tracer->prev_state.instr_code != (PyCodeObject *)prev_code) {
|
||||
@@ -11918,6 +11927,11 @@
|
||||
if (_PyOpcode_Caches[_PyOpcode_Deopt[opcode]]) {
|
||||
(&next_instr[1])->counter = trigger_backoff_counter();
|
||||
}
|
||||
uint8_t record_func_index = _PyOpcode_RecordFunctionIndices[opcode];
|
||||
if (record_func_index) {
|
||||
_Py_RecordFuncPtr doesnt_escape = _PyOpcode_RecordFunctions[record_func_index];
|
||||
doesnt_escape(frame, stack_pointer, oparg, &tracer->prev_state.recorded_value);
|
||||
}
|
||||
DISPATCH_GOTO_NON_TRACING();
|
||||
#else
|
||||
(void)prev_instr;
|
||||
@@ -12309,37 +12323,40 @@
|
||||
INSTRUCTION_STATS(YIELD_VALUE);
|
||||
_PyStackRef retval;
|
||||
_PyStackRef value;
|
||||
retval = stack_pointer[-1];
|
||||
assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
|
||||
frame->instr_ptr++;
|
||||
PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame);
|
||||
assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1);
|
||||
assert(oparg == 0 || oparg == 1);
|
||||
_PyStackRef temp = retval;
|
||||
stack_pointer += -1;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
tstate->exc_info = gen->gi_exc_state.previous_item;
|
||||
gen->gi_exc_state.previous_item = NULL;
|
||||
_Py_LeaveRecursiveCallPy(tstate);
|
||||
_PyInterpreterFrame *gen_frame = frame;
|
||||
frame = tstate->current_frame = frame->previous;
|
||||
gen_frame->previous = NULL;
|
||||
((_PyThreadStateImpl *)tstate)->generator_return_kind = GENERATOR_YIELD;
|
||||
FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_SUSPENDED + oparg);
|
||||
assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER);
|
||||
#if TIER_ONE
|
||||
assert(frame->instr_ptr->op.code == INSTRUMENTED_LINE ||
|
||||
// _YIELD_VALUE
|
||||
{
|
||||
retval = stack_pointer[-1];
|
||||
assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
|
||||
frame->instr_ptr++;
|
||||
PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame);
|
||||
assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1);
|
||||
assert(oparg == 0 || oparg == 1);
|
||||
_PyStackRef temp = retval;
|
||||
stack_pointer += -1;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
tstate->exc_info = gen->gi_exc_state.previous_item;
|
||||
gen->gi_exc_state.previous_item = NULL;
|
||||
_Py_LeaveRecursiveCallPy(tstate);
|
||||
_PyInterpreterFrame *gen_frame = frame;
|
||||
frame = tstate->current_frame = frame->previous;
|
||||
gen_frame->previous = NULL;
|
||||
((_PyThreadStateImpl *)tstate)->generator_return_kind = GENERATOR_YIELD;
|
||||
FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_SUSPENDED + oparg);
|
||||
assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER);
|
||||
#if TIER_ONE
|
||||
assert(frame->instr_ptr->op.code == INSTRUMENTED_LINE ||
|
||||
frame->instr_ptr->op.code == INSTRUMENTED_INSTRUCTION ||
|
||||
_PyOpcode_Deopt[frame->instr_ptr->op.code] == SEND ||
|
||||
_PyOpcode_Deopt[frame->instr_ptr->op.code] == FOR_ITER ||
|
||||
_PyOpcode_Deopt[frame->instr_ptr->op.code] == INTERPRETER_EXIT ||
|
||||
_PyOpcode_Deopt[frame->instr_ptr->op.code] == ENTER_EXECUTOR);
|
||||
#endif
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND);
|
||||
value = PyStackRef_MakeHeapSafe(temp);
|
||||
LLTRACE_RESUME_FRAME();
|
||||
#endif
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND);
|
||||
value = PyStackRef_MakeHeapSafe(temp);
|
||||
LLTRACE_RESUME_FRAME();
|
||||
}
|
||||
stack_pointer[0] = value;
|
||||
stack_pointer += 1;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
|
||||
+21
-3
@@ -955,6 +955,11 @@ _PyJit_translate_single_bytecode_to_trace(
|
||||
assert(next->op.code == STORE_FAST);
|
||||
operand = next->op.arg;
|
||||
}
|
||||
else if (_PyUop_Flags[uop] & HAS_RECORDS_VALUE_FLAG) {
|
||||
PyObject *recorded_value = tracer->prev_state.recorded_value;
|
||||
tracer->prev_state.recorded_value = NULL;
|
||||
operand = (uintptr_t)recorded_value;
|
||||
}
|
||||
// All other instructions
|
||||
ADD_TO_TRACE(uop, oparg, operand, target);
|
||||
}
|
||||
@@ -997,7 +1002,7 @@ done:
|
||||
Py_NO_INLINE int
|
||||
_PyJit_TryInitializeTracing(
|
||||
PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *curr_instr,
|
||||
_Py_CODEUNIT *start_instr, _Py_CODEUNIT *close_loop_instr, int curr_stackdepth, int chain_depth,
|
||||
_Py_CODEUNIT *start_instr, _Py_CODEUNIT *close_loop_instr, _PyStackRef *stack_pointer, int chain_depth,
|
||||
_PyExitData *exit, int oparg, _PyExecutorObject *current_executor)
|
||||
{
|
||||
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
|
||||
@@ -1048,14 +1053,20 @@ _PyJit_TryInitializeTracing(
|
||||
tracer->initial_state.func = (PyFunctionObject *)Py_NewRef(func);
|
||||
tracer->initial_state.executor = (_PyExecutorObject *)Py_XNewRef(current_executor);
|
||||
tracer->initial_state.exit = exit;
|
||||
tracer->initial_state.stack_depth = curr_stackdepth;
|
||||
tracer->initial_state.stack_depth = stack_pointer - _PyFrame_Stackbase(frame);
|
||||
tracer->initial_state.chain_depth = chain_depth;
|
||||
tracer->prev_state.dependencies_still_valid = true;
|
||||
tracer->prev_state.instr_code = (PyCodeObject *)Py_NewRef(_PyFrame_GetCode(frame));
|
||||
tracer->prev_state.instr = curr_instr;
|
||||
tracer->prev_state.instr_frame = frame;
|
||||
tracer->prev_state.instr_oparg = oparg;
|
||||
tracer->prev_state.instr_stacklevel = curr_stackdepth;
|
||||
tracer->prev_state.instr_stacklevel = tracer->initial_state.stack_depth;
|
||||
tracer->prev_state.recorded_value = NULL;
|
||||
uint8_t record_func_index = _PyOpcode_RecordFunctionIndices[curr_instr->op.code];
|
||||
if (record_func_index) {
|
||||
_Py_RecordFuncPtr record_func = _PyOpcode_RecordFunctions[record_func_index];
|
||||
record_func(frame, stack_pointer, oparg, &tracer->prev_state.recorded_value);
|
||||
}
|
||||
assert(curr_instr->op.code == JUMP_BACKWARD_JIT || (exit != NULL));
|
||||
tracer->initial_state.jump_backward_instr = curr_instr;
|
||||
|
||||
@@ -1099,6 +1110,7 @@ _PyJit_FinalizeTracing(PyThreadState *tstate, int err)
|
||||
Py_CLEAR(tracer->initial_state.func);
|
||||
Py_CLEAR(tracer->initial_state.executor);
|
||||
Py_CLEAR(tracer->prev_state.instr_code);
|
||||
Py_CLEAR(tracer->prev_state.recorded_value);
|
||||
uop_buffer_init(&tracer->code_buffer, &tracer->uop_array[0], UOP_MAX_TRACE_LENGTH);
|
||||
tracer->is_tracing = false;
|
||||
}
|
||||
@@ -1526,6 +1538,10 @@ uop_optimize(
|
||||
buffer[pc].opcode = opcode + oparg + 1 - _PyUop_Replication[opcode].start;
|
||||
assert(strncmp(_PyOpcode_uop_name[buffer[pc].opcode], _PyOpcode_uop_name[opcode], strlen(_PyOpcode_uop_name[opcode])) == 0);
|
||||
}
|
||||
else if (_PyUop_Flags[opcode] & HAS_RECORDS_VALUE_FLAG) {
|
||||
Py_XDECREF((PyObject *)(uintptr_t)buffer[pc].operand0);
|
||||
buffer[pc].opcode = _NOP;
|
||||
}
|
||||
else if (is_terminator(&buffer[pc])) {
|
||||
break;
|
||||
}
|
||||
@@ -1926,6 +1942,8 @@ error:
|
||||
_Py_Executors_InvalidateAll(interp, 0);
|
||||
}
|
||||
|
||||
#include "record_functions.c.h"
|
||||
|
||||
static int
|
||||
escape_angles(const char *input, Py_ssize_t size, char *buffer) {
|
||||
int written = 0;
|
||||
|
||||
@@ -177,6 +177,7 @@ dummy_func(void) {
|
||||
|
||||
op(_GUARD_TYPE_VERSION, (type_version/2, owner -- owner)) {
|
||||
assert(type_version);
|
||||
assert(this_instr[-1].opcode == _RECORD_TOS_TYPE);
|
||||
if (sym_matches_type_version(owner, type_version)) {
|
||||
ADD_OP(_NOP, 0, 0);
|
||||
} else {
|
||||
|
||||
Generated
+29
@@ -1833,6 +1833,7 @@
|
||||
owner = stack_pointer[-1];
|
||||
uint32_t type_version = (uint32_t)this_instr->operand0;
|
||||
assert(type_version);
|
||||
assert(this_instr[-1].opcode == _RECORD_TOS_TYPE);
|
||||
if (sym_matches_type_version(owner, type_version)) {
|
||||
ADD_OP(_NOP, 0, 0);
|
||||
} else {
|
||||
@@ -4176,5 +4177,33 @@
|
||||
break;
|
||||
}
|
||||
|
||||
case _RECORD_TOS: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _RECORD_TOS_TYPE: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _RECORD_NOS: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _RECORD_4OS: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _RECORD_CALLABLE: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _RECORD_BOUND_METHOD: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _RECORD_CALLER_CODE: {
|
||||
break;
|
||||
}
|
||||
|
||||
/* _TRACE_RECORD is not a viable micro-op for tier 2 */
|
||||
|
||||
Generated
+115
@@ -0,0 +1,115 @@
|
||||
// This file is generated by Tools/cases_generator/record_function_generator.py
|
||||
// from:
|
||||
// Python/bytecodes.c
|
||||
// Do not edit!
|
||||
|
||||
#ifdef TIER_ONE
|
||||
#error "This file is for Tier 2 only"
|
||||
#endif
|
||||
void _PyOpcode_RecordFunction_TOS(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer, int oparg, PyObject **recorded_value) {
|
||||
_PyStackRef tos;
|
||||
tos = stack_pointer[-1];
|
||||
*recorded_value = (PyObject *)PyStackRef_AsPyObjectBorrow(tos);
|
||||
Py_INCREF(*recorded_value);
|
||||
}
|
||||
|
||||
void _PyOpcode_RecordFunction_TOS_TYPE(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer, int oparg, PyObject **recorded_value) {
|
||||
_PyStackRef tos;
|
||||
tos = stack_pointer[-1];
|
||||
*recorded_value = (PyObject *)Py_TYPE(PyStackRef_AsPyObjectBorrow(tos));
|
||||
Py_INCREF(*recorded_value);
|
||||
}
|
||||
|
||||
void _PyOpcode_RecordFunction_NOS(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer, int oparg, PyObject **recorded_value) {
|
||||
_PyStackRef nos;
|
||||
nos = stack_pointer[-2];
|
||||
*recorded_value = (PyObject *)PyStackRef_AsPyObjectBorrow(nos);
|
||||
Py_INCREF(*recorded_value);
|
||||
}
|
||||
|
||||
void _PyOpcode_RecordFunction_4OS(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer, int oparg, PyObject **recorded_value) {
|
||||
_PyStackRef value;
|
||||
value = stack_pointer[-4];
|
||||
*recorded_value = (PyObject *)PyStackRef_AsPyObjectBorrow(value);
|
||||
Py_INCREF(*recorded_value);
|
||||
}
|
||||
|
||||
void _PyOpcode_RecordFunction_CALLABLE(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer, int oparg, PyObject **recorded_value) {
|
||||
_PyStackRef func;
|
||||
func = stack_pointer[-2 - oparg];
|
||||
*recorded_value = (PyObject *)PyStackRef_AsPyObjectBorrow(func);
|
||||
Py_INCREF(*recorded_value);
|
||||
}
|
||||
|
||||
void _PyOpcode_RecordFunction_BOUND_METHOD(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer, int oparg, PyObject **recorded_value) {
|
||||
_PyStackRef callable;
|
||||
callable = stack_pointer[-2 - oparg];
|
||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||
if (Py_TYPE(callable_o) == &PyMethod_Type) {
|
||||
PyObject *func = ((PyMethodObject *)callable_o)->im_func;
|
||||
*recorded_value = (PyObject *)func;
|
||||
Py_INCREF(*recorded_value);
|
||||
}
|
||||
}
|
||||
|
||||
void _PyOpcode_RecordFunction_CALLER_CODE(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer, int oparg, PyObject **recorded_value) {
|
||||
_PyInterpreterFrame *caller_frame = frame->previous;
|
||||
if (caller_frame->owner < FRAME_OWNED_BY_INTERPRETER) {
|
||||
PyCodeObject *code = _PyFrame_GetCode(frame->previous);
|
||||
*recorded_value = (PyObject *)code;
|
||||
Py_INCREF(*recorded_value);
|
||||
}
|
||||
}
|
||||
|
||||
#define _RECORD_TOS_TYPE_INDEX 1
|
||||
#define _RECORD_TOS_INDEX 2
|
||||
#define _RECORD_CALLER_CODE_INDEX 3
|
||||
#define _RECORD_NOS_INDEX 4
|
||||
#define _RECORD_CALLABLE_INDEX 5
|
||||
#define _RECORD_BOUND_METHOD_INDEX 6
|
||||
#define _RECORD_4OS_INDEX 7
|
||||
const uint8_t _PyOpcode_RecordFunctionIndices[256] = {
|
||||
[TO_BOOL_ALWAYS_TRUE] = _RECORD_TOS_TYPE_INDEX,
|
||||
[BINARY_OP_SUBSCR_GETITEM] = _RECORD_TOS_INDEX,
|
||||
[RETURN_VALUE] = _RECORD_CALLER_CODE_INDEX,
|
||||
[YIELD_VALUE] = _RECORD_CALLER_CODE_INDEX,
|
||||
[LOAD_ATTR_INSTANCE_VALUE] = _RECORD_TOS_TYPE_INDEX,
|
||||
[LOAD_ATTR_WITH_HINT] = _RECORD_TOS_TYPE_INDEX,
|
||||
[LOAD_ATTR_SLOT] = _RECORD_TOS_TYPE_INDEX,
|
||||
[LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = _RECORD_TOS_TYPE_INDEX,
|
||||
[LOAD_ATTR_PROPERTY] = _RECORD_TOS_TYPE_INDEX,
|
||||
[STORE_ATTR_WITH_HINT] = _RECORD_TOS_TYPE_INDEX,
|
||||
[STORE_ATTR_SLOT] = _RECORD_TOS_TYPE_INDEX,
|
||||
[FOR_ITER_GEN] = _RECORD_NOS_INDEX,
|
||||
[LOAD_ATTR_METHOD_WITH_VALUES] = _RECORD_TOS_TYPE_INDEX,
|
||||
[LOAD_ATTR_METHOD_NO_DICT] = _RECORD_TOS_TYPE_INDEX,
|
||||
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = _RECORD_TOS_TYPE_INDEX,
|
||||
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = _RECORD_TOS_TYPE_INDEX,
|
||||
[LOAD_ATTR_METHOD_LAZY_DICT] = _RECORD_TOS_TYPE_INDEX,
|
||||
[CALL_PY_GENERAL] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_BOUND_METHOD_GENERAL] = _RECORD_BOUND_METHOD_INDEX,
|
||||
[CALL_NON_PY_GENERAL] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_BOUND_METHOD_EXACT_ARGS] = _RECORD_BOUND_METHOD_INDEX,
|
||||
[CALL_PY_EXACT_ARGS] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_ALLOC_AND_ENTER_INIT] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_BUILTIN_CLASS] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_BUILTIN_O] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_BUILTIN_FAST] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_METHOD_DESCRIPTOR_O] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_METHOD_DESCRIPTOR_NOARGS] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_EX_PY] = _RECORD_4OS_INDEX,
|
||||
[RETURN_GENERATOR] = _RECORD_CALLER_CODE_INDEX,
|
||||
};
|
||||
|
||||
const _Py_RecordFuncPtr _PyOpcode_RecordFunctions[8] = {
|
||||
[0] = NULL,
|
||||
[_RECORD_TOS_TYPE_INDEX] = _PyOpcode_RecordFunction_TOS_TYPE,
|
||||
[_RECORD_TOS_INDEX] = _PyOpcode_RecordFunction_TOS,
|
||||
[_RECORD_CALLER_CODE_INDEX] = _PyOpcode_RecordFunction_CALLER_CODE,
|
||||
[_RECORD_NOS_INDEX] = _PyOpcode_RecordFunction_NOS,
|
||||
[_RECORD_CALLABLE_INDEX] = _PyOpcode_RecordFunction_CALLABLE,
|
||||
[_RECORD_BOUND_METHOD_INDEX] = _PyOpcode_RecordFunction_BOUND_METHOD,
|
||||
[_RECORD_4OS_INDEX] = _PyOpcode_RecordFunction_4OS,
|
||||
};
|
||||
@@ -80,6 +80,7 @@ EXCLUDED = format_conf_lines([
|
||||
'Python/generated_cases.c.h',
|
||||
'Python/executor_cases.c.h',
|
||||
'Python/optimizer_cases.c.h',
|
||||
'Python/record_functions.c.h',
|
||||
'Python/opcode_targets.h',
|
||||
'Modules/_testinternalcapi/test_targets.h',
|
||||
'Modules/_testinternalcapi/test_cases.c.h',
|
||||
|
||||
@@ -39,6 +39,7 @@ class Properties:
|
||||
uses_opcode: bool
|
||||
needs_guard_ip: bool
|
||||
unpredictable_jump: bool
|
||||
records_value: bool
|
||||
tier: int | None = None
|
||||
const_oparg: int = -1
|
||||
needs_prev: bool = False
|
||||
@@ -83,6 +84,7 @@ class 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),
|
||||
unpredictable_jump=any(p.unpredictable_jump for p in properties),
|
||||
records_value=any(p.records_value for p in properties),
|
||||
)
|
||||
|
||||
@property
|
||||
@@ -113,6 +115,7 @@ SKIP_PROPERTIES = Properties(
|
||||
no_save_ip=False,
|
||||
needs_guard_ip=False,
|
||||
unpredictable_jump=False,
|
||||
records_value=False,
|
||||
)
|
||||
|
||||
|
||||
@@ -710,6 +713,8 @@ NON_ESCAPING_FUNCTIONS = (
|
||||
"_Py_set_eval_breaker_bit",
|
||||
"trigger_backoff_counter",
|
||||
"_PyThreadState_PopCStackRefSteal",
|
||||
"doesnt_escape",
|
||||
|
||||
)
|
||||
|
||||
|
||||
@@ -999,6 +1004,7 @@ def compute_properties(op: parser.CodeDef) -> Properties:
|
||||
or variable_used(op, "LOAD_IP")
|
||||
or variable_used(op, "DISPATCH_INLINED"),
|
||||
unpredictable_jump=unpredictable_jump,
|
||||
records_value=variable_used(op, "RECORD_VALUE")
|
||||
)
|
||||
|
||||
def expand(items: list[StackItem], oparg: int) -> list[StackItem]:
|
||||
@@ -1124,6 +1130,7 @@ def add_macro(
|
||||
macro: parser.Macro, instructions: dict[str, Instruction], uops: dict[str, Uop]
|
||||
) -> None:
|
||||
parts: list[Part] = []
|
||||
first = True
|
||||
for part in macro.uops:
|
||||
match part:
|
||||
case parser.OpName():
|
||||
@@ -1134,7 +1141,13 @@ def add_macro(
|
||||
raise analysis_error(
|
||||
f"No Uop named {part.name}", macro.tokens[0]
|
||||
)
|
||||
parts.append(uops[part.name])
|
||||
uop = uops[part.name]
|
||||
if uop.properties.records_value and not first:
|
||||
raise analysis_error(
|
||||
f"Recording uop {part.name} must be first in macro",
|
||||
macro.tokens[0])
|
||||
parts.append(uop)
|
||||
first = False
|
||||
case parser.CacheEffect():
|
||||
parts.append(Skip(part.size))
|
||||
case _:
|
||||
|
||||
@@ -788,6 +788,8 @@ def cflags(p: Properties) -> str:
|
||||
flags.append("HAS_UNPREDICTABLE_JUMP_FLAG")
|
||||
if p.needs_guard_ip:
|
||||
flags.append("HAS_NEEDS_GUARD_IP_FLAG")
|
||||
if p.records_value:
|
||||
flags.append("HAS_RECORDS_VALUE_FLAG")
|
||||
if flags:
|
||||
return " | ".join(flags)
|
||||
else:
|
||||
|
||||
@@ -59,6 +59,7 @@ FLAGS = [
|
||||
"PERIODIC",
|
||||
"UNPREDICTABLE_JUMP",
|
||||
"NEEDS_GUARD_IP",
|
||||
"RECORDS_VALUE",
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
|
||||
import argparse
|
||||
|
||||
from analyzer import (
|
||||
Analysis,
|
||||
Instruction,
|
||||
analyze_files,
|
||||
CodeSection,
|
||||
)
|
||||
|
||||
from generators_common import (
|
||||
DEFAULT_INPUT,
|
||||
ROOT,
|
||||
write_header,
|
||||
emit_to,
|
||||
TokenIterator,
|
||||
)
|
||||
|
||||
from cwriter import CWriter
|
||||
|
||||
from tier1_generator import write_uop, Emitter, declare_variable
|
||||
from typing import TextIO
|
||||
from lexer import Token
|
||||
from stack import Stack, Storage
|
||||
|
||||
DEFAULT_OUTPUT = ROOT / "Python/recorder_functions.c.h"
|
||||
|
||||
|
||||
class RecorderEmitter(Emitter):
|
||||
def __init__(self, out: CWriter):
|
||||
super().__init__(out, {})
|
||||
self._replacers["RECORD_VALUE"] = self.record_value
|
||||
|
||||
def record_value(
|
||||
self,
|
||||
tkn: Token,
|
||||
tkn_iter: TokenIterator,
|
||||
uop: CodeSection,
|
||||
storage: Storage,
|
||||
inst: Instruction | None,
|
||||
) -> bool:
|
||||
lparen = next(tkn_iter)
|
||||
self.out.start_line()
|
||||
self.emit("*recorded_value = (PyObject *)")
|
||||
emit_to(self.out, tkn_iter, "RPAREN")
|
||||
next(tkn_iter) # Semi colon
|
||||
self.emit(";\n")
|
||||
self.emit("Py_INCREF(*recorded_value);\n")
|
||||
return True
|
||||
|
||||
|
||||
def generate_recorder_functions(filenames: list[str], analysis: Analysis, out: CWriter) -> None:
|
||||
write_header(__file__, filenames, outfile)
|
||||
outfile.write(
|
||||
"""
|
||||
#ifdef TIER_ONE
|
||||
#error "This file is for Tier 2 only"
|
||||
#endif
|
||||
"""
|
||||
)
|
||||
args = "_PyInterpreterFrame *frame, _PyStackRef *stack_pointer, int oparg, PyObject **recorded_value"
|
||||
emitter = RecorderEmitter(out)
|
||||
func_count = 0
|
||||
nop = analysis.instructions["NOP"]
|
||||
function_table: dict[str, int] = dict()
|
||||
for name, uop in analysis.uops.items():
|
||||
if not uop.properties.records_value:
|
||||
continue
|
||||
func_count += 1
|
||||
out.emit(f"void _PyOpcode_RecordFunction{uop.name[7:]}({args}) {{\n")
|
||||
seen = {"unused"}
|
||||
for var in uop.stack.inputs:
|
||||
if var.used and var.name not in seen:
|
||||
seen.add(var.name)
|
||||
declare_variable(var, out)
|
||||
stack = Stack()
|
||||
write_uop(uop, emitter, 0, stack, nop, False)
|
||||
out.start_line()
|
||||
out.emit("}")
|
||||
out.emit("\n\n")
|
||||
|
||||
def generate_recorder_tables(analysis: Analysis, out: CWriter) -> None:
|
||||
record_function_indexes: dict[str, int] = dict()
|
||||
record_table: dict[str, str] = {}
|
||||
index = 1
|
||||
for inst in analysis.instructions.values():
|
||||
if not inst.properties.records_value:
|
||||
continue
|
||||
for part in inst.parts:
|
||||
if not part.properties.records_value:
|
||||
continue
|
||||
if part.name not in record_function_indexes:
|
||||
record_function_indexes[part.name] = index
|
||||
index += 1
|
||||
record_table[inst.name] = part.name
|
||||
break
|
||||
func_count = len(record_function_indexes)
|
||||
|
||||
for name, index in record_function_indexes.items():
|
||||
out.emit(f"#define {name}_INDEX {index}\n")
|
||||
args = "_PyJitTracerState *tracer, _PyInterpreterFrame *frame, _PyStackRef *stackpointer, int oparg"
|
||||
out.emit("const uint8_t _PyOpcode_RecordFunctionIndices[256] = {\n")
|
||||
for inst_name, record_name in record_table.items():
|
||||
out.emit(f" [{inst_name}] = {record_name}_INDEX,\n")
|
||||
out.emit("};\n\n")
|
||||
out.emit(f"const _Py_RecordFuncPtr _PyOpcode_RecordFunctions[{func_count+1}] = {{\n")
|
||||
out.emit(" [0] = NULL,\n")
|
||||
for name in record_function_indexes:
|
||||
out.emit(f" [{name}_INDEX] = _PyOpcode_RecordFunction{name[7:]},\n")
|
||||
out.emit("};\n")
|
||||
|
||||
|
||||
arg_parser = argparse.ArgumentParser(
|
||||
description="Generate the record functions for the trace recorder.",
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
)
|
||||
|
||||
arg_parser.add_argument(
|
||||
"-o", "--output", type=str, help="Generated code", default=DEFAULT_OUTPUT
|
||||
)
|
||||
|
||||
arg_parser.add_argument(
|
||||
"input", nargs=argparse.REMAINDER, help="Instruction definition file(s)"
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = arg_parser.parse_args()
|
||||
if len(args.input) == 0:
|
||||
args.input.append(DEFAULT_INPUT)
|
||||
data = analyze_files(args.input)
|
||||
with open(args.output, "w") as outfile:
|
||||
out = CWriter(outfile, 0, False)
|
||||
generate_recorder_functions(args.input, data, out)
|
||||
generate_recorder_tables(data, out)
|
||||
@@ -56,7 +56,7 @@ def declare_variables(inst: Instruction, out: CWriter) -> None:
|
||||
raise analysis_error(ex.args[0], inst.where) from None
|
||||
seen = {"unused"}
|
||||
for part in inst.parts:
|
||||
if not isinstance(part, Uop):
|
||||
if not isinstance(part, Uop) or part.properties.records_value:
|
||||
continue
|
||||
for var in part.stack.inputs:
|
||||
if var.used and var.name not in seen:
|
||||
@@ -259,6 +259,8 @@ def generate_tier1_cases(
|
||||
offset = 1 # The instruction itself
|
||||
stack = Stack()
|
||||
for part in inst.parts:
|
||||
if part.properties.records_value:
|
||||
continue
|
||||
# Only emit braces if more than one uop
|
||||
insert_braces = len([p for p in inst.parts if isinstance(p, Uop)]) > 1
|
||||
reachable, offset, stack = write_uop(part, emitter, offset, stack, inst, insert_braces)
|
||||
|
||||
@@ -207,12 +207,10 @@ class Tier2Emitter(Emitter):
|
||||
self.emit(f"SET_CURRENT_CACHED_VALUES({cached_items});\n")
|
||||
|
||||
|
||||
def write_uop(uop: Uop, emitter: Tier2Emitter, stack: Stack, offset_strs: dict[str, tuple[str, str]], cached_items: int = 0) -> tuple[bool, Stack]:
|
||||
def write_uop(uop: Uop, emitter: Tier2Emitter, stack: Stack, cached_items: int = 0) -> tuple[bool, Stack]:
|
||||
locals: dict[str, Local] = {}
|
||||
zero_regs = is_large(uop) or uop.properties.escapes
|
||||
try:
|
||||
if name_offset_pair := offset_strs.get(uop.name):
|
||||
emitter.emit(f"#define OFFSET_OF_{name_offset_pair[0]} ({name_offset_pair[1]})\n")
|
||||
emitter.out.start_line()
|
||||
if uop.properties.oparg:
|
||||
emitter.emit("oparg = CURRENT_OPARG();\n")
|
||||
@@ -237,8 +235,6 @@ def write_uop(uop: Uop, emitter: Tier2Emitter, stack: Stack, offset_strs: dict[s
|
||||
storage.stack._print(emitter.out)
|
||||
emitter.cache_items(storage.stack, cached_items, zero_regs)
|
||||
storage.flush(emitter.out)
|
||||
if name_offset_pair:
|
||||
emitter.emit(f"#undef OFFSET_OF_{name_offset_pair[0]}\n")
|
||||
return reachable, storage.stack
|
||||
except StackError as ex:
|
||||
raise analysis_error(ex.args[0], uop.body.open) from None
|
||||
@@ -251,29 +247,6 @@ def is_for_iter_test(uop: Uop) -> bool:
|
||||
"_GUARD_NOT_EXHAUSTED_TUPLE", "_FOR_ITER_TIER_TWO"
|
||||
)
|
||||
|
||||
def populate_offset_strs(analysis: Analysis) -> dict[str, tuple[str, str]]:
|
||||
offset_strs: dict[str, tuple[str, str]] = {}
|
||||
for name, uop in analysis.uops.items():
|
||||
if not f"_GUARD_IP_{name}" in analysis.uops:
|
||||
continue
|
||||
tkn_iter = uop.body.tokens()
|
||||
found = False
|
||||
offset_str = ""
|
||||
for token in tkn_iter:
|
||||
if token.kind == "IDENTIFIER" and token.text == "LOAD_IP":
|
||||
if found:
|
||||
raise analysis_error("Cannot have two LOAD_IP in a guarded single uop.", uop.body.open)
|
||||
offset = []
|
||||
while token.kind != "SEMI":
|
||||
offset.append(token.text)
|
||||
token = next(tkn_iter)
|
||||
# 1: to remove the LOAD_IP text
|
||||
offset_str = "".join(offset[1:])
|
||||
found = True
|
||||
assert offset_str
|
||||
offset_strs[f"_GUARD_IP_{name}"] = (name, offset_str)
|
||||
return offset_strs
|
||||
|
||||
def generate_tier2(
|
||||
filenames: list[str], analysis: Analysis, outfile: TextIO, lines: bool
|
||||
) -> None:
|
||||
@@ -287,7 +260,6 @@ def generate_tier2(
|
||||
"""
|
||||
)
|
||||
out = CWriter(outfile, 2, lines)
|
||||
offset_strs = populate_offset_strs(analysis)
|
||||
out.emit("\n")
|
||||
|
||||
for name, uop in analysis.uops.items():
|
||||
@@ -295,6 +267,8 @@ def generate_tier2(
|
||||
continue
|
||||
if uop.is_super():
|
||||
continue
|
||||
if uop.properties.records_value:
|
||||
continue
|
||||
why_not_viable = uop.why_not_viable()
|
||||
if why_not_viable is not None:
|
||||
out.emit(
|
||||
@@ -310,7 +284,7 @@ def generate_tier2(
|
||||
stack = Stack()
|
||||
stack.push_cache([f"_tos_cache{i}" for i in range(inputs)], out)
|
||||
stack._print(out)
|
||||
reachable, stack = write_uop(uop, emitter, stack, offset_strs, outputs)
|
||||
reachable, stack = write_uop(uop, emitter, stack, outputs)
|
||||
out.start_line()
|
||||
if reachable:
|
||||
out.emit("assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());\n")
|
||||
|
||||
@@ -51,6 +51,8 @@ def generate_uop_ids(
|
||||
for name, uop in sorted(uops):
|
||||
if uop.properties.tier == 1:
|
||||
continue
|
||||
if uop.properties.records_value:
|
||||
continue
|
||||
for inputs, outputs, _ in sorted(get_uop_cache_depths(uop)):
|
||||
out.emit(f"#define {name}_r{inputs}{outputs} {next_id}\n")
|
||||
next_id += 1
|
||||
|
||||
@@ -28,6 +28,8 @@ DEFAULT_OUTPUT = ROOT / "Include/internal/pycore_uop_metadata.h"
|
||||
def uop_cache_info(uop: Uop) -> list[str] | None:
|
||||
if uop.name == "_SPILL_OR_RELOAD":
|
||||
return None
|
||||
if uop.properties.records_value:
|
||||
return None
|
||||
default = "{ -1, -1, -1 },\n"
|
||||
table_size = MAX_CACHED_REGISTER + 1
|
||||
entries = [ default ] * table_size
|
||||
@@ -96,7 +98,7 @@ def generate_names_and_flags(analysis: Analysis, out: CWriter) -> None:
|
||||
out.emit("};\n\n")
|
||||
out.emit("const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {\n");
|
||||
for uop in analysis.uops.values():
|
||||
if uop.is_viable() and uop.properties.tier != 1 and not uop.is_super():
|
||||
if uop.is_viable() and uop.properties.tier != 1 and not uop.is_super() and not uop.properties.records_value:
|
||||
for inputs, outputs, _ in get_uop_cache_depths(uop):
|
||||
out.emit(f"[{uop.name}_r{inputs}{outputs}] = {uop.name},\n")
|
||||
out.emit("};\n\n")
|
||||
@@ -110,8 +112,9 @@ def generate_names_and_flags(analysis: Analysis, out: CWriter) -> None:
|
||||
for uop in sorted(analysis.uops.values(), key=lambda t: t.name):
|
||||
if uop.is_viable() and uop.properties.tier != 1 and not uop.is_super():
|
||||
out.emit(f'[{uop.name}] = "{uop.name}",\n')
|
||||
for inputs, outputs, _ in get_uop_cache_depths(uop):
|
||||
out.emit(f'[{uop.name}_r{inputs}{outputs}] = "{uop.name}_r{inputs}{outputs}",\n')
|
||||
if not uop.properties.records_value:
|
||||
for inputs, outputs, _ in get_uop_cache_depths(uop):
|
||||
out.emit(f'[{uop.name}_r{inputs}{outputs}] = "{uop.name}_r{inputs}{outputs}",\n')
|
||||
out.emit("};\n")
|
||||
out.emit("int _PyUop_num_popped(int opcode, int oparg)\n{\n")
|
||||
out.emit("switch(opcode) {\n")
|
||||
@@ -132,7 +135,6 @@ def generate_names_and_flags(analysis: Analysis, out: CWriter) -> None:
|
||||
out.emit("}\n\n")
|
||||
out.emit("#endif // NEED_OPCODE_METADATA\n\n")
|
||||
|
||||
|
||||
def generate_uop_metadata(
|
||||
filenames: list[str], analysis: Analysis, outfile: TextIO
|
||||
) -> None:
|
||||
|
||||
Reference in new issue
Block a user