GH-94163: Add BINARY_SLICE and STORE_SLICE instructions. (GH-94168)

This commit is contained in:
Mark Shannon 2022-06-27 12:24:23 +01:00 committed by GitHub
parent 33fc3b5e42
commit c0453a40fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 339 additions and 161 deletions

View File

@ -446,12 +446,13 @@ result back on the stack.
**Binary and in-place operations** **Binary and in-place operations**
Binary operations remove the top of the stack (TOS) and the second top-most In the following, TOS is the top-of-stack.
stack item (TOS1) from the stack. They perform the operation, and put the TOS1, TOS2, TOS3 are the second, thrid and fourth items on the stack, respectively.
result back on the stack.
In-place operations are like binary operations, in that they remove TOS and Binary operations remove the top two items from the stack (TOS and TOS1).
TOS1, and push the result back on the stack, but the operation is done in-place They perform the operation, then put the result back on the stack.
In-place operations are like binary operations, but the operation is done in-place
when TOS1 supports it, and the resulting TOS may be (but does not have to be) when TOS1 supports it, and the resulting TOS may be (but does not have to be)
the original TOS1. the original TOS1.
@ -460,6 +461,7 @@ the original TOS1.
Implements the binary and in-place operators (depending on the value of Implements the binary and in-place operators (depending on the value of
*op*). *op*).
``TOS = TOS1 op TOS``.
.. versionadded:: 3.11 .. versionadded:: 3.11
@ -479,6 +481,20 @@ the original TOS1.
Implements ``del TOS1[TOS]``. Implements ``del TOS1[TOS]``.
.. opcode:: BINARY_SLICE
Implements ``TOS = TOS2[TOS1:TOS]``.
.. versionadded:: 3.12
.. opcode:: STORE_SLICE
Implements ``TOS2[TOS1:TOS] = TOS3``.
.. versionadded:: 3.12
**Coroutine opcodes** **Coroutine opcodes**
.. opcode:: GET_AWAITABLE (where) .. opcode:: GET_AWAITABLE (where)

View File

