]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-107596: Specialize str[int] (GH-107597)
authorBrandt Bucher <brandtbucher@microsoft.com>
Tue, 8 Aug 2023 20:42:43 +0000 (13:42 -0700)
committerGitHub <noreply@github.com>
Tue, 8 Aug 2023 20:42:43 +0000 (13:42 -0700)
Include/internal/pycore_opcode.h
Include/internal/pycore_opcode_metadata.h
Include/opcode.h
Lib/_opcode_metadata.py
Misc/NEWS.d/next/Core and Builtins/2023-08-03-11-13-09.gh-issue-107596.T3yPGI.rst [new file with mode: 0644]
Python/bytecodes.c
Python/executor_cases.c.h
Python/generated_cases.c.h
Python/opcode_targets.h
Python/specialize.c

index aff09a2a926aecede6383e22654f8bdb23a10d02..a187da6e24730fd8eb5ef4901afb969e48b07b82 100644 (file)
@@ -52,6 +52,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
     [BINARY_SUBSCR_DICT] = BINARY_SUBSCR,
     [BINARY_SUBSCR_GETITEM] = BINARY_SUBSCR,
     [BINARY_SUBSCR_LIST_INT] = BINARY_SUBSCR,
+    [BINARY_SUBSCR_STR_INT] = BINARY_SUBSCR,
     [BINARY_SUBSCR_TUPLE_INT] = BINARY_SUBSCR,
     [BUILD_CONST_KEY_MAP] = BUILD_CONST_KEY_MAP,
     [BUILD_LIST] = BUILD_LIST,
