diff --git a/Include/opcode.h b/Include/opcode.h index ff3ffddda2147f..c34907d7c8fc42 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -126,64 +126,63 @@ extern "C" { #define BINARY_SUBSCR_ADAPTIVE 17 #define BINARY_SUBSCR_DICT 18 #define BINARY_SUBSCR_GETITEM 19 -#define BINARY_SUBSCR_LIST_INT 20 -#define BINARY_SUBSCR_TUPLE_INT 21 -#define CALL_ADAPTIVE 22 -#define CALL_PY_EXACT_ARGS 23 -#define CALL_PY_WITH_DEFAULTS 24 -#define COMPARE_OP_ADAPTIVE 26 -#define COMPARE_OP_FLOAT_JUMP 27 -#define COMPARE_OP_INT_JUMP 28 -#define COMPARE_OP_STR_JUMP 29 -#define JUMP_BACKWARD_QUICK 34 -#define LOAD_ATTR_ADAPTIVE 38 -#define LOAD_ATTR_INSTANCE_VALUE 39 -#define LOAD_ATTR_MODULE 40 -#define LOAD_ATTR_SLOT 41 -#define LOAD_ATTR_WITH_HINT 42 -#define LOAD_CONST__LOAD_FAST 43 -#define LOAD_FAST__LOAD_CONST 44 -#define LOAD_FAST__LOAD_FAST 45 -#define LOAD_GLOBAL_ADAPTIVE 46 -#define LOAD_GLOBAL_BUILTIN 47 -#define LOAD_GLOBAL_MODULE 48 -#define LOAD_METHOD_ADAPTIVE 55 -#define LOAD_METHOD_CLASS 56 -#define LOAD_METHOD_MODULE 57 -#define LOAD_METHOD_NO_DICT 58 -#define LOAD_METHOD_WITH_DICT 59 -#define LOAD_METHOD_WITH_VALUES 62 -#define PRECALL_ADAPTIVE 63 -#define PRECALL_BOUND_METHOD 64 -#define PRECALL_BUILTIN_CLASS 65 -#define PRECALL_BUILTIN_FAST_WITH_KEYWORDS 66 -#define PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 67 -#define PRECALL_NO_KW_BUILTIN_FAST 72 -#define PRECALL_NO_KW_BUILTIN_O 73 -#define PRECALL_NO_KW_ISINSTANCE 76 -#define PRECALL_NO_KW_LEN 77 -#define PRECALL_NO_KW_LIST_APPEND 78 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST 79 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 80 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_O 81 -#define PRECALL_NO_KW_STR_1 113 -#define PRECALL_NO_KW_TUPLE_1 121 -#define PRECALL_NO_KW_TYPE_1 127 -#define PRECALL_PYFUNC 141 -#define RESUME_QUICK 143 -#define STORE_ATTR_ADAPTIVE 150 -#define STORE_ATTR_INSTANCE_VALUE 153 -#define STORE_ATTR_SLOT 154 -#define STORE_ATTR_WITH_HINT 158 -#define STORE_FAST__LOAD_FAST 159 -#define STORE_FAST__STORE_FAST 161 -#define STORE_SUBSCR_ADAPTIVE 167 -#define STORE_SUBSCR_DICT 168 -#define STORE_SUBSCR_LIST_INT 169 -#define UNPACK_SEQUENCE_ADAPTIVE 170 -#define UNPACK_SEQUENCE_LIST 173 -#define UNPACK_SEQUENCE_TUPLE 174 -#define UNPACK_SEQUENCE_TWO_TUPLE 175 +#define BINARY_SUBSCR_LIST_OR_TUPLE_INT 20 +#define CALL_ADAPTIVE 21 +#define CALL_PY_EXACT_ARGS 22 +#define CALL_PY_WITH_DEFAULTS 23 +#define COMPARE_OP_ADAPTIVE 24 +#define COMPARE_OP_FLOAT_JUMP 26 +#define COMPARE_OP_INT_JUMP 27 +#define COMPARE_OP_STR_JUMP 28 +#define JUMP_BACKWARD_QUICK 29 +#define LOAD_ATTR_ADAPTIVE 34 +#define LOAD_ATTR_INSTANCE_VALUE 38 +#define LOAD_ATTR_MODULE 39 +#define LOAD_ATTR_SLOT 40 +#define LOAD_ATTR_WITH_HINT 41 +#define LOAD_CONST__LOAD_FAST 42 +#define LOAD_FAST__LOAD_CONST 43 +#define LOAD_FAST__LOAD_FAST 44 +#define LOAD_GLOBAL_ADAPTIVE 45 +#define LOAD_GLOBAL_BUILTIN 46 +#define LOAD_GLOBAL_MODULE 47 +#define LOAD_METHOD_ADAPTIVE 48 +#define LOAD_METHOD_CLASS 55 +#define LOAD_METHOD_MODULE 56 +#define LOAD_METHOD_NO_DICT 57 +#define LOAD_METHOD_WITH_DICT 58 +#define LOAD_METHOD_WITH_VALUES 59 +#define PRECALL_ADAPTIVE 62 +#define PRECALL_BOUND_METHOD 63 +#define PRECALL_BUILTIN_CLASS 64 +#define PRECALL_BUILTIN_FAST_WITH_KEYWORDS 65 +#define PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 66 +#define PRECALL_NO_KW_BUILTIN_FAST 67 +#define PRECALL_NO_KW_BUILTIN_O 72 +#define PRECALL_NO_KW_ISINSTANCE 73 +#define PRECALL_NO_KW_LEN 76 +#define PRECALL_NO_KW_LIST_APPEND 77 +#define PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST 78 +#define PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 79 +#define PRECALL_NO_KW_METHOD_DESCRIPTOR_O 80 +#define PRECALL_NO_KW_STR_1 81 +#define PRECALL_NO_KW_TUPLE_1 113 +#define PRECALL_NO_KW_TYPE_1 121 +#define PRECALL_PYFUNC 127 +#define RESUME_QUICK 141 +#define STORE_ATTR_ADAPTIVE 143 +#define STORE_ATTR_INSTANCE_VALUE 150 +#define STORE_ATTR_SLOT 153 +#define STORE_ATTR_WITH_HINT 154 +#define STORE_FAST__LOAD_FAST 158 +#define STORE_FAST__STORE_FAST 159 +#define STORE_SUBSCR_ADAPTIVE 161 +#define STORE_SUBSCR_DICT 167 +#define STORE_SUBSCR_LIST_INT 168 +#define UNPACK_SEQUENCE_ADAPTIVE 169 +#define UNPACK_SEQUENCE_LIST 170 +#define UNPACK_SEQUENCE_TUPLE 173 +#define UNPACK_SEQUENCE_TWO_TUPLE 174 #define DO_TRACING 255 extern const uint8_t _PyOpcode_Caches[256]; @@ -244,8 +243,7 @@ const uint8_t _PyOpcode_Deopt[256] = { [BINARY_SUBSCR_ADAPTIVE] = BINARY_SUBSCR, [BINARY_SUBSCR_DICT] = BINARY_SUBSCR, [BINARY_SUBSCR_GETITEM] = BINARY_SUBSCR, - [BINARY_SUBSCR_LIST_INT] = BINARY_SUBSCR, - [BINARY_SUBSCR_TUPLE_INT] = BINARY_SUBSCR, + [BINARY_SUBSCR_LIST_OR_TUPLE_INT] = BINARY_SUBSCR, [BUILD_CONST_KEY_MAP] = BUILD_CONST_KEY_MAP, [BUILD_LIST] = BUILD_LIST, [BUILD_MAP] = BUILD_MAP, diff --git a/Lib/opcode.py b/Lib/opcode.py index 97b580532cb94b..8d5b0c88afcc80 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -245,8 +245,7 @@ def jabs_op(name, op, entries=0): "BINARY_SUBSCR_ADAPTIVE", "BINARY_SUBSCR_DICT", "BINARY_SUBSCR_GETITEM", - "BINARY_SUBSCR_LIST_INT", - "BINARY_SUBSCR_TUPLE_INT", + "BINARY_SUBSCR_LIST_OR_TUPLE_INT", ], "CALL": [ "CALL_ADAPTIVE", diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-04-07-19-13-35.bpo-47251.YAMKMr.rst b/Misc/NEWS.d/next/Core and Builtins/2022-04-07-19-13-35.bpo-47251.YAMKMr.rst new file mode 100644 index 00000000000000..50bb3842ce982c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-04-07-19-13-35.bpo-47251.YAMKMr.rst @@ -0,0 +1 @@ +Merge BINARY_SUBSCR_LIST_INT and BINARY_SUBSCR_TUPLE_INT opcodes into BINARY_SUBSCR_LIST_OR_TUPLE_INT . diff --git a/Python/ceval.c b/Python/ceval.c index 5384aac5d6e6cb..4ab016c7a49dff 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2105,52 +2105,34 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } } - TARGET(BINARY_SUBSCR_LIST_INT) { + TARGET(BINARY_SUBSCR_LIST_OR_TUPLE_INT) { assert(cframe.use_tracing == 0); PyObject *sub = TOP(); - PyObject *list = SECOND(); + PyObject *sequence = SECOND(); DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); - DEOPT_IF(!PyList_CheckExact(list), BINARY_SUBSCR); + bool is_list = PyList_CheckExact(sequence); + bool is_tuple = PyTuple_CheckExact(sequence); + DEOPT_IF(!(is_list || is_tuple), BINARY_SUBSCR); - // Deopt unless 0 <= sub < PyList_Size(list) + // Deopt unless 0 <= sub < Py_SIZE(sequence) Py_ssize_t signed_magnitude = Py_SIZE(sub); DEOPT_IF(((size_t)signed_magnitude) > 1, BINARY_SUBSCR); assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0); Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; - DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR); + DEOPT_IF(index >= Py_SIZE(sequence), BINARY_SUBSCR); STAT_INC(BINARY_SUBSCR, hit); - PyObject *res = PyList_GET_ITEM(list, index); - assert(res != NULL); - Py_INCREF(res); - STACK_SHRINK(1); - Py_DECREF(sub); - SET_TOP(res); - Py_DECREF(list); - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); - NOTRACE_DISPATCH(); - } - TARGET(BINARY_SUBSCR_TUPLE_INT) { - assert(cframe.use_tracing == 0); - PyObject *sub = TOP(); - PyObject *tuple = SECOND(); - DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); - DEOPT_IF(!PyTuple_CheckExact(tuple), BINARY_SUBSCR); - - // Deopt unless 0 <= sub < PyTuple_Size(list) - Py_ssize_t signed_magnitude = Py_SIZE(sub); - DEOPT_IF(((size_t)signed_magnitude) > 1, BINARY_SUBSCR); - assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0); - Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; - DEOPT_IF(index >= PyTuple_GET_SIZE(tuple), BINARY_SUBSCR); - STAT_INC(BINARY_SUBSCR, hit); - PyObject *res = PyTuple_GET_ITEM(tuple, index); + PyObject* res; + if (is_list) + res = PyList_GET_ITEM(sequence, index); + else + res = PyTuple_GET_ITEM(sequence, index); assert(res != NULL); Py_INCREF(res); STACK_SHRINK(1); Py_DECREF(sub); SET_TOP(res); - Py_DECREF(tuple); + Py_DECREF(sequence); JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); NOTRACE_DISPATCH(); } diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 064aa060c84284..c64589468a728b 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -19,25 +19,24 @@ static void *opcode_targets[256] = { &&TARGET_BINARY_SUBSCR_ADAPTIVE, &&TARGET_BINARY_SUBSCR_DICT, &&TARGET_BINARY_SUBSCR_GETITEM, - &&TARGET_BINARY_SUBSCR_LIST_INT, - &&TARGET_BINARY_SUBSCR_TUPLE_INT, + &&TARGET_BINARY_SUBSCR_LIST_OR_TUPLE_INT, &&TARGET_CALL_ADAPTIVE, &&TARGET_CALL_PY_EXACT_ARGS, &&TARGET_CALL_PY_WITH_DEFAULTS, - &&TARGET_BINARY_SUBSCR, &&TARGET_COMPARE_OP_ADAPTIVE, + &&TARGET_BINARY_SUBSCR, &&TARGET_COMPARE_OP_FLOAT_JUMP, &&TARGET_COMPARE_OP_INT_JUMP, &&TARGET_COMPARE_OP_STR_JUMP, + &&TARGET_JUMP_BACKWARD_QUICK, &&TARGET_GET_LEN, &&TARGET_MATCH_MAPPING, &&TARGET_MATCH_SEQUENCE, &&TARGET_MATCH_KEYS, - &&TARGET_JUMP_BACKWARD_QUICK, + &&TARGET_LOAD_ATTR_ADAPTIVE, &&TARGET_PUSH_EXC_INFO, &&TARGET_CHECK_EXC_MATCH, &&TARGET_CHECK_EG_MATCH, - &&TARGET_LOAD_ATTR_ADAPTIVE, &&TARGET_LOAD_ATTR_INSTANCE_VALUE, &&TARGET_LOAD_ATTR_MODULE, &&TARGET_LOAD_ATTR_SLOT, @@ -48,39 +47,40 @@ static void *opcode_targets[256] = { &&TARGET_LOAD_GLOBAL_ADAPTIVE, &&TARGET_LOAD_GLOBAL_BUILTIN, &&TARGET_LOAD_GLOBAL_MODULE, + &&TARGET_LOAD_METHOD_ADAPTIVE, &&TARGET_WITH_EXCEPT_START, &&TARGET_GET_AITER, &&TARGET_GET_ANEXT, &&TARGET_BEFORE_ASYNC_WITH, &&TARGET_BEFORE_WITH, &&TARGET_END_ASYNC_FOR, - &&TARGET_LOAD_METHOD_ADAPTIVE, &&TARGET_LOAD_METHOD_CLASS, &&TARGET_LOAD_METHOD_MODULE, &&TARGET_LOAD_METHOD_NO_DICT, &&TARGET_LOAD_METHOD_WITH_DICT, + &&TARGET_LOAD_METHOD_WITH_VALUES, &&TARGET_STORE_SUBSCR, &&TARGET_DELETE_SUBSCR, - &&TARGET_LOAD_METHOD_WITH_VALUES, &&TARGET_PRECALL_ADAPTIVE, &&TARGET_PRECALL_BOUND_METHOD, &&TARGET_PRECALL_BUILTIN_CLASS, &&TARGET_PRECALL_BUILTIN_FAST_WITH_KEYWORDS, &&TARGET_PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, + &&TARGET_PRECALL_NO_KW_BUILTIN_FAST, &&TARGET_GET_ITER, &&TARGET_GET_YIELD_FROM_ITER, &&TARGET_PRINT_EXPR, &&TARGET_LOAD_BUILD_CLASS, - &&TARGET_PRECALL_NO_KW_BUILTIN_FAST, &&TARGET_PRECALL_NO_KW_BUILTIN_O, + &&TARGET_PRECALL_NO_KW_ISINSTANCE, &&TARGET_LOAD_ASSERTION_ERROR, &&TARGET_RETURN_GENERATOR, - &&TARGET_PRECALL_NO_KW_ISINSTANCE, &&TARGET_PRECALL_NO_KW_LEN, &&TARGET_PRECALL_NO_KW_LIST_APPEND, &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST, &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_O, + &&TARGET_PRECALL_NO_KW_STR_1, &&TARGET_LIST_TO_TUPLE, &&TARGET_RETURN_VALUE, &&TARGET_IMPORT_STAR, @@ -112,7 +112,7 @@ static void *opcode_targets[256] = { &&TARGET_JUMP_FORWARD, &&TARGET_JUMP_IF_FALSE_OR_POP, &&TARGET_JUMP_IF_TRUE_OR_POP, - &&TARGET_PRECALL_NO_KW_STR_1, + &&TARGET_PRECALL_NO_KW_TUPLE_1, &&TARGET_POP_JUMP_IF_FALSE, &&TARGET_POP_JUMP_IF_TRUE, &&TARGET_LOAD_GLOBAL, @@ -120,13 +120,13 @@ static void *opcode_targets[256] = { &&TARGET_CONTAINS_OP, &&TARGET_RERAISE, &&TARGET_COPY, - &&TARGET_PRECALL_NO_KW_TUPLE_1, + &&TARGET_PRECALL_NO_KW_TYPE_1, &&TARGET_BINARY_OP, &&TARGET_SEND, &&TARGET_LOAD_FAST, &&TARGET_STORE_FAST, &&TARGET_DELETE_FAST, - &&TARGET_PRECALL_NO_KW_TYPE_1, + &&TARGET_PRECALL_PYFUNC, &&TARGET_POP_JUMP_IF_NOT_NONE, &&TARGET_POP_JUMP_IF_NONE, &&TARGET_RAISE_VARARGS, @@ -140,39 +140,38 @@ static void *opcode_targets[256] = { &&TARGET_STORE_DEREF, &&TARGET_DELETE_DEREF, &&TARGET_JUMP_BACKWARD, - &&TARGET_PRECALL_PYFUNC, - &&TARGET_CALL_FUNCTION_EX, &&TARGET_RESUME_QUICK, + &&TARGET_CALL_FUNCTION_EX, + &&TARGET_STORE_ATTR_ADAPTIVE, &&TARGET_EXTENDED_ARG, &&TARGET_LIST_APPEND, &&TARGET_SET_ADD, &&TARGET_MAP_ADD, &&TARGET_LOAD_CLASSDEREF, &&TARGET_COPY_FREE_VARS, - &&TARGET_STORE_ATTR_ADAPTIVE, + &&TARGET_STORE_ATTR_INSTANCE_VALUE, &&TARGET_RESUME, &&TARGET_MATCH_CLASS, - &&TARGET_STORE_ATTR_INSTANCE_VALUE, &&TARGET_STORE_ATTR_SLOT, + &&TARGET_STORE_ATTR_WITH_HINT, &&TARGET_FORMAT_VALUE, &&TARGET_BUILD_CONST_KEY_MAP, &&TARGET_BUILD_STRING, - &&TARGET_STORE_ATTR_WITH_HINT, &&TARGET_STORE_FAST__LOAD_FAST, - &&TARGET_LOAD_METHOD, &&TARGET_STORE_FAST__STORE_FAST, + &&TARGET_LOAD_METHOD, + &&TARGET_STORE_SUBSCR_ADAPTIVE, &&TARGET_LIST_EXTEND, &&TARGET_SET_UPDATE, &&TARGET_DICT_MERGE, &&TARGET_DICT_UPDATE, &&TARGET_PRECALL, - &&TARGET_STORE_SUBSCR_ADAPTIVE, &&TARGET_STORE_SUBSCR_DICT, &&TARGET_STORE_SUBSCR_LIST_INT, &&TARGET_UNPACK_SEQUENCE_ADAPTIVE, + &&TARGET_UNPACK_SEQUENCE_LIST, &&TARGET_CALL, &&TARGET_KW_NAMES, - &&TARGET_UNPACK_SEQUENCE_LIST, &&TARGET_UNPACK_SEQUENCE_TUPLE, &&TARGET_UNPACK_SEQUENCE_TWO_TUPLE, &&_unknown_opcode, @@ -254,5 +253,6 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, + &&_unknown_opcode, &&TARGET_DO_TRACING }; diff --git a/Python/specialize.c b/Python/specialize.c index 36b05026489cfd..4094fc57d595e3 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -1176,24 +1176,15 @@ _Py_Specialize_BinarySubscr( INLINE_CACHE_ENTRIES_BINARY_SUBSCR); _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)(instr + 1); PyTypeObject *container_type = Py_TYPE(container); - if (container_type == &PyList_Type) { + if (container_type == &PyList_Type || container_type == &PyTuple_Type) { if (PyLong_CheckExact(sub)) { - _Py_SET_OPCODE(*instr, BINARY_SUBSCR_LIST_INT); + _Py_SET_OPCODE(*instr, BINARY_SUBSCR_LIST_OR_TUPLE_INT); goto success; } SPECIALIZATION_FAIL(BINARY_SUBSCR, PySlice_Check(sub) ? SPEC_FAIL_SUBSCR_LIST_SLICE : SPEC_FAIL_OTHER); goto fail; } - if (container_type == &PyTuple_Type) { - if (PyLong_CheckExact(sub)) { - _Py_SET_OPCODE(*instr, BINARY_SUBSCR_TUPLE_INT); - goto success; - } - SPECIALIZATION_FAIL(BINARY_SUBSCR, - PySlice_Check(sub) ? SPEC_FAIL_SUBSCR_TUPLE_SLICE : SPEC_FAIL_OTHER); - goto fail; - } if (container_type == &PyDict_Type) { _Py_SET_OPCODE(*instr, BINARY_SUBSCR_DICT); goto success;