@ -67,6 +67,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
[BINARY_OP_MULTIPLY_INT] = BINARY_OP, [BINARY_OP_MULTIPLY_INT] = BINARY_OP,
[BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP, [BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP,
[BINARY_OP_SUBTRACT_INT] = BINARY_OP, [BINARY_OP_SUBTRACT_INT] = BINARY_OP,
[BINARY_SLICE] = BINARY_SLICE,
[BINARY_SUBSCR] = BINARY_SUBSCR, [BINARY_SUBSCR] = BINARY_SUBSCR,
[BINARY_SUBSCR_ADAPTIVE] = BINARY_SUBSCR, [BINARY_SUBSCR_ADAPTIVE] = BINARY_SUBSCR,
[BINARY_SUBSCR_DICT] = BINARY_SUBSCR, [BINARY_SUBSCR_DICT] = BINARY_SUBSCR,
@ -218,6 +219,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
[STORE_FAST__STORE_FAST] = STORE_FAST, [STORE_FAST__STORE_FAST] = STORE_FAST,
[STORE_GLOBAL] = STORE_GLOBAL, [STORE_GLOBAL] = STORE_GLOBAL,
[STORE_NAME] = STORE_NAME, [STORE_NAME] = STORE_NAME,
[STORE_SLICE] = STORE_SLICE,
[STORE_SUBSCR] = STORE_SUBSCR, [STORE_SUBSCR] = STORE_SUBSCR,
[STORE_SUBSCR_ADAPTIVE] = STORE_SUBSCR, [STORE_SUBSCR_ADAPTIVE] = STORE_SUBSCR,
[STORE_SUBSCR_DICT] = STORE_SUBSCR, [STORE_SUBSCR_DICT] = STORE_SUBSCR,
@ -251,6 +253,7 @@ const uint8_t _PyOpcode_Original[256] = {
[BINARY_OP_MULTIPLY_INT] = BINARY_OP, [BINARY_OP_MULTIPLY_INT] = BINARY_OP,
[BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP, [BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP,
[BINARY_OP_SUBTRACT_INT] = BINARY_OP, [BINARY_OP_SUBTRACT_INT] = BINARY_OP,
[BINARY_SLICE] = BINARY_SLICE,
[BINARY_SUBSCR] = BINARY_SUBSCR, [BINARY_SUBSCR] = BINARY_SUBSCR,
[BINARY_SUBSCR_ADAPTIVE] = BINARY_SUBSCR, [BINARY_SUBSCR_ADAPTIVE] = BINARY_SUBSCR,
[BINARY_SUBSCR_DICT] = BINARY_SUBSCR, [BINARY_SUBSCR_DICT] = BINARY_SUBSCR,
@ -402,6 +405,7 @@ const uint8_t _PyOpcode_Original[256] = {
[STORE_FAST__STORE_FAST] = STORE_FAST, [STORE_FAST__STORE_FAST] = STORE_FAST,
[STORE_GLOBAL] = STORE_GLOBAL, [STORE_GLOBAL] = STORE_GLOBAL,
[STORE_NAME] = STORE_NAME, [STORE_NAME] = STORE_NAME,
[STORE_SLICE] = STORE_SLICE,
[STORE_SUBSCR] = STORE_SUBSCR, [STORE_SUBSCR] = STORE_SUBSCR,
[STORE_SUBSCR_ADAPTIVE] = STORE_SUBSCR, [STORE_SUBSCR_ADAPTIVE] = STORE_SUBSCR,
[STORE_SUBSCR_DICT] = STORE_SUBSCR, [STORE_SUBSCR_DICT] = STORE_SUBSCR,
@ -450,18 +454,20 @@ static const char *const _PyOpcode_OpName[256] = {
[CALL_PY_EXACT_ARGS] = "CALL_PY_EXACT_ARGS", [CALL_PY_EXACT_ARGS] = "CALL_PY_EXACT_ARGS",
[CALL_PY_WITH_DEFAULTS] = "CALL_PY_WITH_DEFAULTS", [CALL_PY_WITH_DEFAULTS] = "CALL_PY_WITH_DEFAULTS",
[BINARY_SUBSCR] = "BINARY_SUBSCR", [BINARY_SUBSCR] = "BINARY_SUBSCR",
[BINARY_SLICE] = "BINARY_SLICE",
[STORE_SLICE] = "STORE_SLICE",
[CALL_BOUND_METHOD_EXACT_ARGS] = "CALL_BOUND_METHOD_EXACT_ARGS", [CALL_BOUND_METHOD_EXACT_ARGS] = "CALL_BOUND_METHOD_EXACT_ARGS",
[CALL_BUILTIN_CLASS] = "CALL_BUILTIN_CLASS", [CALL_BUILTIN_CLASS] = "CALL_BUILTIN_CLASS",
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = "CALL_BUILTIN_FAST_WITH_KEYWORDS",
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = "CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS",
[GET_LEN] = "GET_LEN", [GET_LEN] = "GET_LEN",
[MATCH_MAPPING] = "MATCH_MAPPING", [MATCH_MAPPING] = "MATCH_MAPPING",
[MATCH_SEQUENCE] = "MATCH_SEQUENCE", [MATCH_SEQUENCE] = "MATCH_SEQUENCE",
[MATCH_KEYS] = "MATCH_KEYS", [MATCH_KEYS] = "MATCH_KEYS",
[CALL_NO_KW_BUILTIN_FAST] = "CALL_NO_KW_BUILTIN_FAST", [CALL_BUILTIN_FAST_WITH_KEYWORDS] = "CALL_BUILTIN_FAST_WITH_KEYWORDS",
[PUSH_EXC_INFO] = "PUSH_EXC_INFO", [PUSH_EXC_INFO] = "PUSH_EXC_INFO",
[CHECK_EXC_MATCH] = "CHECK_EXC_MATCH", [CHECK_EXC_MATCH] = "CHECK_EXC_MATCH",
[CHECK_EG_MATCH] = "CHECK_EG_MATCH", [CHECK_EG_MATCH] = "CHECK_EG_MATCH",
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = "CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS",
[CALL_NO_KW_BUILTIN_FAST] = "CALL_NO_KW_BUILTIN_FAST",
[CALL_NO_KW_BUILTIN_O] = "CALL_NO_KW_BUILTIN_O", [CALL_NO_KW_BUILTIN_O] = "CALL_NO_KW_BUILTIN_O",
[CALL_NO_KW_ISINSTANCE] = "CALL_NO_KW_ISINSTANCE", [CALL_NO_KW_ISINSTANCE] = "CALL_NO_KW_ISINSTANCE",
[CALL_NO_KW_LEN] = "CALL_NO_KW_LEN", [CALL_NO_KW_LEN] = "CALL_NO_KW_LEN",
@ -471,46 +477,44 @@ static const char *const _PyOpcode_OpName[256] = {
[CALL_NO_KW_METHOD_DESCRIPTOR_O] = "CALL_NO_KW_METHOD_DESCRIPTOR_O", [CALL_NO_KW_METHOD_DESCRIPTOR_O] = "CALL_NO_KW_METHOD_DESCRIPTOR_O",
[CALL_NO_KW_STR_1] = "CALL_NO_KW_STR_1", [CALL_NO_KW_STR_1] = "CALL_NO_KW_STR_1",
[CALL_NO_KW_TUPLE_1] = "CALL_NO_KW_TUPLE_1", [CALL_NO_KW_TUPLE_1] = "CALL_NO_KW_TUPLE_1",
[CALL_NO_KW_TYPE_1] = "CALL_NO_KW_TYPE_1",
[COMPARE_OP_ADAPTIVE] = "COMPARE_OP_ADAPTIVE",
[WITH_EXCEPT_START] = "WITH_EXCEPT_START", [WITH_EXCEPT_START] = "WITH_EXCEPT_START",
[GET_AITER] = "GET_AITER", [GET_AITER] = "GET_AITER",
[GET_ANEXT] = "GET_ANEXT", [GET_ANEXT] = "GET_ANEXT",
[BEFORE_ASYNC_WITH] = "BEFORE_ASYNC_WITH", [BEFORE_ASYNC_WITH] = "BEFORE_ASYNC_WITH",
[BEFORE_WITH] = "BEFORE_WITH", [BEFORE_WITH] = "BEFORE_WITH",
[END_ASYNC_FOR] = "END_ASYNC_FOR", [END_ASYNC_FOR] = "END_ASYNC_FOR",
[CALL_NO_KW_TYPE_1] = "CALL_NO_KW_TYPE_1",
[COMPARE_OP_ADAPTIVE] = "COMPARE_OP_ADAPTIVE",
[COMPARE_OP_FLOAT_JUMP] = "COMPARE_OP_FLOAT_JUMP", [COMPARE_OP_FLOAT_JUMP] = "COMPARE_OP_FLOAT_JUMP",
[COMPARE_OP_INT_JUMP] = "COMPARE_OP_INT_JUMP", [COMPARE_OP_INT_JUMP] = "COMPARE_OP_INT_JUMP",
[COMPARE_OP_STR_JUMP] = "COMPARE_OP_STR_JUMP", [COMPARE_OP_STR_JUMP] = "COMPARE_OP_STR_JUMP",
[EXTENDED_ARG_QUICK] = "EXTENDED_ARG_QUICK",
[FOR_ITER_ADAPTIVE] = "FOR_ITER_ADAPTIVE",
[STORE_SUBSCR] = "STORE_SUBSCR", [STORE_SUBSCR] = "STORE_SUBSCR",
[DELETE_SUBSCR] = "DELETE_SUBSCR", [DELETE_SUBSCR] = "DELETE_SUBSCR",
[EXTENDED_ARG_QUICK] = "EXTENDED_ARG_QUICK",
[FOR_ITER_ADAPTIVE] = "FOR_ITER_ADAPTIVE",
[FOR_ITER_LIST] = "FOR_ITER_LIST", [FOR_ITER_LIST] = "FOR_ITER_LIST",
[FOR_ITER_RANGE] = "FOR_ITER_RANGE", [FOR_ITER_RANGE] = "FOR_ITER_RANGE",
[JUMP_BACKWARD_QUICK] = "JUMP_BACKWARD_QUICK", [JUMP_BACKWARD_QUICK] = "JUMP_BACKWARD_QUICK",
[LOAD_ATTR_ADAPTIVE] = "LOAD_ATTR_ADAPTIVE", [LOAD_ATTR_ADAPTIVE] = "LOAD_ATTR_ADAPTIVE",
[LOAD_ATTR_CLASS] = "LOAD_ATTR_CLASS",
[LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE",
[GET_ITER] = "GET_ITER", [GET_ITER] = "GET_ITER",
[GET_YIELD_FROM_ITER] = "GET_YIELD_FROM_ITER", [GET_YIELD_FROM_ITER] = "GET_YIELD_FROM_ITER",
[PRINT_EXPR] = "PRINT_EXPR", [PRINT_EXPR] = "PRINT_EXPR",
[LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS", [LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS",
[LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE", [LOAD_ATTR_CLASS] = "LOAD_ATTR_CLASS",
[LOAD_ATTR_PROPERTY] = "LOAD_ATTR_PROPERTY", [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE",
[LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR", [LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR",
[RETURN_GENERATOR] = "RETURN_GENERATOR", [RETURN_GENERATOR] = "RETURN_GENERATOR",
[LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE",
[LOAD_ATTR_PROPERTY] = "LOAD_ATTR_PROPERTY",
[LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT", [LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT",
[LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT", [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT",
[LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT", [LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT",
[LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT", [LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT",
[LOAD_ATTR_METHOD_WITH_DICT] = "LOAD_ATTR_METHOD_WITH_DICT",
[LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES",
[LIST_TO_TUPLE] = "LIST_TO_TUPLE", [LIST_TO_TUPLE] = "LIST_TO_TUPLE",
[RETURN_VALUE] = "RETURN_VALUE", [RETURN_VALUE] = "RETURN_VALUE",
[IMPORT_STAR] = "IMPORT_STAR", [IMPORT_STAR] = "IMPORT_STAR",
[SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS", [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS",
[LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST", [LOAD_ATTR_METHOD_WITH_DICT] = "LOAD_ATTR_METHOD_WITH_DICT",
[ASYNC_GEN_WRAP] = "ASYNC_GEN_WRAP", [ASYNC_GEN_WRAP] = "ASYNC_GEN_WRAP",
[PREP_RERAISE_STAR] = "PREP_RERAISE_STAR", [PREP_RERAISE_STAR] = "PREP_RERAISE_STAR",
[POP_EXCEPT] = "POP_EXCEPT", [POP_EXCEPT] = "POP_EXCEPT",
@ -537,7 +541,7 @@ static const char *const _PyOpcode_OpName[256] = {
[JUMP_FORWARD] = "JUMP_FORWARD", [JUMP_FORWARD] = "JUMP_FORWARD",
[JUMP_IF_FALSE_OR_POP] = "JUMP_IF_FALSE_OR_POP", [JUMP_IF_FALSE_OR_POP] = "JUMP_IF_FALSE_OR_POP",
[JUMP_IF_TRUE_OR_POP] = "JUMP_IF_TRUE_OR_POP", [JUMP_IF_TRUE_OR_POP] = "JUMP_IF_TRUE_OR_POP",
[LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST", [LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES",
[POP_JUMP_FORWARD_IF_FALSE] = "POP_JUMP_FORWARD_IF_FALSE", [POP_JUMP_FORWARD_IF_FALSE] = "POP_JUMP_FORWARD_IF_FALSE",
[POP_JUMP_FORWARD_IF_TRUE] = "POP_JUMP_FORWARD_IF_TRUE", [POP_JUMP_FORWARD_IF_TRUE] = "POP_JUMP_FORWARD_IF_TRUE",
[LOAD_GLOBAL] = "LOAD_GLOBAL", [LOAD_GLOBAL] = "LOAD_GLOBAL",
@ -545,7 +549,7 @@ static const char *const _PyOpcode_OpName[256] = {
[CONTAINS_OP] = "CONTAINS_OP", [CONTAINS_OP] = "CONTAINS_OP",
[RERAISE] = "RERAISE", [RERAISE] = "RERAISE",
[COPY] = "COPY", [COPY] = "COPY",
[LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST", [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST",
[BINARY_OP] = "BINARY_OP", [BINARY_OP] = "BINARY_OP",
[SEND] = "SEND", [SEND] = "SEND",
[LOAD_FAST] = "LOAD_FAST", [LOAD_FAST] = "LOAD_FAST",
@ -565,9 +569,9 @@ static const char *const _PyOpcode_OpName[256] = {
[STORE_DEREF] = "STORE_DEREF", [STORE_DEREF] = "STORE_DEREF",
[DELETE_DEREF] = "DELETE_DEREF", [DELETE_DEREF] = "DELETE_DEREF",
[JUMP_BACKWARD] = "JUMP_BACKWARD", [JUMP_BACKWARD] = "JUMP_BACKWARD",
[LOAD_GLOBAL_ADAPTIVE] = "LOAD_GLOBAL_ADAPTIVE", [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST",
[CALL_FUNCTION_EX] = "CALL_FUNCTION_EX", [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX",
[LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST",
[EXTENDED_ARG] = "EXTENDED_ARG", [EXTENDED_ARG] = "EXTENDED_ARG",
[LIST_APPEND] = "LIST_APPEND", [LIST_APPEND] = "LIST_APPEND",
[SET_ADD] = "SET_ADD", [SET_ADD] = "SET_ADD",
@ -577,36 +581,36 @@ static const char *const _PyOpcode_OpName[256] = {
[YIELD_VALUE] = "YIELD_VALUE", [YIELD_VALUE] = "YIELD_VALUE",
[RESUME] = "RESUME", [RESUME] = "RESUME",
[MATCH_CLASS] = "MATCH_CLASS", [MATCH_CLASS] = "MATCH_CLASS",
[LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", [LOAD_GLOBAL_ADAPTIVE] = "LOAD_GLOBAL_ADAPTIVE",
[RESUME_QUICK] = "RESUME_QUICK", [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN",
[FORMAT_VALUE] = "FORMAT_VALUE", [FORMAT_VALUE] = "FORMAT_VALUE",
[BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP", [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP",
[BUILD_STRING] = "BUILD_STRING", [BUILD_STRING] = "BUILD_STRING",
[LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE",
[RESUME_QUICK] = "RESUME_QUICK",
[STORE_ATTR_ADAPTIVE] = "STORE_ATTR_ADAPTIVE", [STORE_ATTR_ADAPTIVE] = "STORE_ATTR_ADAPTIVE",
[STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE", [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE",
[STORE_ATTR_SLOT] = "STORE_ATTR_SLOT",
[STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT",
[LIST_EXTEND] = "LIST_EXTEND", [LIST_EXTEND] = "LIST_EXTEND",
[SET_UPDATE] = "SET_UPDATE", [SET_UPDATE] = "SET_UPDATE",
[DICT_MERGE] = "DICT_MERGE", [DICT_MERGE] = "DICT_MERGE",
[DICT_UPDATE] = "DICT_UPDATE", [DICT_UPDATE] = "DICT_UPDATE",
[STORE_ATTR_SLOT] = "STORE_ATTR_SLOT",
[STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT",
[STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST", [STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST",
[STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST", [STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST",
[STORE_SUBSCR_ADAPTIVE] = "STORE_SUBSCR_ADAPTIVE", [STORE_SUBSCR_ADAPTIVE] = "STORE_SUBSCR_ADAPTIVE",
[STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT",
[STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT",
[CALL] = "CALL", [CALL] = "CALL",
[KW_NAMES] = "KW_NAMES", [KW_NAMES] = "KW_NAMES",
[POP_JUMP_BACKWARD_IF_NOT_NONE] = "POP_JUMP_BACKWARD_IF_NOT_NONE", [POP_JUMP_BACKWARD_IF_NOT_NONE] = "POP_JUMP_BACKWARD_IF_NOT_NONE",
[POP_JUMP_BACKWARD_IF_NONE] = "POP_JUMP_BACKWARD_IF_NONE", [POP_JUMP_BACKWARD_IF_NONE] = "POP_JUMP_BACKWARD_IF_NONE",
[POP_JUMP_BACKWARD_IF_FALSE] = "POP_JUMP_BACKWARD_IF_FALSE", [POP_JUMP_BACKWARD_IF_FALSE] = "POP_JUMP_BACKWARD_IF_FALSE",
[POP_JUMP_BACKWARD_IF_TRUE] = "POP_JUMP_BACKWARD_IF_TRUE", [POP_JUMP_BACKWARD_IF_TRUE] = "POP_JUMP_BACKWARD_IF_TRUE",
[STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT",
[STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT",
[UNPACK_SEQUENCE_ADAPTIVE] = "UNPACK_SEQUENCE_ADAPTIVE", [UNPACK_SEQUENCE_ADAPTIVE] = "UNPACK_SEQUENCE_ADAPTIVE",
[UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST", [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST",
[UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE", [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE",
[UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE", [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE",
[181] = "<181>",
[182] = "<182>",
[183] = "<183>", [183] = "<183>",
[184] = "<184>", [184] = "<184>",
[185] = "<185>", [185] = "<185>",
@ -684,8 +688,6 @@ static const char *const _PyOpcode_OpName[256] = {
#endif #endif
#define EXTRA_CASES \ #define EXTRA_CASES \
case 181: \
case 182: \
case 183: \ case 183: \
case 184: \ case 184: \
case 185: \ case 185: \

View File

@ -13,6 +13,8 @@ extern "C" {
extern void _PySlice_Fini(PyInterpreterState *); extern void _PySlice_Fini(PyInterpreterState *);
extern PyObject *
_PyBuildSlice_ConsumeRefs(PyObject *start, PyObject *stop);
#ifdef __cplusplus #ifdef __cplusplus
} }

112
Include/opcode.h generated
View File

@ -17,6 +17,8 @@ extern "C" {
#define UNARY_NOT 12 #define UNARY_NOT 12
#define UNARY_INVERT 15 #define UNARY_INVERT 15
#define BINARY_SUBSCR 25 #define BINARY_SUBSCR 25
#define BINARY_SLICE 26
#define STORE_SLICE 27
#define GET_LEN 30 #define GET_LEN 30
#define MATCH_MAPPING 31 #define MATCH_MAPPING 31
#define MATCH_SEQUENCE 32 #define MATCH_SEQUENCE 32
@ -135,61 +137,61 @@ extern "C" {
#define CALL_ADAPTIVE 22 #define CALL_ADAPTIVE 22
#define CALL_PY_EXACT_ARGS 23 #define CALL_PY_EXACT_ARGS 23
#define CALL_PY_WITH_DEFAULTS 24 #define CALL_PY_WITH_DEFAULTS 24
#define CALL_BOUND_METHOD_EXACT_ARGS 26 #define CALL_BOUND_METHOD_EXACT_ARGS 28
#define CALL_BUILTIN_CLASS 27 #define CALL_BUILTIN_CLASS 29
#define CALL_BUILTIN_FAST_WITH_KEYWORDS 28 #define CALL_BUILTIN_FAST_WITH_KEYWORDS 34
#define CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 29 #define CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 38
#define CALL_NO_KW_BUILTIN_FAST 34 #define CALL_NO_KW_BUILTIN_FAST 39
#define CALL_NO_KW_BUILTIN_O 38 #define CALL_NO_KW_BUILTIN_O 40
#define CALL_NO_KW_ISINSTANCE 39 #define CALL_NO_KW_ISINSTANCE 41
#define CALL_NO_KW_LEN 40 #define CALL_NO_KW_LEN 42
#define CALL_NO_KW_LIST_APPEND 41 #define CALL_NO_KW_LIST_APPEND 43
#define CALL_NO_KW_METHOD_DESCRIPTOR_FAST 42 #define CALL_NO_KW_METHOD_DESCRIPTOR_FAST 44
#define CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 43 #define CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 45
#define CALL_NO_KW_METHOD_DESCRIPTOR_O 44 #define CALL_NO_KW_METHOD_DESCRIPTOR_O 46
#define CALL_NO_KW_STR_1 45 #define CALL_NO_KW_STR_1 47
#define CALL_NO_KW_TUPLE_1 46 #define CALL_NO_KW_TUPLE_1 48
#define CALL_NO_KW_TYPE_1 47 #define CALL_NO_KW_TYPE_1 55
#define COMPARE_OP_ADAPTIVE 48 #define COMPARE_OP_ADAPTIVE 56
#define COMPARE_OP_FLOAT_JUMP 55 #define COMPARE_OP_FLOAT_JUMP 57
#define COMPARE_OP_INT_JUMP 56 #define COMPARE_OP_INT_JUMP 58
#define COMPARE_OP_STR_JUMP 57 #define COMPARE_OP_STR_JUMP 59
#define EXTENDED_ARG_QUICK 58 #define EXTENDED_ARG_QUICK 62
#define FOR_ITER_ADAPTIVE 59 #define FOR_ITER_ADAPTIVE 63
#define FOR_ITER_LIST 62 #define FOR_ITER_LIST 64
#define FOR_ITER_RANGE 63 #define FOR_ITER_RANGE 65
#define JUMP_BACKWARD_QUICK 64 #define JUMP_BACKWARD_QUICK 66
#define LOAD_ATTR_ADAPTIVE 65 #define LOAD_ATTR_ADAPTIVE 67
#define LOAD_ATTR_CLASS 66 #define LOAD_ATTR_CLASS 72
#define LOAD_ATTR_INSTANCE_VALUE 67 #define LOAD_ATTR_INSTANCE_VALUE 73
#define LOAD_ATTR_MODULE 72 #define LOAD_ATTR_MODULE 76
#define LOAD_ATTR_PROPERTY 73 #define LOAD_ATTR_PROPERTY 77
#define LOAD_ATTR_SLOT 76 #define LOAD_ATTR_SLOT 78
#define LOAD_ATTR_WITH_HINT 77 #define LOAD_ATTR_WITH_HINT 79
#define LOAD_ATTR_METHOD_LAZY_DICT 78 #define LOAD_ATTR_METHOD_LAZY_DICT 80
#define LOAD_ATTR_METHOD_NO_DICT 79 #define LOAD_ATTR_METHOD_NO_DICT 81
#define LOAD_ATTR_METHOD_WITH_DICT 80 #define LOAD_ATTR_METHOD_WITH_DICT 86
#define LOAD_ATTR_METHOD_WITH_VALUES 81 #define LOAD_ATTR_METHOD_WITH_VALUES 113
#define LOAD_CONST__LOAD_FAST 86 #define LOAD_CONST__LOAD_FAST 121
#define LOAD_FAST__LOAD_CONST 113 #define LOAD_FAST__LOAD_CONST 141
#define LOAD_FAST__LOAD_FAST 121 #define LOAD_FAST__LOAD_FAST 143
#define LOAD_GLOBAL_ADAPTIVE 141 #define LOAD_GLOBAL_ADAPTIVE 153
#define LOAD_GLOBAL_BUILTIN 143 #define LOAD_GLOBAL_BUILTIN 154
#define LOAD_GLOBAL_MODULE 153 #define LOAD_GLOBAL_MODULE 158
#define RESUME_QUICK 154 #define RESUME_QUICK 159
#define STORE_ATTR_ADAPTIVE 158 #define STORE_ATTR_ADAPTIVE 160
#define STORE_ATTR_INSTANCE_VALUE 159 #define STORE_ATTR_INSTANCE_VALUE 161
#define STORE_ATTR_SLOT 160 #define STORE_ATTR_SLOT 166
#define STORE_ATTR_WITH_HINT 161 #define STORE_ATTR_WITH_HINT 167
#define STORE_FAST__LOAD_FAST 166 #define STORE_FAST__LOAD_FAST 168
#define STORE_FAST__STORE_FAST 167 #define STORE_FAST__STORE_FAST 169
#define STORE_SUBSCR_ADAPTIVE 168 #define STORE_SUBSCR_ADAPTIVE 170
#define STORE_SUBSCR_DICT 169 #define STORE_SUBSCR_DICT 177
#define STORE_SUBSCR_LIST_INT 170 #define STORE_SUBSCR_LIST_INT 178
#define UNPACK_SEQUENCE_ADAPTIVE 177 #define UNPACK_SEQUENCE_ADAPTIVE 179
#define UNPACK_SEQUENCE_LIST 178 #define UNPACK_SEQUENCE_LIST 180
#define UNPACK_SEQUENCE_TUPLE 179 #define UNPACK_SEQUENCE_TUPLE 181
#define UNPACK_SEQUENCE_TWO_TUPLE 180 #define UNPACK_SEQUENCE_TWO_TUPLE 182
#define DO_TRACING 255 #define DO_TRACING 255
#define HAS_CONST(op) (false\ #define HAS_CONST(op) (false\

View File

@ -409,6 +409,7 @@ def _write_atomic(path, data, mode=0o666):
# Python 3.12a1 3503 (Shrink LOAD_METHOD cache) # Python 3.12a1 3503 (Shrink LOAD_METHOD cache)
# Python 3.12a1 3504 (Merge LOAD_METHOD back into LOAD_ATTR) # Python 3.12a1 3504 (Merge LOAD_METHOD back into LOAD_ATTR)
# Python 3.12a1 3505 (Specialization/Cache for FOR_ITER) # Python 3.12a1 3505 (Specialization/Cache for FOR_ITER)
# Python 3.12a1 3506 (Add BINARY_SLICE and STORE_SLICE instructions)
# Python 3.13 will start with 3550 # Python 3.13 will start with 3550
@ -422,7 +423,7 @@ def _write_atomic(path, data, mode=0o666):
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
# in PC/launcher.c must also be updated. # in PC/launcher.c must also be updated.
MAGIC_NUMBER = (3505).to_bytes(2, 'little') + b'\r\n' MAGIC_NUMBER = (3506).to_bytes(2, 'little') + b'\r\n'
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c

View File

@ -66,6 +66,8 @@ def jabs_op(name, op):
def_op('UNARY_INVERT', 15) def_op('UNARY_INVERT', 15)
def_op('BINARY_SUBSCR', 25) def_op('BINARY_SUBSCR', 25)
def_op('BINARY_SLICE', 26)
def_op('STORE_SLICE', 27)
def_op('GET_LEN', 30) def_op('GET_LEN', 30)
def_op('MATCH_MAPPING', 31) def_op('MATCH_MAPPING', 31)

View File

@ -1026,6 +1026,42 @@ def while_not_chained(a, b, c):
for instr in dis.Bytecode(while_not_chained): for instr in dis.Bytecode(while_not_chained):
self.assertNotEqual(instr.opname, "EXTENDED_ARG") self.assertNotEqual(instr.opname, "EXTENDED_ARG")
@support.cpython_only
def test_uses_slice_instructions(self):
def check_op_count(func, op, expected):
actual = 0
for instr in dis.Bytecode(func):
if instr.opname == op:
actual += 1
self.assertEqual(actual, expected)
def load():
return x[a:b] + x [a:] + x[:b] + x[:]
def store():
x[a:b] = y
x [a:] = y
x[:b] = y
x[:] = y
def long_slice():
return x[a:b:c]
def aug():
x[a:b] += y
check_op_count(load, "BINARY_SLICE", 4)
check_op_count(load, "BUILD_SLICE", 0)
check_op_count(store, "STORE_SLICE", 4)
check_op_count(store, "BUILD_SLICE", 0)
check_op_count(long_slice, "BUILD_SLICE", 1)
check_op_count(long_slice, "BINARY_SLICE", 0)
check_op_count(aug, "BINARY_SLICE", 1)
check_op_count(aug, "STORE_SLICE", 1)
check_op_count(aug, "BUILD_SLICE", 0)
@requires_debug_ranges() @requires_debug_ranges()
class TestSourcePositions(unittest.TestCase): class TestSourcePositions(unittest.TestCase):
# Ensure that compiled code snippets have correct line and column numbers # Ensure that compiled code snippets have correct line and column numbers

View File

@ -0,0 +1,5 @@
Add :opcode:`BINARY_SLICE` and :opcode:`STORE_SLICE` instructions for more efficient handling
and better specialization of slicing operations, where the slice is explicit
in the source code.

View File

@ -110,6 +110,37 @@ void _PySlice_Fini(PyInterpreterState *interp)
index is present. index is present.
*/ */
static PySliceObject *
_PyBuildSlice_Consume2(PyObject *start, PyObject *stop, PyObject *step)
{
assert(start != NULL && stop != NULL && step != NULL);
PyInterpreterState *interp = _PyInterpreterState_GET();
PySliceObject *obj;
if (interp->slice_cache != NULL) {
obj = interp->slice_cache;
interp->slice_cache = NULL;
_Py_NewReference((PyObject *)obj);
}
else {
obj = PyObject_GC_New(PySliceObject, &PySlice_Type);
if (obj == NULL) {
goto error;
}
}
obj->start = start;
obj->stop = stop;
obj->step = Py_NewRef(step);
_PyObject_GC_TRACK(obj);
return obj;
error:
Py_DECREF(start);
Py_DECREF(stop);
return NULL;
}
PyObject * PyObject *
PySlice_New(PyObject *start, PyObject *stop, PyObject *step) PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
{ {
@ -122,30 +153,16 @@ PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
if (stop == NULL) { if (stop == NULL) {
stop = Py_None; stop = Py_None;
} }
PyInterpreterState *interp = _PyInterpreterState_GET();
PySliceObject *obj;
if (interp->slice_cache != NULL) {
obj = interp->slice_cache;
interp->slice_cache = NULL;
_Py_NewReference((PyObject *)obj);
}
else {
obj = PyObject_GC_New(PySliceObject, &PySlice_Type);
if (obj == NULL) {
return NULL;
}
}
Py_INCREF(step);
obj->step = step;
Py_INCREF(start); Py_INCREF(start);
obj->start = start;
Py_INCREF(stop); Py_INCREF(stop);
obj->stop = stop; return (PyObject *) _PyBuildSlice_Consume2(start, stop, step);
}
_PyObject_GC_TRACK(obj); PyObject *
return (PyObject *) obj; _PyBuildSlice_ConsumeRefs(PyObject *start, PyObject *stop)
{
assert(start != NULL && stop != NULL);
return (PyObject *)_PyBuildSlice_Consume2(start, stop, Py_None);
} }
PyObject * PyObject *

View File

@ -23,6 +23,7 @@
#include "pycore_pymem.h" // _PyMem_IsPtrFreed() #include "pycore_pymem.h" // _PyMem_IsPtrFreed()
#include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_range.h" // _PyRangeIterObject #include "pycore_range.h" // _PyRangeIterObject
#include "pycore_sliceobject.h" // _PyBuildSlice_ConsumeRefs
#include "pycore_sysmodule.h" // _PySys_Audit() #include "pycore_sysmodule.h" // _PySys_Audit()
#include "pycore_tuple.h" // _PyTuple_ITEMS() #include "pycore_tuple.h" // _PyTuple_ITEMS()
#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS #include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS
@ -2139,6 +2140,46 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
DISPATCH(); DISPATCH();
} }
TARGET(BINARY_SLICE) {
PyObject *stop = POP();
PyObject *start = POP();
PyObject *container = TOP();
PyObject *slice = _PyBuildSlice_ConsumeRefs(start, stop);
if (slice == NULL) {
goto error;
}
PyObject *res = PyObject_GetItem(container, slice);
Py_DECREF(slice);
if (res == NULL) {
goto error;
}
SET_TOP(res);
Py_DECREF(container);
DISPATCH();
}
TARGET(STORE_SLICE) {
PyObject *stop = POP();
PyObject *start = POP();
PyObject *container = TOP();
PyObject *v = SECOND();
PyObject *slice = _PyBuildSlice_ConsumeRefs(start, stop);
if (slice == NULL) {
goto error;
}
int err = PyObject_SetItem(container, slice, v);
Py_DECREF(slice);
if (err) {
goto error;
}
STACK_SHRINK(2);
Py_DECREF(v);
Py_DECREF(container);
DISPATCH();
}
TARGET(BINARY_SUBSCR_ADAPTIVE) { TARGET(BINARY_SUBSCR_ADAPTIVE) {
_PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr; _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache)) { if (ADAPTIVE_COUNTER_IS_ZERO(cache)) {

View File

@ -1030,8 +1030,12 @@ stack_effect(int opcode, int oparg, int jump)
case BINARY_SUBSCR: case BINARY_SUBSCR:
return -1; return -1;
case BINARY_SLICE:
return -2;
case STORE_SUBSCR: case STORE_SUBSCR:
return -3; return -3;
case STORE_SLICE:
return -4;
case DELETE_SUBSCR: case DELETE_SUBSCR:
return -2; return -2;
@ -5864,7 +5868,14 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
} }
break; break;
case Slice_kind: case Slice_kind:
return compiler_slice(c, e); {
int n = compiler_slice(c, e);
if (n == 0) {
return 0;
}
ADDOP_I(c, BUILD_SLICE, n);
break;
}
case Name_kind: case Name_kind:
return compiler_nameop(c, e->v.Name.id, e->v.Name.ctx); return compiler_nameop(c, e->v.Name.id, e->v.Name.ctx);
/* child nodes of List and Tuple will have expr_context set */ /* child nodes of List and Tuple will have expr_context set */
@ -5886,6 +5897,13 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
return res; return res;
} }
static bool
is_two_element_slice(expr_ty s)
{
return s->kind == Slice_kind &&
s->v.Slice.step == NULL;
}
static int static int
compiler_augassign(struct compiler *c, stmt_ty s) compiler_augassign(struct compiler *c, stmt_ty s)
{ {
@ -5906,10 +5924,21 @@ compiler_augassign(struct compiler *c, stmt_ty s)
break; break;
case Subscript_kind: case Subscript_kind:
VISIT(c, expr, e->v.Subscript.value); VISIT(c, expr, e->v.Subscript.value);
if (is_two_element_slice(e->v.Subscript.slice)) {
if (!compiler_slice(c, e->v.Subscript.slice)) {
return 0;
}
ADDOP_I(c, COPY, 3);
ADDOP_I(c, COPY, 3);
ADDOP_I(c, COPY, 3);
ADDOP(c, BINARY_SLICE);
}
else {
VISIT(c, expr, e->v.Subscript.slice); VISIT(c, expr, e->v.Subscript.slice);
ADDOP_I(c, COPY, 2); ADDOP_I(c, COPY, 2);
ADDOP_I(c, COPY, 2); ADDOP_I(c, COPY, 2);
ADDOP(c, BINARY_SUBSCR); ADDOP(c, BINARY_SUBSCR);
}
break; break;
case Name_kind: case Name_kind:
if (!compiler_nameop(c, e->v.Name.id, Load)) if (!compiler_nameop(c, e->v.Name.id, Load))
@ -5936,9 +5965,17 @@ compiler_augassign(struct compiler *c, stmt_ty s)
ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names); ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names);
break; break;
case Subscript_kind: case Subscript_kind:
if (is_two_element_slice(e->v.Subscript.slice)) {
ADDOP_I(c, SWAP, 4);
ADDOP_I(c, SWAP, 3);
ADDOP_I(c, SWAP, 2);
ADDOP(c, STORE_SLICE);
}
else {
ADDOP_I(c, SWAP, 3); ADDOP_I(c, SWAP, 3);
ADDOP_I(c, SWAP, 2); ADDOP_I(c, SWAP, 2);
ADDOP(c, STORE_SUBSCR); ADDOP(c, STORE_SUBSCR);
}
break; break;
case Name_kind: case Name_kind:
return compiler_nameop(c, e->v.Name.id, Store); return compiler_nameop(c, e->v.Name.id, Store);
@ -6146,18 +6183,34 @@ compiler_subscript(struct compiler *c, expr_ty e)
} }
} }
VISIT(c, expr, e->v.Subscript.value);
if (is_two_element_slice(e->v.Subscript.slice) && ctx != Del) {
if (!compiler_slice(c, e->v.Subscript.slice)) {
return 0;
}
if (ctx == Load) {
ADDOP(c, BINARY_SLICE);
}
else {
assert(ctx == Store);
ADDOP(c, STORE_SLICE);
}
}
else {
VISIT(c, expr, e->v.Subscript.slice);
switch (ctx) { switch (ctx) {
case Load: op = BINARY_SUBSCR; break; case Load: op = BINARY_SUBSCR; break;
case Store: op = STORE_SUBSCR; break; case Store: op = STORE_SUBSCR; break;
case Del: op = DELETE_SUBSCR; break; case Del: op = DELETE_SUBSCR; break;
} }
assert(op); assert(op);
VISIT(c, expr, e->v.Subscript.value);
VISIT(c, expr, e->v.Subscript.slice);
ADDOP(c, op); ADDOP(c, op);
}
return 1; return 1;
} }
/* Returns the number of the values emitted,
* thus are needed to build the slice, or 0 if there is an error. */
static int static int
compiler_slice(struct compiler *c, expr_ty s) compiler_slice(struct compiler *c, expr_ty s)
{ {
@ -6183,8 +6236,7 @@ compiler_slice(struct compiler *c, expr_ty s)
n++; n++;
VISIT(c, expr, s->v.Slice.step); VISIT(c, expr, s->v.Slice.step);
} }
ADDOP_I(c, BUILD_SLICE, n); return n;
return 1;
} }

View File

@ -25,18 +25,20 @@ static void *opcode_targets[256] = {
&&TARGET_CALL_PY_EXACT_ARGS, &&TARGET_CALL_PY_EXACT_ARGS,
&&TARGET_CALL_PY_WITH_DEFAULTS, &&TARGET_CALL_PY_WITH_DEFAULTS,
&&TARGET_BINARY_SUBSCR, &&TARGET_BINARY_SUBSCR,
&&TARGET_BINARY_SLICE,
&&TARGET_STORE_SLICE,
&&TARGET_CALL_BOUND_METHOD_EXACT_ARGS, &&TARGET_CALL_BOUND_METHOD_EXACT_ARGS,
&&TARGET_CALL_BUILTIN_CLASS, &&TARGET_CALL_BUILTIN_CLASS,
&&TARGET_CALL_BUILTIN_FAST_WITH_KEYWORDS,
&&TARGET_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS,
&&TARGET_GET_LEN, &&TARGET_GET_LEN,
&&TARGET_MATCH_MAPPING, &&TARGET_MATCH_MAPPING,
&&TARGET_MATCH_SEQUENCE, &&TARGET_MATCH_SEQUENCE,
&&TARGET_MATCH_KEYS, &&TARGET_MATCH_KEYS,
&&TARGET_CALL_NO_KW_BUILTIN_FAST, &&TARGET_CALL_BUILTIN_FAST_WITH_KEYWORDS,
&&TARGET_PUSH_EXC_INFO, &&TARGET_PUSH_EXC_INFO,
&&TARGET_CHECK_EXC_MATCH, &&TARGET_CHECK_EXC_MATCH,
&&TARGET_CHECK_EG_MATCH, &&TARGET_CHECK_EG_MATCH,
&&TARGET_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS,
&&TARGET_CALL_NO_KW_BUILTIN_FAST,
&&TARGET_CALL_NO_KW_BUILTIN_O, &&TARGET_CALL_NO_KW_BUILTIN_O,
&&TARGET_CALL_NO_KW_ISINSTANCE, &&TARGET_CALL_NO_KW_ISINSTANCE,
&&TARGET_CALL_NO_KW_LEN, &&TARGET_CALL_NO_KW_LEN,
@ -46,46 +48,44 @@ static void *opcode_targets[256] = {
&&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_O, &&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_O,
&&TARGET_CALL_NO_KW_STR_1, &&TARGET_CALL_NO_KW_STR_1,
&&TARGET_CALL_NO_KW_TUPLE_1, &&TARGET_CALL_NO_KW_TUPLE_1,
&&TARGET_CALL_NO_KW_TYPE_1,
&&TARGET_COMPARE_OP_ADAPTIVE,
&&TARGET_WITH_EXCEPT_START, &&TARGET_WITH_EXCEPT_START,
&&TARGET_GET_AITER, &&TARGET_GET_AITER,
&&TARGET_GET_ANEXT, &&TARGET_GET_ANEXT,
&&TARGET_BEFORE_ASYNC_WITH, &&TARGET_BEFORE_ASYNC_WITH,
&&TARGET_BEFORE_WITH, &&TARGET_BEFORE_WITH,
&&TARGET_END_ASYNC_FOR, &&TARGET_END_ASYNC_FOR,
&&TARGET_CALL_NO_KW_TYPE_1,
&&TARGET_COMPARE_OP_ADAPTIVE,
&&TARGET_COMPARE_OP_FLOAT_JUMP, &&TARGET_COMPARE_OP_FLOAT_JUMP,
&&TARGET_COMPARE_OP_INT_JUMP, &&TARGET_COMPARE_OP_INT_JUMP,
&&TARGET_COMPARE_OP_STR_JUMP, &&TARGET_COMPARE_OP_STR_JUMP,
&&TARGET_EXTENDED_ARG_QUICK,
&&TARGET_FOR_ITER_ADAPTIVE,
&&TARGET_STORE_SUBSCR, &&TARGET_STORE_SUBSCR,
&&TARGET_DELETE_SUBSCR, &&TARGET_DELETE_SUBSCR,
&&TARGET_EXTENDED_ARG_QUICK,
&&TARGET_FOR_ITER_ADAPTIVE,
&&TARGET_FOR_ITER_LIST, &&TARGET_FOR_ITER_LIST,
&&TARGET_FOR_ITER_RANGE, &&TARGET_FOR_ITER_RANGE,
&&TARGET_JUMP_BACKWARD_QUICK, &&TARGET_JUMP_BACKWARD_QUICK,
&&TARGET_LOAD_ATTR_ADAPTIVE, &&TARGET_LOAD_ATTR_ADAPTIVE,
&&TARGET_LOAD_ATTR_CLASS,
&&TARGET_LOAD_ATTR_INSTANCE_VALUE,
&&TARGET_GET_ITER, &&TARGET_GET_ITER,
&&TARGET_GET_YIELD_FROM_ITER, &&TARGET_GET_YIELD_FROM_ITER,
&&TARGET_PRINT_EXPR, &&TARGET_PRINT_EXPR,
&&TARGET_LOAD_BUILD_CLASS, &&TARGET_LOAD_BUILD_CLASS,
&&TARGET_LOAD_ATTR_MODULE, &&TARGET_LOAD_ATTR_CLASS,
&&TARGET_LOAD_ATTR_PROPERTY, &&TARGET_LOAD_ATTR_INSTANCE_VALUE,
&&TARGET_LOAD_ASSERTION_ERROR, &&TARGET_LOAD_ASSERTION_ERROR,
&&TARGET_RETURN_GENERATOR, &&TARGET_RETURN_GENERATOR,
&&TARGET_LOAD_ATTR_MODULE,
&&TARGET_LOAD_ATTR_PROPERTY,
&&TARGET_LOAD_ATTR_SLOT, &&TARGET_LOAD_ATTR_SLOT,
&&TARGET_LOAD_ATTR_WITH_HINT, &&TARGET_LOAD_ATTR_WITH_HINT,
&&TARGET_LOAD_ATTR_METHOD_LAZY_DICT, &&TARGET_LOAD_ATTR_METHOD_LAZY_DICT,
&&TARGET_LOAD_ATTR_METHOD_NO_DICT, &&TARGET_LOAD_ATTR_METHOD_NO_DICT,
&&TARGET_LOAD_ATTR_METHOD_WITH_DICT,
&&TARGET_LOAD_ATTR_METHOD_WITH_VALUES,
&&TARGET_LIST_TO_TUPLE, &&TARGET_LIST_TO_TUPLE,
&&TARGET_RETURN_VALUE, &&TARGET_RETURN_VALUE,
&&TARGET_IMPORT_STAR, &&TARGET_IMPORT_STAR,
&&TARGET_SETUP_ANNOTATIONS, &&TARGET_SETUP_ANNOTATIONS,
&&TARGET_LOAD_CONST__LOAD_FAST, &&TARGET_LOAD_ATTR_METHOD_WITH_DICT,
&&TARGET_ASYNC_GEN_WRAP, &&TARGET_ASYNC_GEN_WRAP,
&&TARGET_PREP_RERAISE_STAR, &&TARGET_PREP_RERAISE_STAR,
&&TARGET_POP_EXCEPT, &&TARGET_POP_EXCEPT,
@ -112,7 +112,7 @@ static void *opcode_targets[256] = {
&&TARGET_JUMP_FORWARD, &&TARGET_JUMP_FORWARD,
&&TARGET_JUMP_IF_FALSE_OR_POP, &&TARGET_JUMP_IF_FALSE_OR_POP,
&&TARGET_JUMP_IF_TRUE_OR_POP, &&TARGET_JUMP_IF_TRUE_OR_POP,
&&TARGET_LOAD_FAST__LOAD_CONST, &&TARGET_LOAD_ATTR_METHOD_WITH_VALUES,
&&TARGET_POP_JUMP_FORWARD_IF_FALSE, &&TARGET_POP_JUMP_FORWARD_IF_FALSE,
&&TARGET_POP_JUMP_FORWARD_IF_TRUE, &&TARGET_POP_JUMP_FORWARD_IF_TRUE,
&&TARGET_LOAD_GLOBAL, &&TARGET_LOAD_GLOBAL,
@ -120,7 +120,7 @@ static void *opcode_targets[256] = {
&&TARGET_CONTAINS_OP, &&TARGET_CONTAINS_OP,
&&TARGET_RERAISE, &&TARGET_RERAISE,
&&TARGET_COPY, &&TARGET_COPY,
&&TARGET_LOAD_FAST__LOAD_FAST, &&TARGET_LOAD_CONST__LOAD_FAST,
&&TARGET_BINARY_OP, &&TARGET_BINARY_OP,
&&TARGET_SEND, &&TARGET_SEND,
&&TARGET_LOAD_FAST, &&TARGET_LOAD_FAST,
@ -140,9 +140,9 @@ static void *opcode_targets[256] = {
&&TARGET_STORE_DEREF, &&TARGET_STORE_DEREF,
&&TARGET_DELETE_DEREF, &&TARGET_DELETE_DEREF,
&&TARGET_JUMP_BACKWARD, &&TARGET_JUMP_BACKWARD,
&&TARGET_LOAD_GLOBAL_ADAPTIVE, &&TARGET_LOAD_FAST__LOAD_CONST,
&&TARGET_CALL_FUNCTION_EX, &&TARGET_CALL_FUNCTION_EX,
&&TARGET_LOAD_GLOBAL_BUILTIN, &&TARGET_LOAD_FAST__LOAD_FAST,
&&TARGET_EXTENDED_ARG, &&TARGET_EXTENDED_ARG,
&&TARGET_LIST_APPEND, &&TARGET_LIST_APPEND,
&&TARGET_SET_ADD, &&TARGET_SET_ADD,
@ -152,30 +152,32 @@ static void *opcode_targets[256] = {
&&TARGET_YIELD_VALUE, &&TARGET_YIELD_VALUE,
&&TARGET_RESUME, &&TARGET_RESUME,
&&TARGET_MATCH_CLASS, &&TARGET_MATCH_CLASS,
&&TARGET_LOAD_GLOBAL_MODULE, &&TARGET_LOAD_GLOBAL_ADAPTIVE,
&&TARGET_RESUME_QUICK, &&TARGET_LOAD_GLOBAL_BUILTIN,
&&TARGET_FORMAT_VALUE, &&TARGET_FORMAT_VALUE,
&&TARGET_BUILD_CONST_KEY_MAP, &&TARGET_BUILD_CONST_KEY_MAP,
&&TARGET_BUILD_STRING, &&TARGET_BUILD_STRING,
&&TARGET_LOAD_GLOBAL_MODULE,
&&TARGET_RESUME_QUICK,
&&TARGET_STORE_ATTR_ADAPTIVE, &&TARGET_STORE_ATTR_ADAPTIVE,
&&TARGET_STORE_ATTR_INSTANCE_VALUE, &&TARGET_STORE_ATTR_INSTANCE_VALUE,
&&TARGET_STORE_ATTR_SLOT,
&&TARGET_STORE_ATTR_WITH_HINT,
&&TARGET_LIST_EXTEND, &&TARGET_LIST_EXTEND,
&&TARGET_SET_UPDATE, &&TARGET_SET_UPDATE,
&&TARGET_DICT_MERGE, &&TARGET_DICT_MERGE,
&&TARGET_DICT_UPDATE, &&TARGET_DICT_UPDATE,
&&TARGET_STORE_ATTR_SLOT,
&&TARGET_STORE_ATTR_WITH_HINT,
&&TARGET_STORE_FAST__LOAD_FAST, &&TARGET_STORE_FAST__LOAD_FAST,
&&TARGET_STORE_FAST__STORE_FAST, &&TARGET_STORE_FAST__STORE_FAST,
&&TARGET_STORE_SUBSCR_ADAPTIVE, &&TARGET_STORE_SUBSCR_ADAPTIVE,
&&TARGET_STORE_SUBSCR_DICT,
&&TARGET_STORE_SUBSCR_LIST_INT,
&&TARGET_CALL, &&TARGET_CALL,
&&TARGET_KW_NAMES, &&TARGET_KW_NAMES,
&&TARGET_POP_JUMP_BACKWARD_IF_NOT_NONE, &&TARGET_POP_JUMP_BACKWARD_IF_NOT_NONE,
&&TARGET_POP_JUMP_BACKWARD_IF_NONE, &&TARGET_POP_JUMP_BACKWARD_IF_NONE,
&&TARGET_POP_JUMP_BACKWARD_IF_FALSE, &&TARGET_POP_JUMP_BACKWARD_IF_FALSE,
&&TARGET_POP_JUMP_BACKWARD_IF_TRUE, &&TARGET_POP_JUMP_BACKWARD_IF_TRUE,
&&TARGET_STORE_SUBSCR_DICT,
&&TARGET_STORE_SUBSCR_LIST_INT,
&&TARGET_UNPACK_SEQUENCE_ADAPTIVE, &&TARGET_UNPACK_SEQUENCE_ADAPTIVE,
&&TARGET_UNPACK_SEQUENCE_LIST, &&TARGET_UNPACK_SEQUENCE_LIST,
&&TARGET_UNPACK_SEQUENCE_TUPLE, &&TARGET_UNPACK_SEQUENCE_TUPLE,
@ -252,7 +254,5 @@ static void *opcode_targets[256] = {
&&_unknown_opcode, &&_unknown_opcode,
&&_unknown_opcode, &&_unknown_opcode,
&&_unknown_opcode, &&_unknown_opcode,
&&_unknown_opcode,
&&_unknown_opcode,
&&TARGET_DO_TRACING &&TARGET_DO_TRACING
}; };

View File

@ -140,7 +140,8 @@ print_spec_stats(FILE *out, OpcodeStats *stats)
{ {
/* Mark some opcodes as specializable for stats, /* Mark some opcodes as specializable for stats,
* even though we don't specialize them yet. */ * even though we don't specialize them yet. */
fprintf(out, "opcode[%d].specializable : 1\n", FOR_ITER); fprintf(out, "opcode[%d].specializable : 1\n", BINARY_SLICE);
fprintf(out, "opcode[%d].specializable : 1\n", STORE_SLICE);
for (int i = 0; i < 256; i++) { for (int i = 0; i < 256; i++) {
if (_PyOpcode_Adaptive[i]) { if (_PyOpcode_Adaptive[i]) {
fprintf(out, "opcode[%d].specializable : 1\n", i); fprintf(out, "opcode[%d].specializable : 1\n", i);

View File

@ -60,6 +60,7 @@ def print_specialization_stats(name, family_stats, defines):
for key in ("specialization.success", "specialization.failure"): for key in ("specialization.success", "specialization.failure"):
total_attempts += family_stats.get(key, 0) total_attempts += family_stats.get(key, 0)
rows = [] rows = []
if total_attempts:
for key in ("specialization.success", "specialization.failure"): for key in ("specialization.success", "specialization.failure"):
label = key[len("specialization."):] label = key[len("specialization."):]
label = label[0].upper() + label[1:] label = label[0].upper() + label[1:]