@@ -292,12 +293,12 @@ const char *const _PyOpcode_OpName[268] = {
     [FORMAT_SIMPLE] = "FORMAT_SIMPLE",
     [FORMAT_WITH_SPEC] = "FORMAT_WITH_SPEC",
     [BINARY_SUBSCR_LIST_INT] = "BINARY_SUBSCR_LIST_INT",
+    [BINARY_SUBSCR_STR_INT] = "BINARY_SUBSCR_STR_INT",
     [BINARY_SUBSCR_TUPLE_INT] = "BINARY_SUBSCR_TUPLE_INT",
     [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT",
     [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT",
     [SEND_GEN] = "SEND_GEN",
     [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE",
-    [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE",
     [WITH_EXCEPT_START] = "WITH_EXCEPT_START",
     [GET_AITER] = "GET_AITER",
     [GET_ANEXT] = "GET_ANEXT",
@@ -305,39 +306,39 @@ const char *const _PyOpcode_OpName[268] = {
     [BEFORE_WITH] = "BEFORE_WITH",
     [END_ASYNC_FOR] = "END_ASYNC_FOR",
     [CLEANUP_THROW] = "CLEANUP_THROW",
+    [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE",
     [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST",
     [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE",
     [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT",
-    [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT",
     [STORE_SUBSCR] = "STORE_SUBSCR",
     [DELETE_SUBSCR] = "DELETE_SUBSCR",
+    [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT",
     [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE",
     [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN",
     [LOAD_SUPER_ATTR_ATTR] = "LOAD_SUPER_ATTR_ATTR",
     [LOAD_SUPER_ATTR_METHOD] = "LOAD_SUPER_ATTR_METHOD",
     [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE",
-    [LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE",
     [GET_ITER] = "GET_ITER",
     [GET_YIELD_FROM_ITER] = "GET_YIELD_FROM_ITER",
-    [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT",
+    [LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE",
     [LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS",
+    [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT",
     [LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT",
-    [LOAD_ATTR_CLASS] = "LOAD_ATTR_CLASS",
     [LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR",
     [RETURN_GENERATOR] = "RETURN_GENERATOR",
+    [LOAD_ATTR_CLASS] = "LOAD_ATTR_CLASS",
     [LOAD_ATTR_PROPERTY] = "LOAD_ATTR_PROPERTY",
     [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN",
     [LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES",
     [LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT",
     [LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT",
     [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES",
-    [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "LOAD_ATTR_NONDESCRIPTOR_NO_DICT",
     [RETURN_VALUE] = "RETURN_VALUE",
-    [COMPARE_OP_FLOAT] = "COMPARE_OP_FLOAT",
+    [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "LOAD_ATTR_NONDESCRIPTOR_NO_DICT",
     [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS",
-    [COMPARE_OP_INT] = "COMPARE_OP_INT",
+    [COMPARE_OP_FLOAT] = "COMPARE_OP_FLOAT",
     [LOAD_LOCALS] = "LOAD_LOCALS",
-    [COMPARE_OP_STR] = "COMPARE_OP_STR",
+    [COMPARE_OP_INT] = "COMPARE_OP_INT",
     [POP_EXCEPT] = "POP_EXCEPT",
     [STORE_NAME] = "STORE_NAME",
     [DELETE_NAME] = "DELETE_NAME",
@@ -360,9 +361,9 @@ const char *const _PyOpcode_OpName[268] = {
     [IMPORT_NAME] = "IMPORT_NAME",
     [IMPORT_FROM] = "IMPORT_FROM",
     [JUMP_FORWARD] = "JUMP_FORWARD",
+    [COMPARE_OP_STR] = "COMPARE_OP_STR",
     [FOR_ITER_LIST] = "FOR_ITER_LIST",
     [FOR_ITER_TUPLE] = "FOR_ITER_TUPLE",
-    [FOR_ITER_RANGE] = "FOR_ITER_RANGE",
     [POP_JUMP_IF_FALSE] = "POP_JUMP_IF_FALSE",
     [POP_JUMP_IF_TRUE] = "POP_JUMP_IF_TRUE",
     [LOAD_GLOBAL] = "LOAD_GLOBAL",
@@ -381,11 +382,11 @@ const char *const _PyOpcode_OpName[268] = {
     [POP_JUMP_IF_NONE] = "POP_JUMP_IF_NONE",
     [RAISE_VARARGS] = "RAISE_VARARGS",
     [GET_AWAITABLE] = "GET_AWAITABLE",
-    [FOR_ITER_GEN] = "FOR_ITER_GEN",
+    [FOR_ITER_RANGE] = "FOR_ITER_RANGE",
     [BUILD_SLICE] = "BUILD_SLICE",
     [JUMP_BACKWARD_NO_INTERRUPT] = "JUMP_BACKWARD_NO_INTERRUPT",
     [MAKE_CELL] = "MAKE_CELL",
-    [CALL_BOUND_METHOD_EXACT_ARGS] = "CALL_BOUND_METHOD_EXACT_ARGS",
+    [FOR_ITER_GEN] = "FOR_ITER_GEN",
     [LOAD_DEREF] = "LOAD_DEREF",
     [STORE_DEREF] = "STORE_DEREF",
     [DELETE_DEREF] = "DELETE_DEREF",
@@ -397,26 +398,26 @@ const char *const _PyOpcode_OpName[268] = {
     [LIST_APPEND] = "LIST_APPEND",
     [SET_ADD] = "SET_ADD",
     [MAP_ADD] = "MAP_ADD",
-    [CALL_PY_EXACT_ARGS] = "CALL_PY_EXACT_ARGS",
+    [CALL_BOUND_METHOD_EXACT_ARGS] = "CALL_BOUND_METHOD_EXACT_ARGS",
     [COPY_FREE_VARS] = "COPY_FREE_VARS",
     [YIELD_VALUE] = "YIELD_VALUE",
     [RESUME] = "RESUME",
     [MATCH_CLASS] = "MATCH_CLASS",
+    [CALL_PY_EXACT_ARGS] = "CALL_PY_EXACT_ARGS",
     [CALL_PY_WITH_DEFAULTS] = "CALL_PY_WITH_DEFAULTS",
     [CALL_NO_KW_TYPE_1] = "CALL_NO_KW_TYPE_1",
-    [CALL_NO_KW_STR_1] = "CALL_NO_KW_STR_1",
     [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP",
     [BUILD_STRING] = "BUILD_STRING",
     [CONVERT_VALUE] = "CONVERT_VALUE",
+    [CALL_NO_KW_STR_1] = "CALL_NO_KW_STR_1",
     [CALL_NO_KW_TUPLE_1] = "CALL_NO_KW_TUPLE_1",
     [CALL_BUILTIN_CLASS] = "CALL_BUILTIN_CLASS",
-    [CALL_NO_KW_BUILTIN_O] = "CALL_NO_KW_BUILTIN_O",
     [LIST_EXTEND] = "LIST_EXTEND",
     [SET_UPDATE] = "SET_UPDATE",
     [DICT_MERGE] = "DICT_MERGE",
     [DICT_UPDATE] = "DICT_UPDATE",
+    [CALL_NO_KW_BUILTIN_O] = "CALL_NO_KW_BUILTIN_O",
     [CALL_NO_KW_BUILTIN_FAST] = "CALL_NO_KW_BUILTIN_FAST",
-    [CALL_BUILTIN_FAST_WITH_KEYWORDS] = "CALL_BUILTIN_FAST_WITH_KEYWORDS",
     [LOAD_FAST_LOAD_FAST] = "LOAD_FAST_LOAD_FAST",
     [STORE_FAST_LOAD_FAST] = "STORE_FAST_LOAD_FAST",
     [STORE_FAST_STORE_FAST] = "STORE_FAST_STORE_FAST",
@@ -427,6 +428,7 @@ const char *const _PyOpcode_OpName[268] = {
     [LOAD_FROM_DICT_OR_GLOBALS] = "LOAD_FROM_DICT_OR_GLOBALS",
     [LOAD_FROM_DICT_OR_DEREF] = "LOAD_FROM_DICT_OR_DEREF",
     [SET_FUNCTION_ATTRIBUTE] = "SET_FUNCTION_ATTRIBUTE",
+    [CALL_BUILTIN_FAST_WITH_KEYWORDS] = "CALL_BUILTIN_FAST_WITH_KEYWORDS",
     [CALL_NO_KW_LEN] = "CALL_NO_KW_LEN",
     [CALL_NO_KW_ISINSTANCE] = "CALL_NO_KW_ISINSTANCE",
     [CALL_NO_KW_LIST_APPEND] = "CALL_NO_KW_LIST_APPEND",
@@ -435,7 +437,6 @@ const char *const _PyOpcode_OpName[268] = {
     [CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = "CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS",
     [CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = "CALL_NO_KW_METHOD_DESCRIPTOR_FAST",
     [CALL_NO_KW_ALLOC_AND_ENTER_INIT] = "CALL_NO_KW_ALLOC_AND_ENTER_INIT",
-    [186] = "<186>",
     [187] = "<187>",
     [188] = "<188>",
     [189] = "<189>",
@@ -521,7 +522,6 @@ const char *const _PyOpcode_OpName[268] = {
 #endif   // NEED_OPCODE_TABLES
 
 #define EXTRA_CASES \
-    case 186: \
     case 187: \
     case 188: \
     case 189: \
index 1cab6c984f3ace08809faaf50fbe0140e1a8176f..02303c42c75c8a4736e6c094596749b515c922d4 100644 (file)
@@ -144,6 +144,8 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
             return 4;
         case BINARY_SUBSCR_LIST_INT:
             return 2;
+        case BINARY_SUBSCR_STR_INT:
+            return 2;
         case BINARY_SUBSCR_TUPLE_INT:
             return 2;
         case BINARY_SUBSCR_DICT:
@@ -588,6 +590,8 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
             return 0;
         case BINARY_SUBSCR_LIST_INT:
             return 1;
+        case BINARY_SUBSCR_STR_INT:
+            return 1;
         case BINARY_SUBSCR_TUPLE_INT:
             return 1;
         case BINARY_SUBSCR_DICT:
@@ -1047,6 +1051,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
     [BINARY_SLICE] = { true, INSTR_FMT_IX, 0 },
     [STORE_SLICE] = { true, INSTR_FMT_IX, 0 },
     [BINARY_SUBSCR_LIST_INT] = { true, INSTR_FMT_IXC, 0 },
+    [BINARY_SUBSCR_STR_INT] = { true, INSTR_FMT_IXC, 0 },
     [BINARY_SUBSCR_TUPLE_INT] = { true, INSTR_FMT_IXC, 0 },
     [BINARY_SUBSCR_DICT] = { true, INSTR_FMT_IXC, 0 },
     [BINARY_SUBSCR_GETITEM] = { true, INSTR_FMT_IXC, 0 },
@@ -1258,6 +1263,7 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN
     [BINARY_SLICE] = { .nuops = 1, .uops = { { BINARY_SLICE, 0, 0 } } },
     [STORE_SLICE] = { .nuops = 1, .uops = { { STORE_SLICE, 0, 0 } } },
     [BINARY_SUBSCR_LIST_INT] = { .nuops = 1, .uops = { { BINARY_SUBSCR_LIST_INT, 0, 0 } } },
+    [BINARY_SUBSCR_STR_INT] = { .nuops = 1, .uops = { { BINARY_SUBSCR_STR_INT, 0, 0 } } },
     [BINARY_SUBSCR_TUPLE_INT] = { .nuops = 1, .uops = { { BINARY_SUBSCR_TUPLE_INT, 0, 0 } } },
     [BINARY_SUBSCR_DICT] = { .nuops = 1, .uops = { { BINARY_SUBSCR_DICT, 0, 0 } } },
     [LIST_APPEND] = { .nuops = 1, .uops = { { LIST_APPEND, 0, 0 } } },
index ede1518b6fd25c9604d292faebc26bbeee73c536..b3d6cba63096c8fd2407f1004d08dc1f315d300c 100644 (file)
@@ -175,57 +175,58 @@ extern "C" {
 #define BINARY_SUBSCR_DICT                      38
 #define BINARY_SUBSCR_GETITEM                   39
 #define BINARY_SUBSCR_LIST_INT                  42
-#define BINARY_SUBSCR_TUPLE_INT                 43
-#define STORE_SUBSCR_DICT                       44
-#define STORE_SUBSCR_LIST_INT                   45
-#define SEND_GEN                                46
-#define UNPACK_SEQUENCE_TWO_TUPLE               47
-#define UNPACK_SEQUENCE_TUPLE                   48
-#define UNPACK_SEQUENCE_LIST                    56
-#define STORE_ATTR_INSTANCE_VALUE               57
-#define STORE_ATTR_SLOT                         58
-#define STORE_ATTR_WITH_HINT                    59
-#define LOAD_GLOBAL_MODULE                      62
-#define LOAD_GLOBAL_BUILTIN                     63
-#define LOAD_SUPER_ATTR_ATTR                    64
-#define LOAD_SUPER_ATTR_METHOD                  65
-#define LOAD_ATTR_INSTANCE_VALUE                66
-#define LOAD_ATTR_MODULE                        67
-#define LOAD_ATTR_WITH_HINT                     70
-#define LOAD_ATTR_SLOT                          72
-#define LOAD_ATTR_CLASS                         73
-#define LOAD_ATTR_PROPERTY                      76
-#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN       77
-#define LOAD_ATTR_METHOD_WITH_VALUES            78
-#define LOAD_ATTR_METHOD_NO_DICT                79
-#define LOAD_ATTR_METHOD_LAZY_DICT              80
-#define LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES     81
-#define LOAD_ATTR_NONDESCRIPTOR_NO_DICT         82
-#define COMPARE_OP_FLOAT                        84
-#define COMPARE_OP_INT                          86
-#define COMPARE_OP_STR                          88
-#define FOR_ITER_LIST                          111
-#define FOR_ITER_TUPLE                         112
-#define FOR_ITER_RANGE                         113
-#define FOR_ITER_GEN                           132
-#define CALL_BOUND_METHOD_EXACT_ARGS           136
-#define CALL_PY_EXACT_ARGS                     148
-#define CALL_PY_WITH_DEFAULTS                  153
-#define CALL_NO_KW_TYPE_1                      154
-#define CALL_NO_KW_STR_1                       155
-#define CALL_NO_KW_TUPLE_1                     159
-#define CALL_BUILTIN_CLASS                     160
-#define CALL_NO_KW_BUILTIN_O                   161
-#define CALL_NO_KW_BUILTIN_FAST                166
-#define CALL_BUILTIN_FAST_WITH_KEYWORDS        167
-#define CALL_NO_KW_LEN                         178
-#define CALL_NO_KW_ISINSTANCE                  179
-#define CALL_NO_KW_LIST_APPEND                 180
-#define CALL_NO_KW_METHOD_DESCRIPTOR_O         181
-#define CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 182
-#define CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS    183
-#define CALL_NO_KW_METHOD_DESCRIPTOR_FAST      184
-#define CALL_NO_KW_ALLOC_AND_ENTER_INIT        185
+#define BINARY_SUBSCR_STR_INT                   43
+#define BINARY_SUBSCR_TUPLE_INT                 44
+#define STORE_SUBSCR_DICT                       45
+#define STORE_SUBSCR_LIST_INT                   46
+#define SEND_GEN                                47
+#define UNPACK_SEQUENCE_TWO_TUPLE               48
+#define UNPACK_SEQUENCE_TUPLE                   56
+#define UNPACK_SEQUENCE_LIST                    57
+#define STORE_ATTR_INSTANCE_VALUE               58
+#define STORE_ATTR_SLOT                         59
+#define STORE_ATTR_WITH_HINT                    62
+#define LOAD_GLOBAL_MODULE                      63
+#define LOAD_GLOBAL_BUILTIN                     64
+#define LOAD_SUPER_ATTR_ATTR                    65
+#define LOAD_SUPER_ATTR_METHOD                  66
+#define LOAD_ATTR_INSTANCE_VALUE                67
+#define LOAD_ATTR_MODULE                        70
+#define LOAD_ATTR_WITH_HINT                     72
+#define LOAD_ATTR_SLOT                          73
+#define LOAD_ATTR_CLASS                         76
+#define LOAD_ATTR_PROPERTY                      77
+#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN       78
+#define LOAD_ATTR_METHOD_WITH_VALUES            79
+#define LOAD_ATTR_METHOD_NO_DICT                80
+#define LOAD_ATTR_METHOD_LAZY_DICT              81
+#define LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES     82
+#define LOAD_ATTR_NONDESCRIPTOR_NO_DICT         84
+#define COMPARE_OP_FLOAT                        86
+#define COMPARE_OP_INT                          88
+#define COMPARE_OP_STR                         111
+#define FOR_ITER_LIST                          112
+#define FOR_ITER_TUPLE                         113
+#define FOR_ITER_RANGE                         132
+#define FOR_ITER_GEN                           136
+#define CALL_BOUND_METHOD_EXACT_ARGS           148
+#define CALL_PY_EXACT_ARGS                     153
+#define CALL_PY_WITH_DEFAULTS                  154
+#define CALL_NO_KW_TYPE_1                      155
+#define CALL_NO_KW_STR_1                       159
+#define CALL_NO_KW_TUPLE_1                     160
+#define CALL_BUILTIN_CLASS                     161
+#define CALL_NO_KW_BUILTIN_O                   166
+#define CALL_NO_KW_BUILTIN_FAST                167
+#define CALL_BUILTIN_FAST_WITH_KEYWORDS        178
+#define CALL_NO_KW_LEN                         179
+#define CALL_NO_KW_ISINSTANCE                  180
+#define CALL_NO_KW_LIST_APPEND                 181
+#define CALL_NO_KW_METHOD_DESCRIPTOR_O         182
+#define CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 183
+#define CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS    184
+#define CALL_NO_KW_METHOD_DESCRIPTOR_FAST      185
+#define CALL_NO_KW_ALLOC_AND_ENTER_INIT        186
 
 #define NB_ADD                                   0
 #define NB_AND                                   1
index fd8ecdb5c980f3ffb0172a755ded14f3865a5b15..17101d1d94757ba1c51710530b0dd38cb229b930 100644 (file)
@@ -25,6 +25,7 @@ _specializations = {
         "BINARY_SUBSCR_DICT",
         "BINARY_SUBSCR_GETITEM",
         "BINARY_SUBSCR_LIST_INT",
+        "BINARY_SUBSCR_STR_INT",
         "BINARY_SUBSCR_TUPLE_INT",
     ],
     "STORE_SUBSCR": [
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-03-11-13-09.gh-issue-107596.T3yPGI.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-03-11-13-09.gh-issue-107596.T3yPGI.rst
new file mode 100644 (file)
index 0000000..8912de7
--- /dev/null
@@ -0,0 +1 @@
+Specialize subscripting :class:`str` objects by :class:`int` indexes.
index 90e26d3c86b380a57238509c7d9dddc3319b8794..d6bfb624c77133344219f8f7b88ed908fc20c732 100644 (file)
@@ -509,6 +509,7 @@ dummy_func(
             BINARY_SUBSCR_DICT,
             BINARY_SUBSCR_GETITEM,
             BINARY_SUBSCR_LIST_INT,
+            BINARY_SUBSCR_STR_INT,
             BINARY_SUBSCR_TUPLE_INT,
         };
 
@@ -574,6 +575,21 @@ dummy_func(
             Py_DECREF(list);
         }
 
+        inst(BINARY_SUBSCR_STR_INT, (unused/1, str, sub -- res)) {
+            DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR);
+            DEOPT_IF(!PyUnicode_CheckExact(str), BINARY_SUBSCR);
+            DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), BINARY_SUBSCR);
+            Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0];
+            DEOPT_IF(PyUnicode_GET_LENGTH(str) <= index, BINARY_SUBSCR);
+            // Specialize for reading an ASCII character from any string:
+            Py_UCS4 c = PyUnicode_READ_CHAR(str, index);
+            DEOPT_IF(Py_ARRAY_LENGTH(_Py_SINGLETON(strings).ascii) <= c, BINARY_SUBSCR);
+            STAT_INC(BINARY_SUBSCR, hit);
+            res = (PyObject*)&_Py_SINGLETON(strings).ascii[c];
+            _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free);
+            Py_DECREF(str);
+        }
+
         inst(BINARY_SUBSCR_TUPLE_INT, (unused/1, tuple, sub -- res)) {
             DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR);
             DEOPT_IF(!PyTuple_CheckExact(tuple), BINARY_SUBSCR);
index 9363b4955087dbec4d5827e67e2463f76e4eccc0..27be8a383989eebf0b39cec848fd8f058c87944b 100644 (file)
             break;
         }
 
+        case BINARY_SUBSCR_STR_INT: {
+            PyObject *sub;
+            PyObject *str;
+            PyObject *res;
+            sub = stack_pointer[-1];
+            str = stack_pointer[-2];
+            DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR);
+            DEOPT_IF(!PyUnicode_CheckExact(str), BINARY_SUBSCR);
+            DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), BINARY_SUBSCR);
+            Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0];
+            DEOPT_IF(PyUnicode_GET_LENGTH(str) <= index, BINARY_SUBSCR);
+            // Specialize for reading an ASCII character from any string:
+            Py_UCS4 c = PyUnicode_READ_CHAR(str, index);
+            DEOPT_IF(Py_ARRAY_LENGTH(_Py_SINGLETON(strings).ascii) <= c, BINARY_SUBSCR);
+            STAT_INC(BINARY_SUBSCR, hit);
+            res = (PyObject*)&_Py_SINGLETON(strings).ascii[c];
+            _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free);
+            Py_DECREF(str);
+            STACK_SHRINK(1);
+            stack_pointer[-1] = res;
+            break;
+        }
+
         case BINARY_SUBSCR_TUPLE_INT: {
             PyObject *sub;
             PyObject *tuple;
index 7250240ac2396c9d1c80770a74e30dc3f5a5cb0d..d7db8b07005fd1e3fd9ed1a34e2de8866a8a60cf 100644 (file)
             DISPATCH();
         }
 
+        TARGET(BINARY_SUBSCR_STR_INT) {
+            PyObject *sub;
+            PyObject *str;
+            PyObject *res;
+            sub = stack_pointer[-1];
+            str = stack_pointer[-2];
+            DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR);
+            DEOPT_IF(!PyUnicode_CheckExact(str), BINARY_SUBSCR);
+            DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), BINARY_SUBSCR);
+            Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0];
+            DEOPT_IF(PyUnicode_GET_LENGTH(str) <= index, BINARY_SUBSCR);
+            // Specialize for reading an ASCII character from any string:
+            Py_UCS4 c = PyUnicode_READ_CHAR(str, index);
+            DEOPT_IF(Py_ARRAY_LENGTH(_Py_SINGLETON(strings).ascii) <= c, BINARY_SUBSCR);
+            STAT_INC(BINARY_SUBSCR, hit);
+            res = (PyObject*)&_Py_SINGLETON(strings).ascii[c];
+            _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free);
+            Py_DECREF(str);
+            STACK_SHRINK(1);
+            stack_pointer[-1] = res;
+            next_instr += 1;
+            DISPATCH();
+        }
+
         TARGET(BINARY_SUBSCR_TUPLE_INT) {
             PyObject *sub;
             PyObject *tuple;
index d84d253c912a285869b05b949dd38c8c12262731..210c37b37225bbd871c2c20f3b7d0abfffb2ba7b 100644 (file)
@@ -42,12 +42,12 @@ static void *opcode_targets[256] = {
     &&TARGET_FORMAT_SIMPLE,
     &&TARGET_FORMAT_WITH_SPEC,
     &&TARGET_BINARY_SUBSCR_LIST_INT,
+    &&TARGET_BINARY_SUBSCR_STR_INT,
     &&TARGET_BINARY_SUBSCR_TUPLE_INT,
     &&TARGET_STORE_SUBSCR_DICT,
     &&TARGET_STORE_SUBSCR_LIST_INT,
     &&TARGET_SEND_GEN,
     &&TARGET_UNPACK_SEQUENCE_TWO_TUPLE,
-    &&TARGET_UNPACK_SEQUENCE_TUPLE,
     &&TARGET_WITH_EXCEPT_START,
     &&TARGET_GET_AITER,
     &&TARGET_GET_ANEXT,
@@ -55,39 +55,39 @@ static void *opcode_targets[256] = {
     &&TARGET_BEFORE_WITH,
     &&TARGET_END_ASYNC_FOR,
     &&TARGET_CLEANUP_THROW,
+    &&TARGET_UNPACK_SEQUENCE_TUPLE,
     &&TARGET_UNPACK_SEQUENCE_LIST,
     &&TARGET_STORE_ATTR_INSTANCE_VALUE,
     &&TARGET_STORE_ATTR_SLOT,
-    &&TARGET_STORE_ATTR_WITH_HINT,
     &&TARGET_STORE_SUBSCR,
     &&TARGET_DELETE_SUBSCR,
+    &&TARGET_STORE_ATTR_WITH_HINT,
     &&TARGET_LOAD_GLOBAL_MODULE,
     &&TARGET_LOAD_GLOBAL_BUILTIN,
     &&TARGET_LOAD_SUPER_ATTR_ATTR,
     &&TARGET_LOAD_SUPER_ATTR_METHOD,
     &&TARGET_LOAD_ATTR_INSTANCE_VALUE,
-    &&TARGET_LOAD_ATTR_MODULE,
     &&TARGET_GET_ITER,
     &&TARGET_GET_YIELD_FROM_ITER,
-    &&TARGET_LOAD_ATTR_WITH_HINT,
+    &&TARGET_LOAD_ATTR_MODULE,
     &&TARGET_LOAD_BUILD_CLASS,
+    &&TARGET_LOAD_ATTR_WITH_HINT,
     &&TARGET_LOAD_ATTR_SLOT,
-    &&TARGET_LOAD_ATTR_CLASS,
     &&TARGET_LOAD_ASSERTION_ERROR,
     &&TARGET_RETURN_GENERATOR,
+    &&TARGET_LOAD_ATTR_CLASS,
     &&TARGET_LOAD_ATTR_PROPERTY,
     &&TARGET_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN,
     &&TARGET_LOAD_ATTR_METHOD_WITH_VALUES,
     &&TARGET_LOAD_ATTR_METHOD_NO_DICT,
     &&TARGET_LOAD_ATTR_METHOD_LAZY_DICT,
     &&TARGET_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES,
-    &&TARGET_LOAD_ATTR_NONDESCRIPTOR_NO_DICT,
     &&TARGET_RETURN_VALUE,
-    &&TARGET_COMPARE_OP_FLOAT,
+    &&TARGET_LOAD_ATTR_NONDESCRIPTOR_NO_DICT,
     &&TARGET_SETUP_ANNOTATIONS,
-    &&TARGET_COMPARE_OP_INT,
+    &&TARGET_COMPARE_OP_FLOAT,
     &&TARGET_LOAD_LOCALS,
-    &&TARGET_COMPARE_OP_STR,
+    &&TARGET_COMPARE_OP_INT,
     &&TARGET_POP_EXCEPT,
     &&TARGET_STORE_NAME,
     &&TARGET_DELETE_NAME,
@@ -110,9 +110,9 @@ static void *opcode_targets[256] = {
     &&TARGET_IMPORT_NAME,
     &&TARGET_IMPORT_FROM,
     &&TARGET_JUMP_FORWARD,
+    &&TARGET_COMPARE_OP_STR,
     &&TARGET_FOR_ITER_LIST,
     &&TARGET_FOR_ITER_TUPLE,
-    &&TARGET_FOR_ITER_RANGE,
     &&TARGET_POP_JUMP_IF_FALSE,
     &&TARGET_POP_JUMP_IF_TRUE,
     &&TARGET_LOAD_GLOBAL,
@@ -131,11 +131,11 @@ static void *opcode_targets[256] = {
     &&TARGET_POP_JUMP_IF_NONE,
     &&TARGET_RAISE_VARARGS,
     &&TARGET_GET_AWAITABLE,
-    &&TARGET_FOR_ITER_GEN,
+    &&TARGET_FOR_ITER_RANGE,
     &&TARGET_BUILD_SLICE,
     &&TARGET_JUMP_BACKWARD_NO_INTERRUPT,
     &&TARGET_MAKE_CELL,
-    &&TARGET_CALL_BOUND_METHOD_EXACT_ARGS,
+    &&TARGET_FOR_ITER_GEN,
     &&TARGET_LOAD_DEREF,
     &&TARGET_STORE_DEREF,
     &&TARGET_DELETE_DEREF,
@@ -147,26 +147,26 @@ static void *opcode_targets[256] = {
     &&TARGET_LIST_APPEND,
     &&TARGET_SET_ADD,
     &&TARGET_MAP_ADD,
-    &&TARGET_CALL_PY_EXACT_ARGS,
+    &&TARGET_CALL_BOUND_METHOD_EXACT_ARGS,
     &&TARGET_COPY_FREE_VARS,
     &&TARGET_YIELD_VALUE,
     &&TARGET_RESUME,
     &&TARGET_MATCH_CLASS,
+    &&TARGET_CALL_PY_EXACT_ARGS,
     &&TARGET_CALL_PY_WITH_DEFAULTS,
     &&TARGET_CALL_NO_KW_TYPE_1,
-    &&TARGET_CALL_NO_KW_STR_1,
     &&TARGET_BUILD_CONST_KEY_MAP,
     &&TARGET_BUILD_STRING,
     &&TARGET_CONVERT_VALUE,
+    &&TARGET_CALL_NO_KW_STR_1,
     &&TARGET_CALL_NO_KW_TUPLE_1,
     &&TARGET_CALL_BUILTIN_CLASS,
-    &&TARGET_CALL_NO_KW_BUILTIN_O,
     &&TARGET_LIST_EXTEND,
     &&TARGET_SET_UPDATE,
     &&TARGET_DICT_MERGE,
     &&TARGET_DICT_UPDATE,
+    &&TARGET_CALL_NO_KW_BUILTIN_O,
     &&TARGET_CALL_NO_KW_BUILTIN_FAST,
-    &&TARGET_CALL_BUILTIN_FAST_WITH_KEYWORDS,
     &&TARGET_LOAD_FAST_LOAD_FAST,
     &&TARGET_STORE_FAST_LOAD_FAST,
     &&TARGET_STORE_FAST_STORE_FAST,
@@ -177,6 +177,7 @@ static void *opcode_targets[256] = {
     &&TARGET_LOAD_FROM_DICT_OR_GLOBALS,
     &&TARGET_LOAD_FROM_DICT_OR_DEREF,
     &&TARGET_SET_FUNCTION_ATTRIBUTE,
+    &&TARGET_CALL_BUILTIN_FAST_WITH_KEYWORDS,
     &&TARGET_CALL_NO_KW_LEN,
     &&TARGET_CALL_NO_KW_ISINSTANCE,
     &&TARGET_CALL_NO_KW_LIST_APPEND,
@@ -228,7 +229,6 @@ static void *opcode_targets[256] = {
     &&_unknown_opcode,
     &&_unknown_opcode,
     &&_unknown_opcode,
-    &&_unknown_opcode,
     &&TARGET_ENTER_EXECUTOR,
     &&_unknown_opcode,
     &&_unknown_opcode,
index de329ef1195cbf975641b99672714dc76479a939..855252e066dea14d45895f924335686674dcd0dd 100644 (file)
@@ -363,7 +363,6 @@ _PyCode_Quicken(PyCodeObject *code)
 #define SPEC_FAIL_SUBSCR_ARRAY_SLICE 10
 #define SPEC_FAIL_SUBSCR_LIST_SLICE 11
 #define SPEC_FAIL_SUBSCR_TUPLE_SLICE 12
-#define SPEC_FAIL_SUBSCR_STRING_INT 13
 #define SPEC_FAIL_SUBSCR_STRING_SLICE 14
 #define SPEC_FAIL_SUBSCR_BUFFER_INT 15
 #define SPEC_FAIL_SUBSCR_BUFFER_SLICE 16
@@ -1260,16 +1259,7 @@ success:
 static int
 binary_subscr_fail_kind(PyTypeObject *container_type, PyObject *sub)
 {
-    if (container_type == &PyUnicode_Type) {
-        if (PyLong_CheckExact(sub)) {
-            return SPEC_FAIL_SUBSCR_STRING_INT;
-        }
-        if (PySlice_Check(sub)) {
-            return SPEC_FAIL_SUBSCR_STRING_SLICE;
-        }
-        return SPEC_FAIL_OTHER;
-    }
-    else if (strcmp(container_type->tp_name, "array.array") == 0) {
+    if (strcmp(container_type->tp_name, "array.array") == 0) {
         if (PyLong_CheckExact(sub)) {
             return SPEC_FAIL_SUBSCR_ARRAY_INT;
         }
@@ -1376,6 +1366,19 @@ _Py_Specialize_BinarySubscr(
             PySlice_Check(sub) ? SPEC_FAIL_SUBSCR_TUPLE_SLICE : SPEC_FAIL_OTHER);
         goto fail;
     }
+    if (container_type == &PyUnicode_Type) {
+        if (PyLong_CheckExact(sub)) {
+            if (_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) {
+                instr->op.code = BINARY_SUBSCR_STR_INT;
+                goto success;
+            }
+            SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OUT_OF_RANGE);
+            goto fail;
+        }
+        SPECIALIZATION_FAIL(BINARY_SUBSCR,
+            PySlice_Check(sub) ? SPEC_FAIL_SUBSCR_STRING_SLICE : SPEC_FAIL_OTHER);
+        goto fail;
+    }
     if (container_type == &PyDict_Type) {
         instr->op.code = BINARY_SUBSCR_DICT;
         goto success;