From 7ea8f6647fd938ec6295176da65412c82b840292 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Thu, 2 Jun 2022 16:25:24 +0800 Subject: [PATCH 01/14] Merge LOAD_METHOD back into LOAD_ATTR --- Include/internal/pycore_code.h | 7 +- Include/internal/pycore_opcode.h | 68 +++++++------- Include/opcode.h | 53 +++++------ Lib/dis.py | 5 + Lib/importlib/_bootstrap_external.py | 3 +- Lib/opcode.py | 26 ++--- Lib/test/test_dis.py | 6 +- Programs/test_frozenmain.h | 70 +++++++------- Python/ceval.c | 136 +++++++++++---------------- Python/compile.c | 10 +- Python/opcode_targets.h | 38 ++++---- Python/specialize.c | 50 +++++----- 12 files changed, 224 insertions(+), 248 deletions(-) diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index 9d33ed71e78907..627b5f5c811002 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -58,7 +58,9 @@ typedef struct { _Py_CODEUNIT index; } _PyAttrCache; -#define INLINE_CACHE_ENTRIES_LOAD_ATTR CACHE_ENTRIES(_PyAttrCache) + +// MUST be the max(_PyAttrCache, _PyLoadMethodCache) +#define INLINE_CACHE_ENTRIES_LOAD_ATTR CACHE_ENTRIES(_PyLoadMethodCache) #define INLINE_CACHE_ENTRIES_STORE_ATTR CACHE_ENTRIES(_PyAttrCache) @@ -70,7 +72,6 @@ typedef struct { _Py_CODEUNIT descr[4]; } _PyLoadMethodCache; -#define INLINE_CACHE_ENTRIES_LOAD_METHOD CACHE_ENTRIES(_PyLoadMethodCache) typedef struct { _Py_CODEUNIT counter; @@ -234,8 +235,6 @@ extern int _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, extern int _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name); extern int _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins, _Py_CODEUNIT *instr, PyObject *name); -extern int _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, - PyObject *name); extern int _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container, _Py_CODEUNIT *instr); extern int _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *instr); extern int _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, diff --git a/Include/internal/pycore_opcode.h b/Include/internal/pycore_opcode.h index e5d948dd696a2b..6137080258feeb 100644 --- a/Include/internal/pycore_opcode.h +++ b/Include/internal/pycore_opcode.h @@ -45,11 +45,10 @@ const uint8_t _PyOpcode_Caches[256] = { [STORE_SUBSCR] = 1, [UNPACK_SEQUENCE] = 1, [STORE_ATTR] = 4, - [LOAD_ATTR] = 4, + [LOAD_ATTR] = 10, [COMPARE_OP] = 2, [LOAD_GLOBAL] = 5, [BINARY_OP] = 1, - [LOAD_METHOD] = 10, [CALL] = 4, }; @@ -148,6 +147,12 @@ const uint8_t _PyOpcode_Deopt[256] = { [LOAD_ATTR] = LOAD_ATTR, [LOAD_ATTR_ADAPTIVE] = LOAD_ATTR, [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR, + [LOAD_ATTR_METHOD_CLASS] = LOAD_ATTR, + [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR, + [LOAD_ATTR_METHOD_MODULE] = LOAD_ATTR, + [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR, + [LOAD_ATTR_METHOD_WITH_DICT] = LOAD_ATTR, + [LOAD_ATTR_METHOD_WITH_VALUES] = LOAD_ATTR, [LOAD_ATTR_MODULE] = LOAD_ATTR, [LOAD_ATTR_SLOT] = LOAD_ATTR, [LOAD_ATTR_WITH_HINT] = LOAD_ATTR, @@ -166,13 +171,6 @@ const uint8_t _PyOpcode_Deopt[256] = { [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL, [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL, [LOAD_METHOD] = LOAD_METHOD, - [LOAD_METHOD_ADAPTIVE] = LOAD_METHOD, - [LOAD_METHOD_CLASS] = LOAD_METHOD, - [LOAD_METHOD_LAZY_DICT] = LOAD_METHOD, - [LOAD_METHOD_MODULE] = LOAD_METHOD, - [LOAD_METHOD_NO_DICT] = LOAD_METHOD, - [LOAD_METHOD_WITH_DICT] = LOAD_METHOD, - [LOAD_METHOD_WITH_VALUES] = LOAD_METHOD, [LOAD_NAME] = LOAD_NAME, [MAKE_CELL] = MAKE_CELL, [MAKE_FUNCTION] = MAKE_FUNCTION, @@ -331,6 +329,12 @@ const uint8_t _PyOpcode_Original[256] = { [LOAD_ATTR] = LOAD_ATTR, [LOAD_ATTR_ADAPTIVE] = LOAD_ATTR, [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR, + [LOAD_ATTR_METHOD_CLASS] = LOAD_ATTR, + [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR, + [LOAD_ATTR_METHOD_MODULE] = LOAD_ATTR, + [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR, + [LOAD_ATTR_METHOD_WITH_DICT] = LOAD_ATTR, + [LOAD_ATTR_METHOD_WITH_VALUES] = LOAD_ATTR, [LOAD_ATTR_MODULE] = LOAD_ATTR, [LOAD_ATTR_SLOT] = LOAD_ATTR, [LOAD_ATTR_WITH_HINT] = LOAD_ATTR, @@ -349,13 +353,6 @@ const uint8_t _PyOpcode_Original[256] = { [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL, [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL, [LOAD_METHOD] = LOAD_METHOD, - [LOAD_METHOD_ADAPTIVE] = LOAD_METHOD, - [LOAD_METHOD_CLASS] = LOAD_METHOD, - [LOAD_METHOD_LAZY_DICT] = LOAD_METHOD, - [LOAD_METHOD_MODULE] = LOAD_METHOD, - [LOAD_METHOD_NO_DICT] = LOAD_METHOD, - [LOAD_METHOD_WITH_DICT] = LOAD_METHOD, - [LOAD_METHOD_WITH_VALUES] = LOAD_METHOD, [LOAD_NAME] = LOAD_NAME, [MAKE_CELL] = MAKE_CELL, [MAKE_FUNCTION] = MAKE_FUNCTION, @@ -489,26 +486,26 @@ static const char *const _PyOpcode_OpName[256] = { [LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE", [LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT", [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT", - [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST", + [LOAD_ATTR_METHOD_CLASS] = "LOAD_ATTR_METHOD_CLASS", [GET_ITER] = "GET_ITER", [GET_YIELD_FROM_ITER] = "GET_YIELD_FROM_ITER", [PRINT_EXPR] = "PRINT_EXPR", [LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS", - [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST", - [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST", + [LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT", + [LOAD_ATTR_METHOD_MODULE] = "LOAD_ATTR_METHOD_MODULE", [LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR", [RETURN_GENERATOR] = "RETURN_GENERATOR", - [LOAD_GLOBAL_ADAPTIVE] = "LOAD_GLOBAL_ADAPTIVE", - [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", - [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", - [LOAD_METHOD_ADAPTIVE] = "LOAD_METHOD_ADAPTIVE", - [LOAD_METHOD_CLASS] = "LOAD_METHOD_CLASS", - [LOAD_METHOD_LAZY_DICT] = "LOAD_METHOD_LAZY_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", + [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST", + [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST", + [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST", [LIST_TO_TUPLE] = "LIST_TO_TUPLE", [RETURN_VALUE] = "RETURN_VALUE", [IMPORT_STAR] = "IMPORT_STAR", [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS", - [LOAD_METHOD_MODULE] = "LOAD_METHOD_MODULE", + [LOAD_GLOBAL_ADAPTIVE] = "LOAD_GLOBAL_ADAPTIVE", [ASYNC_GEN_WRAP] = "ASYNC_GEN_WRAP", [PREP_RERAISE_STAR] = "PREP_RERAISE_STAR", [POP_EXCEPT] = "POP_EXCEPT", @@ -535,7 +532,7 @@ static const char *const _PyOpcode_OpName[256] = { [JUMP_FORWARD] = "JUMP_FORWARD", [JUMP_IF_FALSE_OR_POP] = "JUMP_IF_FALSE_OR_POP", [JUMP_IF_TRUE_OR_POP] = "JUMP_IF_TRUE_OR_POP", - [LOAD_METHOD_NO_DICT] = "LOAD_METHOD_NO_DICT", + [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", [POP_JUMP_FORWARD_IF_FALSE] = "POP_JUMP_FORWARD_IF_FALSE", [POP_JUMP_FORWARD_IF_TRUE] = "POP_JUMP_FORWARD_IF_TRUE", [LOAD_GLOBAL] = "LOAD_GLOBAL", @@ -543,7 +540,7 @@ static const char *const _PyOpcode_OpName[256] = { [CONTAINS_OP] = "CONTAINS_OP", [RERAISE] = "RERAISE", [COPY] = "COPY", - [LOAD_METHOD_WITH_DICT] = "LOAD_METHOD_WITH_DICT", + [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", [BINARY_OP] = "BINARY_OP", [SEND] = "SEND", [LOAD_FAST] = "LOAD_FAST", @@ -563,9 +560,9 @@ static const char *const _PyOpcode_OpName[256] = { [STORE_DEREF] = "STORE_DEREF", [DELETE_DEREF] = "DELETE_DEREF", [JUMP_BACKWARD] = "JUMP_BACKWARD", - [LOAD_METHOD_WITH_VALUES] = "LOAD_METHOD_WITH_VALUES", - [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX", [RESUME_QUICK] = "RESUME_QUICK", + [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX", + [STORE_ATTR_ADAPTIVE] = "STORE_ATTR_ADAPTIVE", [EXTENDED_ARG] = "EXTENDED_ARG", [LIST_APPEND] = "LIST_APPEND", [SET_ADD] = "SET_ADD", @@ -575,33 +572,33 @@ static const char *const _PyOpcode_OpName[256] = { [YIELD_VALUE] = "YIELD_VALUE", [RESUME] = "RESUME", [MATCH_CLASS] = "MATCH_CLASS", - [STORE_ATTR_ADAPTIVE] = "STORE_ATTR_ADAPTIVE", [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE", + [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT", [FORMAT_VALUE] = "FORMAT_VALUE", [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP", [BUILD_STRING] = "BUILD_STRING", - [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT", [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT", - [LOAD_METHOD] = "LOAD_METHOD", [STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST", + [LOAD_METHOD] = "LOAD_METHOD", + [STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST", [LIST_EXTEND] = "LIST_EXTEND", [SET_UPDATE] = "SET_UPDATE", [DICT_MERGE] = "DICT_MERGE", [DICT_UPDATE] = "DICT_UPDATE", - [STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST", [STORE_SUBSCR_ADAPTIVE] = "STORE_SUBSCR_ADAPTIVE", [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT", [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT", [UNPACK_SEQUENCE_ADAPTIVE] = "UNPACK_SEQUENCE_ADAPTIVE", + [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST", [CALL] = "CALL", [KW_NAMES] = "KW_NAMES", [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_FALSE] = "POP_JUMP_BACKWARD_IF_FALSE", [POP_JUMP_BACKWARD_IF_TRUE] = "POP_JUMP_BACKWARD_IF_TRUE", - [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST", [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE", [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE", + [179] = "<179>", [180] = "<180>", [181] = "<181>", [182] = "<182>", @@ -682,6 +679,7 @@ static const char *const _PyOpcode_OpName[256] = { #endif #define EXTRA_CASES \ + case 179: \ case 180: \ case 181: \ case 182: \ diff --git a/Include/opcode.h b/Include/opcode.h index e7713013cd3081..5f3164bf670725 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -162,33 +162,32 @@ extern "C" { #define LOAD_ATTR_MODULE 64 #define LOAD_ATTR_SLOT 65 #define LOAD_ATTR_WITH_HINT 66 -#define LOAD_CONST__LOAD_FAST 67 -#define LOAD_FAST__LOAD_CONST 72 -#define LOAD_FAST__LOAD_FAST 73 -#define LOAD_GLOBAL_ADAPTIVE 76 -#define LOAD_GLOBAL_BUILTIN 77 -#define LOAD_GLOBAL_MODULE 78 -#define LOAD_METHOD_ADAPTIVE 79 -#define LOAD_METHOD_CLASS 80 -#define LOAD_METHOD_LAZY_DICT 81 -#define LOAD_METHOD_MODULE 86 -#define LOAD_METHOD_NO_DICT 113 -#define LOAD_METHOD_WITH_DICT 121 -#define LOAD_METHOD_WITH_VALUES 141 -#define RESUME_QUICK 143 -#define STORE_ATTR_ADAPTIVE 153 -#define STORE_ATTR_INSTANCE_VALUE 154 -#define STORE_ATTR_SLOT 158 -#define STORE_ATTR_WITH_HINT 159 -#define STORE_FAST__LOAD_FAST 161 -#define STORE_FAST__STORE_FAST 166 -#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 177 -#define UNPACK_SEQUENCE_TUPLE 178 -#define UNPACK_SEQUENCE_TWO_TUPLE 179 +#define LOAD_ATTR_METHOD_CLASS 67 +#define LOAD_ATTR_METHOD_LAZY_DICT 72 +#define LOAD_ATTR_METHOD_MODULE 73 +#define LOAD_ATTR_METHOD_NO_DICT 76 +#define LOAD_ATTR_METHOD_WITH_DICT 77 +#define LOAD_ATTR_METHOD_WITH_VALUES 78 +#define LOAD_CONST__LOAD_FAST 79 +#define LOAD_FAST__LOAD_CONST 80 +#define LOAD_FAST__LOAD_FAST 81 +#define LOAD_GLOBAL_ADAPTIVE 86 +#define LOAD_GLOBAL_BUILTIN 113 +#define LOAD_GLOBAL_MODULE 121 +#define RESUME_QUICK 141 +#define STORE_ATTR_ADAPTIVE 143 +#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 166 +#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 177 +#define UNPACK_SEQUENCE_TWO_TUPLE 178 #define DO_TRACING 255 #define HAS_CONST(op) (false\ diff --git a/Lib/dis.py b/Lib/dis.py index 046013120b000d..0d439dc6e50697 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -37,6 +37,7 @@ LOAD_GLOBAL = opmap['LOAD_GLOBAL'] BINARY_OP = opmap['BINARY_OP'] JUMP_BACKWARD = opmap['JUMP_BACKWARD'] +LOAD_ATTR = opmap['LOAD_ATTR'] CACHE = opmap["CACHE"] @@ -463,6 +464,10 @@ def _get_instructions_bytes(code, varname_from_oparg=None, argval, argrepr = _get_name_info(arg//2, get_name) if (arg & 1) and argrepr: argrepr = "NULL + " + argrepr + elif deop == LOAD_ATTR: + argval, argrepr = _get_name_info(arg//2, get_name) + if (arg & 1) and argrepr: + argrepr = "NULL|self + " + argrepr else: argval, argrepr = _get_name_info(arg, get_name) elif deop in hasjabs: diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 894848a15d97d8..7ff8e12d208fb6 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -407,6 +407,7 @@ def _write_atomic(path, data, mode=0o666): # Python 3.12a1 3500 (Remove PRECALL opcode) # Python 3.12a1 3501 (YIELD_VALUE oparg == stack_depth) # Python 3.12a1 3502 (LOAD_FAST_CHECK, no NULL-check in LOAD_FAST) +# Python 3.12a1 3503 (Merge LOAD_METHOD back into LOAD_ATTR) # Python 3.13 will start with 3550 @@ -420,7 +421,7 @@ def _write_atomic(path, data, mode=0o666): # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # in PC/launcher.c must also be updated. -MAGIC_NUMBER = (3502).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3503).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c diff --git a/Lib/opcode.py b/Lib/opcode.py index 5cbb5c57521ae3..8f96fedc836494 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -285,10 +285,18 @@ def jabs_op(name, op): ], "LOAD_ATTR": [ "LOAD_ATTR_ADAPTIVE", + # LOAD_ATTR "LOAD_ATTR_INSTANCE_VALUE", "LOAD_ATTR_MODULE", "LOAD_ATTR_SLOT", "LOAD_ATTR_WITH_HINT", + # LOAD_METHOD + "LOAD_ATTR_METHOD_CLASS", + "LOAD_ATTR_METHOD_LAZY_DICT", + "LOAD_ATTR_METHOD_MODULE", + "LOAD_ATTR_METHOD_NO_DICT", + "LOAD_ATTR_METHOD_WITH_DICT", + "LOAD_ATTR_METHOD_WITH_VALUES", ], "LOAD_CONST": [ "LOAD_CONST__LOAD_FAST", @@ -302,15 +310,6 @@ def jabs_op(name, op): "LOAD_GLOBAL_BUILTIN", "LOAD_GLOBAL_MODULE", ], - "LOAD_METHOD": [ - "LOAD_METHOD_ADAPTIVE", - "LOAD_METHOD_CLASS", - "LOAD_METHOD_LAZY_DICT", - "LOAD_METHOD_MODULE", - "LOAD_METHOD_NO_DICT", - "LOAD_METHOD_WITH_DICT", - "LOAD_METHOD_WITH_VALUES", - ], "RESUME": [ "RESUME_QUICK", ], @@ -374,19 +373,14 @@ def jabs_op(name, op): "counter": 1, "version": 2, "index": 1, + "keys_version": 2, + "descr": 4, }, "STORE_ATTR": { "counter": 1, "version": 2, "index": 1, }, - "LOAD_METHOD": { - "counter": 1, - "type_version": 2, - "dict_offset": 1, - "keys_version": 2, - "descr": 4, - }, "CALL": { "counter": 1, "func_version": 2, diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 5aca019e745960..3ee57a910bb304 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -366,11 +366,11 @@ def bug42562(): %3d LOAD_GLOBAL 0 (Exception) CHECK_EXC_MATCH - POP_JUMP_FORWARD_IF_FALSE 18 (to 72) + POP_JUMP_FORWARD_IF_FALSE 24 (to 84) STORE_FAST 0 (e) %3d LOAD_FAST 0 (e) - LOAD_ATTR 1 (__traceback__) + LOAD_ATTR 2 (__traceback__) STORE_FAST 1 (tb) POP_EXCEPT LOAD_CONST 0 (None) @@ -967,7 +967,7 @@ def test_load_attr_specialize(self): 1 2 LOAD_CONST 0 ('a') 4 LOAD_ATTR_SLOT 0 (__class__) - 14 RETURN_VALUE + 26 RETURN_VALUE """ co = compile("'a'.__class__", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index e6e2ef26b1c373..ff56f85eeb654c 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -1,40 +1,42 @@ // Auto-generated by Programs/freeze_test_frozenmain.py unsigned char M_test_frozenmain[] = { 227,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0, - 0,0,0,0,0,115,160,0,0,0,151,0,100,0,100,1, + 0,0,0,0,0,115,184,0,0,0,151,0,100,0,100,1, 108,0,90,0,100,0,100,1,108,1,90,1,2,0,101,2, 100,2,171,1,0,0,0,0,0,0,0,0,1,0,2,0, - 101,2,100,3,101,0,106,3,0,0,0,0,0,0,0,0, - 171,2,0,0,0,0,0,0,0,0,1,0,2,0,101,1, - 106,4,0,0,0,0,0,0,0,0,171,0,0,0,0,0, - 0,0,0,0,100,4,25,0,0,0,0,0,0,0,0,0, - 90,5,100,5,68,0,93,23,90,6,2,0,101,2,100,6, - 101,6,155,0,100,7,101,5,101,6,25,0,0,0,0,0, - 0,0,0,0,155,0,157,4,171,1,0,0,0,0,0,0, - 0,0,1,0,140,24,100,1,83,0,41,8,233,0,0,0, - 0,78,122,18,70,114,111,122,101,110,32,72,101,108,108,111, - 32,87,111,114,108,100,122,8,115,121,115,46,97,114,103,118, - 218,6,99,111,110,102,105,103,41,5,218,12,112,114,111,103, - 114,97,109,95,110,97,109,101,218,10,101,120,101,99,117,116, - 97,98,108,101,218,15,117,115,101,95,101,110,118,105,114,111, - 110,109,101,110,116,218,17,99,111,110,102,105,103,117,114,101, - 95,99,95,115,116,100,105,111,218,14,98,117,102,102,101,114, - 101,100,95,115,116,100,105,111,122,7,99,111,110,102,105,103, - 32,122,2,58,32,41,7,218,3,115,121,115,218,17,95,116, - 101,115,116,105,110,116,101,114,110,97,108,99,97,112,105,218, - 5,112,114,105,110,116,218,4,97,114,103,118,218,11,103,101, - 116,95,99,111,110,102,105,103,115,114,2,0,0,0,218,3, - 107,101,121,169,0,243,0,0,0,0,250,18,116,101,115,116, - 95,102,114,111,122,101,110,109,97,105,110,46,112,121,250,8, - 60,109,111,100,117,108,101,62,114,17,0,0,0,1,0,0, - 0,115,140,0,0,0,248,240,6,0,1,11,128,10,128,10, - 128,10,216,0,24,208,0,24,208,0,24,208,0,24,224,0, - 5,128,5,208,6,26,212,0,27,208,0,27,216,0,5,128, - 5,128,106,144,35,148,40,212,0,27,208,0,27,216,9,38, - 208,9,26,212,9,38,212,9,40,168,24,212,9,50,128,6, - 240,2,6,12,2,240,0,7,1,42,240,0,7,1,42,128, - 67,240,14,0,5,10,128,69,208,10,40,144,67,208,10,40, - 208,10,40,152,54,160,35,156,59,208,10,40,208,10,40,212, - 4,41,208,4,41,208,4,41,240,15,7,1,42,240,0,7, - 1,42,114,15,0,0,0, + 101,2,100,3,101,0,106,6,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,171,2,0,0, + 0,0,0,0,0,0,1,0,2,0,101,1,106,8,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,171,0,0,0,0,0,0,0,0,0,100,4,25,0, + 0,0,0,0,0,0,0,0,90,5,100,5,68,0,93,23, + 90,6,2,0,101,2,100,6,101,6,155,0,100,7,101,5, + 101,6,25,0,0,0,0,0,0,0,0,0,155,0,157,4, + 171,1,0,0,0,0,0,0,0,0,1,0,140,24,100,1, + 83,0,41,8,233,0,0,0,0,78,122,18,70,114,111,122, + 101,110,32,72,101,108,108,111,32,87,111,114,108,100,122,8, + 115,121,115,46,97,114,103,118,218,6,99,111,110,102,105,103, + 41,5,218,12,112,114,111,103,114,97,109,95,110,97,109,101, + 218,10,101,120,101,99,117,116,97,98,108,101,218,15,117,115, + 101,95,101,110,118,105,114,111,110,109,101,110,116,218,17,99, + 111,110,102,105,103,117,114,101,95,99,95,115,116,100,105,111, + 218,14,98,117,102,102,101,114,101,100,95,115,116,100,105,111, + 122,7,99,111,110,102,105,103,32,122,2,58,32,41,7,218, + 3,115,121,115,218,17,95,116,101,115,116,105,110,116,101,114, + 110,97,108,99,97,112,105,218,5,112,114,105,110,116,218,4, + 97,114,103,118,218,11,103,101,116,95,99,111,110,102,105,103, + 115,114,2,0,0,0,218,3,107,101,121,169,0,243,0,0, + 0,0,250,18,116,101,115,116,95,102,114,111,122,101,110,109, + 97,105,110,46,112,121,250,8,60,109,111,100,117,108,101,62, + 114,17,0,0,0,1,0,0,0,115,145,0,0,0,248,240, + 6,0,1,11,128,10,128,10,128,10,216,0,24,208,0,24, + 208,0,24,208,0,24,224,0,5,128,5,208,6,26,212,0, + 27,208,0,27,216,0,5,128,5,128,106,144,35,151,40,146, + 40,212,0,27,208,0,27,216,9,38,208,9,26,215,9,38, + 210,9,38,212,9,40,168,24,212,9,50,128,6,240,2,6, + 12,2,240,0,7,1,42,240,0,7,1,42,128,67,240,14, + 0,5,10,128,69,208,10,40,144,67,208,10,40,208,10,40, + 152,54,160,35,156,59,208,10,40,208,10,40,212,4,41,208, + 4,41,208,4,41,240,15,7,1,42,240,0,7,1,42,114, + 15,0,0,0, }; diff --git a/Python/ceval.c b/Python/ceval.c index ec86c70673ca9a..209162797b9cc6 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1502,22 +1502,6 @@ eval_frame_handle_pending(PyThreadState *tstate) /* Shared opcode macros */ -// shared by LOAD_ATTR_MODULE and LOAD_METHOD_MODULE -#define LOAD_MODULE_ATTR_OR_METHOD(attr_or_method) \ - _PyAttrCache *cache = (_PyAttrCache *)next_instr; \ - DEOPT_IF(!PyModule_CheckExact(owner), LOAD_##attr_or_method); \ - PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; \ - assert(dict != NULL); \ - DEOPT_IF(dict->ma_keys->dk_version != read_u32(cache->version), \ - LOAD_##attr_or_method); \ - assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); \ - assert(cache->index < dict->ma_keys->dk_nentries); \ - PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + cache->index; \ - res = ep->me_value; \ - DEOPT_IF(res == NULL, LOAD_##attr_or_method); \ - STAT_INC(LOAD_##attr_or_method, hit); \ - Py_INCREF(res); - #define TRACE_FUNCTION_EXIT() \ if (cframe.use_tracing) { \ if (trace_function_exit(tstate, frame, retval)) { \ @@ -3467,7 +3451,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(LOAD_ATTR) { PREDICTED(LOAD_ATTR); - PyObject *name = GETITEM(names, oparg); + if (oparg & 1) { + JUMP_TO_INSTRUCTION(LOAD_METHOD); + } + PyObject *name = GETITEM(names, oparg>>1); PyObject *owner = TOP(); PyObject *res = PyObject_GetAttr(owner, name); if (res == NULL) { @@ -3484,7 +3471,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int _PyAttrCache *cache = (_PyAttrCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache)) { PyObject *owner = TOP(); - PyObject *name = GETITEM(names, oparg); + PyObject *name = GETITEM(names, oparg>>1); next_instr--; if (_Py_Specialize_LoadAttr(owner, next_instr, name) < 0) { goto error; @@ -3515,6 +3502,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int DEOPT_IF(res == NULL, LOAD_ATTR); STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); + SET_TOP(NULL); + STACK_GROW((oparg & 1)); SET_TOP(res); Py_DECREF(owner); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); @@ -3523,10 +3512,23 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(LOAD_ATTR_MODULE) { assert(cframe.use_tracing == 0); - // shared with LOAD_METHOD_MODULE PyObject *owner = TOP(); PyObject *res; - LOAD_MODULE_ATTR_OR_METHOD(ATTR); + _PyAttrCache* cache = (_PyAttrCache*)next_instr; + DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR); + PyDictObject* dict = (PyDictObject*)((PyModuleObject*)owner)->md_dict; + assert(dict != NULL); + DEOPT_IF(dict->ma_keys->dk_version != read_u32(cache->version), + LOAD_ATTR); + assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); + assert(cache->index < dict->ma_keys->dk_nentries); + PyDictUnicodeEntry* ep = DK_UNICODE_ENTRIES(dict->ma_keys) + cache->index; + res = ep->me_value; + DEOPT_IF(res == NULL, LOAD_##attr_or_method); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(res); + SET_TOP(NULL); + STACK_GROW((oparg & 1)); SET_TOP(res); Py_DECREF(owner); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); @@ -3546,7 +3548,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyDictObject *dict = *(PyDictObject **)_PyObject_ManagedDictPointer(owner); DEOPT_IF(dict == NULL, LOAD_ATTR); assert(PyDict_CheckExact((PyObject *)dict)); - PyObject *name = GETITEM(names, oparg); + PyObject *name = GETITEM(names, oparg>>1); uint16_t hint = cache->index; DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR); if (DK_IS_UNICODE(dict->ma_keys)) { @@ -3562,6 +3564,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int DEOPT_IF(res == NULL, LOAD_ATTR); STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); + SET_TOP(NULL); + STACK_GROW((oparg & 1)); SET_TOP(res); Py_DECREF(owner); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); @@ -3582,6 +3586,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int DEOPT_IF(res == NULL, LOAD_ATTR); STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); + SET_TOP(NULL); + STACK_GROW((oparg & 1)); SET_TOP(res); Py_DECREF(owner); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); @@ -4489,7 +4495,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(LOAD_METHOD) { PREDICTED(LOAD_METHOD); /* Designed to work in tandem with CALL. */ - PyObject *name = GETITEM(names, oparg); + PyObject *name = GETITEM(names, oparg>>1); PyObject *obj = TOP(); PyObject *meth = NULL; @@ -4521,30 +4527,11 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Py_DECREF(obj); PUSH(meth); } - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); DISPATCH(); } - TARGET(LOAD_METHOD_ADAPTIVE) { - assert(cframe.use_tracing == 0); - _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache)) { - PyObject *owner = TOP(); - PyObject *name = GETITEM(names, oparg); - next_instr--; - if (_Py_Specialize_LoadMethod(owner, next_instr, name) < 0) { - goto error; - } - NOTRACE_DISPATCH_SAME_OPARG(); - } - else { - STAT_INC(LOAD_METHOD, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache); - JUMP_TO_INSTRUCTION(LOAD_METHOD); - } - } - - TARGET(LOAD_METHOD_WITH_VALUES) { + TARGET(LOAD_ATTR_METHOD_WITH_VALUES) { /* LOAD_METHOD, with cached method object */ assert(cframe.use_tracing == 0); PyObject *self = TOP(); @@ -4552,25 +4539,25 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; uint32_t type_version = read_u32(cache->type_version); assert(type_version != 0); - DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_METHOD); + DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); assert(self_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT); PyDictObject *dict = *(PyDictObject**)_PyObject_ManagedDictPointer(self); - DEOPT_IF(dict != NULL, LOAD_METHOD); + DEOPT_IF(dict != NULL, LOAD_ATTR); PyHeapTypeObject *self_heap_type = (PyHeapTypeObject *)self_cls; DEOPT_IF(self_heap_type->ht_cached_keys->dk_version != - read_u32(cache->keys_version), LOAD_METHOD); - STAT_INC(LOAD_METHOD, hit); + read_u32(cache->keys_version), LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); PyObject *res = read_obj(cache->descr); assert(res != NULL); assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)); Py_INCREF(res); SET_TOP(res); PUSH(self); - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); NOTRACE_DISPATCH(); } - TARGET(LOAD_METHOD_WITH_DICT) { + TARGET(LOAD_ATTR_METHOD_WITH_DICT) { /* LOAD_METHOD, with a dict Can be either a managed dict, or a tp_dictoffset offset.*/ assert(cframe.use_tracing == 0); @@ -4579,7 +4566,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; DEOPT_IF(self_cls->tp_version_tag != read_u32(cache->type_version), - LOAD_METHOD); + LOAD_ATTR); /* Treat index as a signed 16 bit value */ int dictoffset = *(int16_t *)&cache->dict_offset; PyDictObject **dictptr = (PyDictObject**)(((char *)self)+dictoffset); @@ -4588,95 +4575,82 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int (dictoffset == self_cls->tp_dictoffset && dictoffset > 0) ); PyDictObject *dict = *dictptr; - DEOPT_IF(dict == NULL, LOAD_METHOD); + DEOPT_IF(dict == NULL, LOAD_ATTR); DEOPT_IF(dict->ma_keys->dk_version != read_u32(cache->keys_version), - LOAD_METHOD); - STAT_INC(LOAD_METHOD, hit); + LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); PyObject *res = read_obj(cache->descr); assert(res != NULL); assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)); Py_INCREF(res); SET_TOP(res); PUSH(self); - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); NOTRACE_DISPATCH(); } - TARGET(LOAD_METHOD_NO_DICT) { + TARGET(LOAD_ATTR_METHOD_NO_DICT) { assert(cframe.use_tracing == 0); PyObject *self = TOP(); PyTypeObject *self_cls = Py_TYPE(self); _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; uint32_t type_version = read_u32(cache->type_version); - DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_METHOD); + DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); assert(self_cls->tp_dictoffset == 0); - STAT_INC(LOAD_METHOD, hit); + STAT_INC(LOAD_ATTR, hit); PyObject *res = read_obj(cache->descr); assert(res != NULL); assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)); Py_INCREF(res); SET_TOP(res); PUSH(self); - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); NOTRACE_DISPATCH(); } - TARGET(LOAD_METHOD_LAZY_DICT) { + TARGET(LOAD_ATTR_METHOD_LAZY_DICT) { assert(cframe.use_tracing == 0); PyObject *self = TOP(); PyTypeObject *self_cls = Py_TYPE(self); _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; uint32_t type_version = read_u32(cache->type_version); - DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_METHOD); + DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); int dictoffset = cache->dict_offset; PyObject *dict = *(PyObject **)((char *)self + dictoffset); assert(dictoffset == self_cls->tp_dictoffset && dictoffset > 0); /* This object has a __dict__, just not yet created */ - DEOPT_IF(dict != NULL, LOAD_METHOD); - STAT_INC(LOAD_METHOD, hit); + DEOPT_IF(dict != NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); PyObject *res = read_obj(cache->descr); assert(res != NULL); assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)); Py_INCREF(res); SET_TOP(res); PUSH(self); - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); - NOTRACE_DISPATCH(); - } - - TARGET(LOAD_METHOD_MODULE) { - /* LOAD_METHOD, for module methods */ - assert(cframe.use_tracing == 0); - PyObject *owner = TOP(); - PyObject *res; - LOAD_MODULE_ATTR_OR_METHOD(METHOD); - SET_TOP(NULL); - Py_DECREF(owner); - PUSH(res); - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); NOTRACE_DISPATCH(); } - TARGET(LOAD_METHOD_CLASS) { + TARGET(LOAD_ATTR_METHOD_CLASS) { /* LOAD_METHOD, for class methods */ assert(cframe.use_tracing == 0); _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; PyObject *cls = TOP(); - DEOPT_IF(!PyType_Check(cls), LOAD_METHOD); + DEOPT_IF(!PyType_Check(cls), LOAD_ATTR); uint32_t type_version = read_u32(cache->type_version); DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != type_version, - LOAD_METHOD); + LOAD_ATTR); assert(type_version != 0); - STAT_INC(LOAD_METHOD, hit); + STAT_INC(LOAD_ATTR, hit); PyObject *res = read_obj(cache->descr); assert(res != NULL); Py_INCREF(res); SET_TOP(NULL); Py_DECREF(cls); PUSH(res); - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); NOTRACE_DISPATCH(); } diff --git a/Python/compile.c b/Python/compile.c index a6788b732831fd..e018359033da27 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1039,7 +1039,7 @@ stack_effect(int opcode, int oparg, int jump) case BUILD_CONST_KEY_MAP: return -oparg; case LOAD_ATTR: - return 0; + return (oparg & 1); case COMPARE_OP: case IS_OP: case CONTAINS_OP: @@ -1470,6 +1470,14 @@ compiler_addop_name(struct compiler *c, int opcode, PyObject *dict, Py_DECREF(mangled); if (arg < 0) return 0; + if (opcode == LOAD_ATTR) { + arg <<= 1; + } + if (opcode == LOAD_METHOD) { + opcode = LOAD_ATTR; + arg <<= 1; + arg |= 1; + } return compiler_addop_i(c, opcode, arg); } diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 1009b3a93458ed..58f39f05ebeb00 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -66,26 +66,26 @@ static void *opcode_targets[256] = { &&TARGET_LOAD_ATTR_MODULE, &&TARGET_LOAD_ATTR_SLOT, &&TARGET_LOAD_ATTR_WITH_HINT, - &&TARGET_LOAD_CONST__LOAD_FAST, + &&TARGET_LOAD_ATTR_METHOD_CLASS, &&TARGET_GET_ITER, &&TARGET_GET_YIELD_FROM_ITER, &&TARGET_PRINT_EXPR, &&TARGET_LOAD_BUILD_CLASS, - &&TARGET_LOAD_FAST__LOAD_CONST, - &&TARGET_LOAD_FAST__LOAD_FAST, + &&TARGET_LOAD_ATTR_METHOD_LAZY_DICT, + &&TARGET_LOAD_ATTR_METHOD_MODULE, &&TARGET_LOAD_ASSERTION_ERROR, &&TARGET_RETURN_GENERATOR, - &&TARGET_LOAD_GLOBAL_ADAPTIVE, - &&TARGET_LOAD_GLOBAL_BUILTIN, - &&TARGET_LOAD_GLOBAL_MODULE, - &&TARGET_LOAD_METHOD_ADAPTIVE, - &&TARGET_LOAD_METHOD_CLASS, - &&TARGET_LOAD_METHOD_LAZY_DICT, + &&TARGET_LOAD_ATTR_METHOD_NO_DICT, + &&TARGET_LOAD_ATTR_METHOD_WITH_DICT, + &&TARGET_LOAD_ATTR_METHOD_WITH_VALUES, + &&TARGET_LOAD_CONST__LOAD_FAST, + &&TARGET_LOAD_FAST__LOAD_CONST, + &&TARGET_LOAD_FAST__LOAD_FAST, &&TARGET_LIST_TO_TUPLE, &&TARGET_RETURN_VALUE, &&TARGET_IMPORT_STAR, &&TARGET_SETUP_ANNOTATIONS, - &&TARGET_LOAD_METHOD_MODULE, + &&TARGET_LOAD_GLOBAL_ADAPTIVE, &&TARGET_ASYNC_GEN_WRAP, &&TARGET_PREP_RERAISE_STAR, &&TARGET_POP_EXCEPT, @@ -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_LOAD_METHOD_NO_DICT, + &&TARGET_LOAD_GLOBAL_BUILTIN, &&TARGET_POP_JUMP_FORWARD_IF_FALSE, &&TARGET_POP_JUMP_FORWARD_IF_TRUE, &&TARGET_LOAD_GLOBAL, @@ -120,7 +120,7 @@ static void *opcode_targets[256] = { &&TARGET_CONTAINS_OP, &&TARGET_RERAISE, &&TARGET_COPY, - &&TARGET_LOAD_METHOD_WITH_DICT, + &&TARGET_LOAD_GLOBAL_MODULE, &&TARGET_BINARY_OP, &&TARGET_SEND, &&TARGET_LOAD_FAST, @@ -140,9 +140,9 @@ static void *opcode_targets[256] = { &&TARGET_STORE_DEREF, &&TARGET_DELETE_DEREF, &&TARGET_JUMP_BACKWARD, - &&TARGET_LOAD_METHOD_WITH_VALUES, - &&TARGET_CALL_FUNCTION_EX, &&TARGET_RESUME_QUICK, + &&TARGET_CALL_FUNCTION_EX, + &&TARGET_STORE_ATTR_ADAPTIVE, &&TARGET_EXTENDED_ARG, &&TARGET_LIST_APPEND, &&TARGET_SET_ADD, @@ -152,31 +152,30 @@ static void *opcode_targets[256] = { &&TARGET_YIELD_VALUE, &&TARGET_RESUME, &&TARGET_MATCH_CLASS, - &&TARGET_STORE_ATTR_ADAPTIVE, &&TARGET_STORE_ATTR_INSTANCE_VALUE, + &&TARGET_STORE_ATTR_SLOT, &&TARGET_FORMAT_VALUE, &&TARGET_BUILD_CONST_KEY_MAP, &&TARGET_BUILD_STRING, - &&TARGET_STORE_ATTR_SLOT, &&TARGET_STORE_ATTR_WITH_HINT, - &&TARGET_LOAD_METHOD, &&TARGET_STORE_FAST__LOAD_FAST, + &&TARGET_LOAD_METHOD, + &&TARGET_STORE_FAST__STORE_FAST, &&TARGET_LIST_EXTEND, &&TARGET_SET_UPDATE, &&TARGET_DICT_MERGE, &&TARGET_DICT_UPDATE, - &&TARGET_STORE_FAST__STORE_FAST, &&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_POP_JUMP_BACKWARD_IF_NOT_NONE, &&TARGET_POP_JUMP_BACKWARD_IF_NONE, &&TARGET_POP_JUMP_BACKWARD_IF_FALSE, &&TARGET_POP_JUMP_BACKWARD_IF_TRUE, - &&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 4d30a2aea5f3be..fae7e5d332455a 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -20,7 +20,6 @@ uint8_t _PyOpcode_Adaptive[256] = { [LOAD_ATTR] = LOAD_ATTR_ADAPTIVE, [LOAD_GLOBAL] = LOAD_GLOBAL_ADAPTIVE, - [LOAD_METHOD] = LOAD_METHOD_ADAPTIVE, [BINARY_SUBSCR] = BINARY_SUBSCR_ADAPTIVE, [STORE_SUBSCR] = STORE_SUBSCR_ADAPTIVE, [CALL] = CALL_ADAPTIVE, @@ -654,6 +653,9 @@ specialize_dict_access( return 1; } +static int +specialize_attr_loadmethod(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name); + int _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) { @@ -667,6 +669,17 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) } goto success; } + int oparg = _Py_OPARG(*instr); + if (oparg & 1) { + int res = specialize_attr_loadmethod(owner, instr, name); + if (res < 0) { + return -1; + } + else if (res) { + goto success; + } + /* res == 0 (fail), fall through and let LOAD_ATTR specialize for it */ + } PyTypeObject *type = Py_TYPE(owner); if (type->tp_dict == NULL) { if (PyType_Ready(type) < 0) { @@ -884,7 +897,7 @@ specialize_class_load_method(PyObject *owner, _Py_CODEUNIT *instr, case NON_DESCRIPTOR: write_u32(cache->type_version, ((PyTypeObject *)owner)->tp_version_tag); write_obj(cache->descr, descr); - _Py_SET_OPCODE(*instr, LOAD_METHOD_CLASS); + _Py_SET_OPCODE(*instr, LOAD_ATTR_METHOD_CLASS); return 0; #ifdef Py_STATS case ABSENT: @@ -913,23 +926,12 @@ typedef enum { // Please collect stats carefully before and after modifying. A subtle change // can cause a significant drop in cache hits. A possible test is // python.exe -m test_typing test_re test_dis test_zlib. -int -_Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) +static int +specialize_attr_loadmethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) { - assert(_PyOpcode_Caches[LOAD_METHOD] == INLINE_CACHE_ENTRIES_LOAD_METHOD); _PyLoadMethodCache *cache = (_PyLoadMethodCache *)(instr + 1); PyTypeObject *owner_cls = Py_TYPE(owner); - if (PyModule_CheckExact(owner)) { - assert(INLINE_CACHE_ENTRIES_LOAD_ATTR <= - INLINE_CACHE_ENTRIES_LOAD_METHOD); - int err = specialize_module_load_attr(owner, instr, name, LOAD_METHOD, - LOAD_METHOD_MODULE); - if (err) { - goto fail; - } - goto success; - } if (owner_cls->tp_dict == NULL) { if (PyType_Ready(owner_cls) < 0) { return -1; @@ -1001,24 +1003,24 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) } switch(dictkind) { case NO_DICT: - _Py_SET_OPCODE(*instr, LOAD_METHOD_NO_DICT); + _Py_SET_OPCODE(*instr, LOAD_ATTR_METHOD_NO_DICT); break; case MANAGED_VALUES: - _Py_SET_OPCODE(*instr, LOAD_METHOD_WITH_VALUES); + _Py_SET_OPCODE(*instr, LOAD_ATTR_METHOD_WITH_VALUES); break; case MANAGED_DICT: *(int16_t *)&cache->dict_offset = (int16_t)MANAGED_DICT_OFFSET; - _Py_SET_OPCODE(*instr, LOAD_METHOD_WITH_DICT); + _Py_SET_OPCODE(*instr, LOAD_ATTR_METHOD_WITH_DICT); break; case OFFSET_DICT: assert(owner_cls->tp_dictoffset > 0 && owner_cls->tp_dictoffset <= INT16_MAX); cache->dict_offset = (uint16_t)owner_cls->tp_dictoffset; - _Py_SET_OPCODE(*instr, LOAD_METHOD_WITH_DICT); + _Py_SET_OPCODE(*instr, LOAD_ATTR_METHOD_WITH_DICT); break; case LAZY_DICT: assert(owner_cls->tp_dictoffset > 0 && owner_cls->tp_dictoffset <= INT16_MAX); cache->dict_offset = (uint16_t)owner_cls->tp_dictoffset; - _Py_SET_OPCODE(*instr, LOAD_METHOD_LAZY_DICT); + _Py_SET_OPCODE(*instr, LOAD_ATTR_METHOD_LAZY_DICT); break; } /* `descr` is borrowed. This is safe for methods (even inherited ones from @@ -1039,14 +1041,8 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) write_obj(cache->descr, descr); // Fall through. success: - STAT_INC(LOAD_METHOD, success); - assert(!PyErr_Occurred()); - cache->counter = miss_counter_start(); - return 0; + return 1; fail: - STAT_INC(LOAD_METHOD, failure); - assert(!PyErr_Occurred()); - cache->counter = adaptive_counter_backoff(cache->counter); return 0; } From 51e34f1e684bff16e730af8dff2ddcf159372c21 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Thu, 2 Jun 2022 08:28:56 +0000 Subject: [PATCH 02/14] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2022-06-02-08-28-55.gh-issue-93429.DZTWHx.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-06-02-08-28-55.gh-issue-93429.DZTWHx.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-06-02-08-28-55.gh-issue-93429.DZTWHx.rst b/Misc/NEWS.d/next/Core and Builtins/2022-06-02-08-28-55.gh-issue-93429.DZTWHx.rst new file mode 100644 index 00000000000000..02efedaa9645f0 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-06-02-08-28-55.gh-issue-93429.DZTWHx.rst @@ -0,0 +1 @@ +``LOAD_METHOD`` instruction has been removed. It was merged back into ``LOAD_ATTR``. From 7e8dd23bff9cf34c3c6f9af3496672acc957b006 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Thu, 2 Jun 2022 16:34:31 +0800 Subject: [PATCH 03/14] Remove LOAD_ATTR_METHOD_MODULE --- Include/internal/pycore_opcode.h | 27 +++++++++--------- Include/opcode.h | 47 ++++++++++++++++---------------- Lib/opcode.py | 1 - Python/opcode_targets.h | 24 ++++++++-------- 4 files changed, 48 insertions(+), 51 deletions(-) diff --git a/Include/internal/pycore_opcode.h b/Include/internal/pycore_opcode.h index 6137080258feeb..ecda14dec9ac29 100644 --- a/Include/internal/pycore_opcode.h +++ b/Include/internal/pycore_opcode.h @@ -149,7 +149,6 @@ const uint8_t _PyOpcode_Deopt[256] = { [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR, [LOAD_ATTR_METHOD_CLASS] = LOAD_ATTR, [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR, - [LOAD_ATTR_METHOD_MODULE] = LOAD_ATTR, [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR, [LOAD_ATTR_METHOD_WITH_DICT] = LOAD_ATTR, [LOAD_ATTR_METHOD_WITH_VALUES] = LOAD_ATTR, @@ -331,7 +330,6 @@ const uint8_t _PyOpcode_Original[256] = { [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR, [LOAD_ATTR_METHOD_CLASS] = LOAD_ATTR, [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR, - [LOAD_ATTR_METHOD_MODULE] = LOAD_ATTR, [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR, [LOAD_ATTR_METHOD_WITH_DICT] = LOAD_ATTR, [LOAD_ATTR_METHOD_WITH_VALUES] = LOAD_ATTR, @@ -492,20 +490,20 @@ static const char *const _PyOpcode_OpName[256] = { [PRINT_EXPR] = "PRINT_EXPR", [LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS", [LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT", - [LOAD_ATTR_METHOD_MODULE] = "LOAD_ATTR_METHOD_MODULE", + [LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT", [LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR", [RETURN_GENERATOR] = "RETURN_GENERATOR", - [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", [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST", [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST", [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST", + [LOAD_GLOBAL_ADAPTIVE] = "LOAD_GLOBAL_ADAPTIVE", [LIST_TO_TUPLE] = "LIST_TO_TUPLE", [RETURN_VALUE] = "RETURN_VALUE", [IMPORT_STAR] = "IMPORT_STAR", [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS", - [LOAD_GLOBAL_ADAPTIVE] = "LOAD_GLOBAL_ADAPTIVE", + [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", [ASYNC_GEN_WRAP] = "ASYNC_GEN_WRAP", [PREP_RERAISE_STAR] = "PREP_RERAISE_STAR", [POP_EXCEPT] = "POP_EXCEPT", @@ -532,7 +530,7 @@ static const char *const _PyOpcode_OpName[256] = { [JUMP_FORWARD] = "JUMP_FORWARD", [JUMP_IF_FALSE_OR_POP] = "JUMP_IF_FALSE_OR_POP", [JUMP_IF_TRUE_OR_POP] = "JUMP_IF_TRUE_OR_POP", - [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", + [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", [POP_JUMP_FORWARD_IF_FALSE] = "POP_JUMP_FORWARD_IF_FALSE", [POP_JUMP_FORWARD_IF_TRUE] = "POP_JUMP_FORWARD_IF_TRUE", [LOAD_GLOBAL] = "LOAD_GLOBAL", @@ -540,7 +538,7 @@ static const char *const _PyOpcode_OpName[256] = { [CONTAINS_OP] = "CONTAINS_OP", [RERAISE] = "RERAISE", [COPY] = "COPY", - [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", + [RESUME_QUICK] = "RESUME_QUICK", [BINARY_OP] = "BINARY_OP", [SEND] = "SEND", [LOAD_FAST] = "LOAD_FAST", @@ -560,9 +558,9 @@ static const char *const _PyOpcode_OpName[256] = { [STORE_DEREF] = "STORE_DEREF", [DELETE_DEREF] = "DELETE_DEREF", [JUMP_BACKWARD] = "JUMP_BACKWARD", - [RESUME_QUICK] = "RESUME_QUICK", - [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX", [STORE_ATTR_ADAPTIVE] = "STORE_ATTR_ADAPTIVE", + [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX", + [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE", [EXTENDED_ARG] = "EXTENDED_ARG", [LIST_APPEND] = "LIST_APPEND", [SET_ADD] = "SET_ADD", @@ -572,32 +570,32 @@ static const char *const _PyOpcode_OpName[256] = { [YIELD_VALUE] = "YIELD_VALUE", [RESUME] = "RESUME", [MATCH_CLASS] = "MATCH_CLASS", - [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE", [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT", + [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT", [FORMAT_VALUE] = "FORMAT_VALUE", [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP", [BUILD_STRING] = "BUILD_STRING", - [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT", [STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST", - [LOAD_METHOD] = "LOAD_METHOD", [STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST", + [LOAD_METHOD] = "LOAD_METHOD", + [STORE_SUBSCR_ADAPTIVE] = "STORE_SUBSCR_ADAPTIVE", [LIST_EXTEND] = "LIST_EXTEND", [SET_UPDATE] = "SET_UPDATE", [DICT_MERGE] = "DICT_MERGE", [DICT_UPDATE] = "DICT_UPDATE", - [STORE_SUBSCR_ADAPTIVE] = "STORE_SUBSCR_ADAPTIVE", [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT", [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT", [UNPACK_SEQUENCE_ADAPTIVE] = "UNPACK_SEQUENCE_ADAPTIVE", [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST", + [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE", [CALL] = "CALL", [KW_NAMES] = "KW_NAMES", [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_FALSE] = "POP_JUMP_BACKWARD_IF_FALSE", [POP_JUMP_BACKWARD_IF_TRUE] = "POP_JUMP_BACKWARD_IF_TRUE", - [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE", [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE", + [178] = "<178>", [179] = "<179>", [180] = "<180>", [181] = "<181>", @@ -679,6 +677,7 @@ static const char *const _PyOpcode_OpName[256] = { #endif #define EXTRA_CASES \ + case 178: \ case 179: \ case 180: \ case 181: \ diff --git a/Include/opcode.h b/Include/opcode.h index 5f3164bf670725..5fcb517ecef4ed 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -164,30 +164,29 @@ extern "C" { #define LOAD_ATTR_WITH_HINT 66 #define LOAD_ATTR_METHOD_CLASS 67 #define LOAD_ATTR_METHOD_LAZY_DICT 72 -#define LOAD_ATTR_METHOD_MODULE 73 -#define LOAD_ATTR_METHOD_NO_DICT 76 -#define LOAD_ATTR_METHOD_WITH_DICT 77 -#define LOAD_ATTR_METHOD_WITH_VALUES 78 -#define LOAD_CONST__LOAD_FAST 79 -#define LOAD_FAST__LOAD_CONST 80 -#define LOAD_FAST__LOAD_FAST 81 -#define LOAD_GLOBAL_ADAPTIVE 86 -#define LOAD_GLOBAL_BUILTIN 113 -#define LOAD_GLOBAL_MODULE 121 -#define RESUME_QUICK 141 -#define STORE_ATTR_ADAPTIVE 143 -#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 166 -#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 177 -#define UNPACK_SEQUENCE_TWO_TUPLE 178 +#define LOAD_ATTR_METHOD_NO_DICT 73 +#define LOAD_ATTR_METHOD_WITH_DICT 76 +#define LOAD_ATTR_METHOD_WITH_VALUES 77 +#define LOAD_CONST__LOAD_FAST 78 +#define LOAD_FAST__LOAD_CONST 79 +#define LOAD_FAST__LOAD_FAST 80 +#define LOAD_GLOBAL_ADAPTIVE 81 +#define LOAD_GLOBAL_BUILTIN 86 +#define LOAD_GLOBAL_MODULE 113 +#define RESUME_QUICK 121 +#define STORE_ATTR_ADAPTIVE 141 +#define STORE_ATTR_INSTANCE_VALUE 143 +#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 166 +#define STORE_SUBSCR_LIST_INT 167 +#define UNPACK_SEQUENCE_ADAPTIVE 168 +#define UNPACK_SEQUENCE_LIST 169 +#define UNPACK_SEQUENCE_TUPLE 170 +#define UNPACK_SEQUENCE_TWO_TUPLE 177 #define DO_TRACING 255 #define HAS_CONST(op) (false\ diff --git a/Lib/opcode.py b/Lib/opcode.py index 8f96fedc836494..49da4e589b607a 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -293,7 +293,6 @@ def jabs_op(name, op): # LOAD_METHOD "LOAD_ATTR_METHOD_CLASS", "LOAD_ATTR_METHOD_LAZY_DICT", - "LOAD_ATTR_METHOD_MODULE", "LOAD_ATTR_METHOD_NO_DICT", "LOAD_ATTR_METHOD_WITH_DICT", "LOAD_ATTR_METHOD_WITH_VALUES", diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 58f39f05ebeb00..ad2ca10f97e258 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -72,20 +72,20 @@ static void *opcode_targets[256] = { &&TARGET_PRINT_EXPR, &&TARGET_LOAD_BUILD_CLASS, &&TARGET_LOAD_ATTR_METHOD_LAZY_DICT, - &&TARGET_LOAD_ATTR_METHOD_MODULE, + &&TARGET_LOAD_ATTR_METHOD_NO_DICT, &&TARGET_LOAD_ASSERTION_ERROR, &&TARGET_RETURN_GENERATOR, - &&TARGET_LOAD_ATTR_METHOD_NO_DICT, &&TARGET_LOAD_ATTR_METHOD_WITH_DICT, &&TARGET_LOAD_ATTR_METHOD_WITH_VALUES, &&TARGET_LOAD_CONST__LOAD_FAST, &&TARGET_LOAD_FAST__LOAD_CONST, &&TARGET_LOAD_FAST__LOAD_FAST, + &&TARGET_LOAD_GLOBAL_ADAPTIVE, &&TARGET_LIST_TO_TUPLE, &&TARGET_RETURN_VALUE, &&TARGET_IMPORT_STAR, &&TARGET_SETUP_ANNOTATIONS, - &&TARGET_LOAD_GLOBAL_ADAPTIVE, + &&TARGET_LOAD_GLOBAL_BUILTIN, &&TARGET_ASYNC_GEN_WRAP, &&TARGET_PREP_RERAISE_STAR, &&TARGET_POP_EXCEPT, @@ -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_LOAD_GLOBAL_BUILTIN, + &&TARGET_LOAD_GLOBAL_MODULE, &&TARGET_POP_JUMP_FORWARD_IF_FALSE, &&TARGET_POP_JUMP_FORWARD_IF_TRUE, &&TARGET_LOAD_GLOBAL, @@ -120,7 +120,7 @@ static void *opcode_targets[256] = { &&TARGET_CONTAINS_OP, &&TARGET_RERAISE, &&TARGET_COPY, - &&TARGET_LOAD_GLOBAL_MODULE, + &&TARGET_RESUME_QUICK, &&TARGET_BINARY_OP, &&TARGET_SEND, &&TARGET_LOAD_FAST, @@ -140,9 +140,9 @@ static void *opcode_targets[256] = { &&TARGET_STORE_DEREF, &&TARGET_DELETE_DEREF, &&TARGET_JUMP_BACKWARD, - &&TARGET_RESUME_QUICK, - &&TARGET_CALL_FUNCTION_EX, &&TARGET_STORE_ATTR_ADAPTIVE, + &&TARGET_CALL_FUNCTION_EX, + &&TARGET_STORE_ATTR_INSTANCE_VALUE, &&TARGET_EXTENDED_ARG, &&TARGET_LIST_APPEND, &&TARGET_SET_ADD, @@ -152,31 +152,30 @@ static void *opcode_targets[256] = { &&TARGET_YIELD_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_STORE_SUBSCR_ADAPTIVE, &&TARGET_STORE_SUBSCR_DICT, &&TARGET_STORE_SUBSCR_LIST_INT, &&TARGET_UNPACK_SEQUENCE_ADAPTIVE, &&TARGET_UNPACK_SEQUENCE_LIST, + &&TARGET_UNPACK_SEQUENCE_TUPLE, &&TARGET_CALL, &&TARGET_KW_NAMES, &&TARGET_POP_JUMP_BACKWARD_IF_NOT_NONE, &&TARGET_POP_JUMP_BACKWARD_IF_NONE, &&TARGET_POP_JUMP_BACKWARD_IF_FALSE, &&TARGET_POP_JUMP_BACKWARD_IF_TRUE, - &&TARGET_UNPACK_SEQUENCE_TUPLE, &&TARGET_UNPACK_SEQUENCE_TWO_TUPLE, &&_unknown_opcode, &&_unknown_opcode, @@ -254,5 +253,6 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, + &&_unknown_opcode, &&TARGET_DO_TRACING }; From e0eb7ee0dd0df37617a06daf327a5abb731583b5 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Tue, 7 Jun 2022 16:49:17 +0800 Subject: [PATCH 04/14] Make LOAD_METHOD a virtual instruction --- Include/internal/pycore_opcode.h | 9 ++-- Include/opcode.h | 15 +++---- Lib/opcode.py | 2 - Python/ceval.c | 77 +++++++++++++++----------------- Python/compile.c | 3 +- Python/opcode_targets.h | 6 +-- 6 files changed, 51 insertions(+), 61 deletions(-) diff --git a/Include/internal/pycore_opcode.h b/Include/internal/pycore_opcode.h index ecda14dec9ac29..2a965e78d0e3f8 100644 --- a/Include/internal/pycore_opcode.h +++ b/Include/internal/pycore_opcode.h @@ -169,7 +169,6 @@ const uint8_t _PyOpcode_Deopt[256] = { [LOAD_GLOBAL_ADAPTIVE] = LOAD_GLOBAL, [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL, [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL, - [LOAD_METHOD] = LOAD_METHOD, [LOAD_NAME] = LOAD_NAME, [MAKE_CELL] = MAKE_CELL, [MAKE_FUNCTION] = MAKE_FUNCTION, @@ -350,7 +349,6 @@ const uint8_t _PyOpcode_Original[256] = { [LOAD_GLOBAL_ADAPTIVE] = LOAD_GLOBAL, [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL, [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL, - [LOAD_METHOD] = LOAD_METHOD, [LOAD_NAME] = LOAD_NAME, [MAKE_CELL] = MAKE_CELL, [MAKE_FUNCTION] = MAKE_FUNCTION, @@ -577,24 +575,24 @@ static const char *const _PyOpcode_OpName[256] = { [BUILD_STRING] = "BUILD_STRING", [STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST", [STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST", - [LOAD_METHOD] = "LOAD_METHOD", [STORE_SUBSCR_ADAPTIVE] = "STORE_SUBSCR_ADAPTIVE", + [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT", [LIST_EXTEND] = "LIST_EXTEND", [SET_UPDATE] = "SET_UPDATE", [DICT_MERGE] = "DICT_MERGE", [DICT_UPDATE] = "DICT_UPDATE", - [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT", [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT", [UNPACK_SEQUENCE_ADAPTIVE] = "UNPACK_SEQUENCE_ADAPTIVE", [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST", [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE", + [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE", [CALL] = "CALL", [KW_NAMES] = "KW_NAMES", [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_FALSE] = "POP_JUMP_BACKWARD_IF_FALSE", [POP_JUMP_BACKWARD_IF_TRUE] = "POP_JUMP_BACKWARD_IF_TRUE", - [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE", + [177] = "<177>", [178] = "<178>", [179] = "<179>", [180] = "<180>", @@ -677,6 +675,7 @@ static const char *const _PyOpcode_OpName[256] = { #endif #define EXTRA_CASES \ + case 177: \ case 178: \ case 179: \ case 180: \ diff --git a/Include/opcode.h b/Include/opcode.h index 5fcb517ecef4ed..62b29de1ac617c 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -108,7 +108,6 @@ extern "C" { #define FORMAT_VALUE 155 #define BUILD_CONST_KEY_MAP 156 #define BUILD_STRING 157 -#define LOAD_METHOD 160 #define LIST_EXTEND 162 #define SET_UPDATE 163 #define DICT_MERGE 164 @@ -180,13 +179,13 @@ extern "C" { #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 166 -#define STORE_SUBSCR_LIST_INT 167 -#define UNPACK_SEQUENCE_ADAPTIVE 168 -#define UNPACK_SEQUENCE_LIST 169 -#define UNPACK_SEQUENCE_TUPLE 170 -#define UNPACK_SEQUENCE_TWO_TUPLE 177 +#define STORE_SUBSCR_ADAPTIVE 160 +#define STORE_SUBSCR_DICT 161 +#define STORE_SUBSCR_LIST_INT 166 +#define UNPACK_SEQUENCE_ADAPTIVE 167 +#define UNPACK_SEQUENCE_LIST 168 +#define UNPACK_SEQUENCE_TUPLE 169 +#define UNPACK_SEQUENCE_TWO_TUPLE 170 #define DO_TRACING 255 #define HAS_CONST(op) (false\ diff --git a/Lib/opcode.py b/Lib/opcode.py index 49da4e589b607a..ce5b610c708e97 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -184,8 +184,6 @@ def jabs_op(name, op): def_op('BUILD_CONST_KEY_MAP', 156) def_op('BUILD_STRING', 157) -name_op('LOAD_METHOD', 160) - def_op('LIST_EXTEND', 162) def_op('SET_UPDATE', 163) def_op('DICT_MERGE', 164) diff --git a/Python/ceval.c b/Python/ceval.c index 209162797b9cc6..7a44dfde7eb270 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3451,11 +3451,43 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(LOAD_ATTR) { PREDICTED(LOAD_ATTR); + PyObject* name = GETITEM(names, oparg>>1); + PyObject* owner = TOP(); if (oparg & 1) { - JUMP_TO_INSTRUCTION(LOAD_METHOD); + /* Designed to work in tandem with CALL. */ + PyObject* meth = NULL; + + int meth_found = _PyObject_GetMethod(owner, name, &meth); + + if (meth == NULL) { + /* Most likely attribute wasn't found. */ + goto error; + } + + if (meth_found) { + /* We can bypass temporary bound method object. + meth is unbound method and obj is self. + + meth | self | arg1 | ... | argN + */ + SET_TOP(meth); + PUSH(owner); // self + } + else { + /* meth is not an unbound method (but a regular attr, or + something was returned by a descriptor protocol). Set + the second element of the stack to NULL, to signal + CALL that it's not a method call. + + NULL | meth | arg1 | ... | argN + */ + SET_TOP(NULL); + Py_DECREF(owner); + PUSH(meth); + } + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + DISPATCH(); } - PyObject *name = GETITEM(names, oparg>>1); - PyObject *owner = TOP(); PyObject *res = PyObject_GetAttr(owner, name); if (res == NULL) { goto error; @@ -4492,45 +4524,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int DISPATCH(); } - TARGET(LOAD_METHOD) { - PREDICTED(LOAD_METHOD); - /* Designed to work in tandem with CALL. */ - PyObject *name = GETITEM(names, oparg>>1); - PyObject *obj = TOP(); - PyObject *meth = NULL; - - int meth_found = _PyObject_GetMethod(obj, name, &meth); - - if (meth == NULL) { - /* Most likely attribute wasn't found. */ - goto error; - } - - if (meth_found) { - /* We can bypass temporary bound method object. - meth is unbound method and obj is self. - - meth | self | arg1 | ... | argN - */ - SET_TOP(meth); - PUSH(obj); // self - } - else { - /* meth is not an unbound method (but a regular attr, or - something was returned by a descriptor protocol). Set - the second element of the stack to NULL, to signal - CALL that it's not a method call. - - NULL | meth | arg1 | ... | argN - */ - SET_TOP(NULL); - Py_DECREF(obj); - PUSH(meth); - } - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); - DISPATCH(); - } - TARGET(LOAD_ATTR_METHOD_WITH_VALUES) { /* LOAD_METHOD, with cached method object */ assert(cframe.use_tracing == 0); diff --git a/Python/compile.c b/Python/compile.c index e018359033da27..814a08bf9371c9 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -84,8 +84,9 @@ #define POP_JUMP_IF_TRUE -8 #define POP_JUMP_IF_NONE -9 #define POP_JUMP_IF_NOT_NONE -10 +#define LOAD_METHOD -11 -#define MIN_VIRTUAL_OPCODE -10 +#define MIN_VIRTUAL_OPCODE -11 #define MAX_ALLOWED_OPCODE 254 #define IS_WITHIN_OPCODE_RANGE(opcode) \ diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index ad2ca10f97e258..1c245b32045e06 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -159,24 +159,24 @@ static void *opcode_targets[256] = { &&TARGET_BUILD_STRING, &&TARGET_STORE_FAST__LOAD_FAST, &&TARGET_STORE_FAST__STORE_FAST, - &&TARGET_LOAD_METHOD, &&TARGET_STORE_SUBSCR_ADAPTIVE, + &&TARGET_STORE_SUBSCR_DICT, &&TARGET_LIST_EXTEND, &&TARGET_SET_UPDATE, &&TARGET_DICT_MERGE, &&TARGET_DICT_UPDATE, - &&TARGET_STORE_SUBSCR_DICT, &&TARGET_STORE_SUBSCR_LIST_INT, &&TARGET_UNPACK_SEQUENCE_ADAPTIVE, &&TARGET_UNPACK_SEQUENCE_LIST, &&TARGET_UNPACK_SEQUENCE_TUPLE, + &&TARGET_UNPACK_SEQUENCE_TWO_TUPLE, &&TARGET_CALL, &&TARGET_KW_NAMES, &&TARGET_POP_JUMP_BACKWARD_IF_NOT_NONE, &&TARGET_POP_JUMP_BACKWARD_IF_NONE, &&TARGET_POP_JUMP_BACKWARD_IF_FALSE, &&TARGET_POP_JUMP_BACKWARD_IF_TRUE, - &&TARGET_UNPACK_SEQUENCE_TWO_TUPLE, + &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, From da7fc17be4f1e9bc400b9c74d81a1ebfd27bbdeb Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Tue, 7 Jun 2022 17:47:50 +0800 Subject: [PATCH 05/14] Regen files, add unused field --- Include/internal/pycore_code.h | 1 + Include/internal/pycore_opcode.h | 761 +++++++++++++++++++++++++++++++ Programs/test_frozenmain.h | 42 ++ 3 files changed, 804 insertions(+) diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index a17c9cd8c3b128..398dfe54ed56be 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -67,6 +67,7 @@ typedef struct { typedef struct { _Py_CODEUNIT counter; _Py_CODEUNIT type_version[2]; + _Py_CODEUNIT UNUSED; _Py_CODEUNIT keys_version[2]; _Py_CODEUNIT descr[4]; } _PyLoadMethodCache; diff --git a/Include/internal/pycore_opcode.h b/Include/internal/pycore_opcode.h index e69de29bb2d1d6..2a965e78d0e3f8 100644 --- a/Include/internal/pycore_opcode.h +++ b/Include/internal/pycore_opcode.h @@ -0,0 +1,761 @@ +// Auto-generated by Tools/scripts/generate_opcode_h.py from Lib/opcode.py + +#ifndef Py_INTERNAL_OPCODE_H +#define Py_INTERNAL_OPCODE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "opcode.h" + +extern const uint8_t _PyOpcode_Caches[256]; + +extern const uint8_t _PyOpcode_Deopt[256]; + +extern const uint8_t _PyOpcode_Original[256]; + +#ifdef NEED_OPCODE_TABLES +static const uint32_t _PyOpcode_RelativeJump[8] = { + 0U, + 0U, + 536870912U, + 135118848U, + 4163U, + 122880U, + 0U, + 0U, +}; +static const uint32_t _PyOpcode_Jump[8] = { + 0U, + 0U, + 536870912U, + 135118848U, + 4163U, + 122880U, + 0U, + 0U, +}; + +const uint8_t _PyOpcode_Caches[256] = { + [BINARY_SUBSCR] = 4, + [STORE_SUBSCR] = 1, + [UNPACK_SEQUENCE] = 1, + [STORE_ATTR] = 4, + [LOAD_ATTR] = 10, + [COMPARE_OP] = 2, + [LOAD_GLOBAL] = 5, + [BINARY_OP] = 1, + [CALL] = 4, +}; + +const uint8_t _PyOpcode_Deopt[256] = { + [ASYNC_GEN_WRAP] = ASYNC_GEN_WRAP, + [BEFORE_ASYNC_WITH] = BEFORE_ASYNC_WITH, + [BEFORE_WITH] = BEFORE_WITH, + [BINARY_OP] = BINARY_OP, + [BINARY_OP_ADAPTIVE] = BINARY_OP, + [BINARY_OP_ADD_FLOAT] = BINARY_OP, + [BINARY_OP_ADD_INT] = BINARY_OP, + [BINARY_OP_ADD_UNICODE] = BINARY_OP, + [BINARY_OP_INPLACE_ADD_UNICODE] = BINARY_OP, + [BINARY_OP_MULTIPLY_FLOAT] = BINARY_OP, + [BINARY_OP_MULTIPLY_INT] = BINARY_OP, + [BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP, + [BINARY_OP_SUBTRACT_INT] = BINARY_OP, + [BINARY_SUBSCR] = BINARY_SUBSCR, + [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, + [BUILD_CONST_KEY_MAP] = BUILD_CONST_KEY_MAP, + [BUILD_LIST] = BUILD_LIST, + [BUILD_MAP] = BUILD_MAP, + [BUILD_SET] = BUILD_SET, + [BUILD_SLICE] = BUILD_SLICE, + [BUILD_STRING] = BUILD_STRING, + [BUILD_TUPLE] = BUILD_TUPLE, + [CACHE] = CACHE, + [CALL] = CALL, + [CALL_ADAPTIVE] = CALL, + [CALL_BOUND_METHOD_EXACT_ARGS] = CALL, + [CALL_BUILTIN_CLASS] = CALL, + [CALL_BUILTIN_FAST_WITH_KEYWORDS] = CALL, + [CALL_FUNCTION_EX] = CALL_FUNCTION_EX, + [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = CALL, + [CALL_NO_KW_BUILTIN_FAST] = CALL, + [CALL_NO_KW_BUILTIN_O] = CALL, + [CALL_NO_KW_ISINSTANCE] = CALL, + [CALL_NO_KW_LEN] = CALL, + [CALL_NO_KW_LIST_APPEND] = CALL, + [CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = CALL, + [CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = CALL, + [CALL_NO_KW_METHOD_DESCRIPTOR_O] = CALL, + [CALL_NO_KW_STR_1] = CALL, + [CALL_NO_KW_TUPLE_1] = CALL, + [CALL_NO_KW_TYPE_1] = CALL, + [CALL_PY_EXACT_ARGS] = CALL, + [CALL_PY_WITH_DEFAULTS] = CALL, + [CHECK_EG_MATCH] = CHECK_EG_MATCH, + [CHECK_EXC_MATCH] = CHECK_EXC_MATCH, + [COMPARE_OP] = COMPARE_OP, + [COMPARE_OP_ADAPTIVE] = COMPARE_OP, + [COMPARE_OP_FLOAT_JUMP] = COMPARE_OP, + [COMPARE_OP_INT_JUMP] = COMPARE_OP, + [COMPARE_OP_STR_JUMP] = COMPARE_OP, + [CONTAINS_OP] = CONTAINS_OP, + [COPY] = COPY, + [COPY_FREE_VARS] = COPY_FREE_VARS, + [DELETE_ATTR] = DELETE_ATTR, + [DELETE_DEREF] = DELETE_DEREF, + [DELETE_FAST] = DELETE_FAST, + [DELETE_GLOBAL] = DELETE_GLOBAL, + [DELETE_NAME] = DELETE_NAME, + [DELETE_SUBSCR] = DELETE_SUBSCR, + [DICT_MERGE] = DICT_MERGE, + [DICT_UPDATE] = DICT_UPDATE, + [END_ASYNC_FOR] = END_ASYNC_FOR, + [EXTENDED_ARG] = EXTENDED_ARG, + [EXTENDED_ARG_QUICK] = EXTENDED_ARG, + [FORMAT_VALUE] = FORMAT_VALUE, + [FOR_ITER] = FOR_ITER, + [GET_AITER] = GET_AITER, + [GET_ANEXT] = GET_ANEXT, + [GET_AWAITABLE] = GET_AWAITABLE, + [GET_ITER] = GET_ITER, + [GET_LEN] = GET_LEN, + [GET_YIELD_FROM_ITER] = GET_YIELD_FROM_ITER, + [IMPORT_FROM] = IMPORT_FROM, + [IMPORT_NAME] = IMPORT_NAME, + [IMPORT_STAR] = IMPORT_STAR, + [IS_OP] = IS_OP, + [JUMP_BACKWARD] = JUMP_BACKWARD, + [JUMP_BACKWARD_NO_INTERRUPT] = JUMP_BACKWARD_NO_INTERRUPT, + [JUMP_BACKWARD_QUICK] = JUMP_BACKWARD, + [JUMP_FORWARD] = JUMP_FORWARD, + [JUMP_IF_FALSE_OR_POP] = JUMP_IF_FALSE_OR_POP, + [JUMP_IF_TRUE_OR_POP] = JUMP_IF_TRUE_OR_POP, + [KW_NAMES] = KW_NAMES, + [LIST_APPEND] = LIST_APPEND, + [LIST_EXTEND] = LIST_EXTEND, + [LIST_TO_TUPLE] = LIST_TO_TUPLE, + [LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR, + [LOAD_ATTR] = LOAD_ATTR, + [LOAD_ATTR_ADAPTIVE] = LOAD_ATTR, + [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR, + [LOAD_ATTR_METHOD_CLASS] = LOAD_ATTR, + [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR, + [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR, + [LOAD_ATTR_METHOD_WITH_DICT] = LOAD_ATTR, + [LOAD_ATTR_METHOD_WITH_VALUES] = LOAD_ATTR, + [LOAD_ATTR_MODULE] = LOAD_ATTR, + [LOAD_ATTR_SLOT] = LOAD_ATTR, + [LOAD_ATTR_WITH_HINT] = LOAD_ATTR, + [LOAD_BUILD_CLASS] = LOAD_BUILD_CLASS, + [LOAD_CLASSDEREF] = LOAD_CLASSDEREF, + [LOAD_CLOSURE] = LOAD_CLOSURE, + [LOAD_CONST] = LOAD_CONST, + [LOAD_CONST__LOAD_FAST] = LOAD_CONST, + [LOAD_DEREF] = LOAD_DEREF, + [LOAD_FAST] = LOAD_FAST, + [LOAD_FAST_CHECK] = LOAD_FAST_CHECK, + [LOAD_FAST__LOAD_CONST] = LOAD_FAST, + [LOAD_FAST__LOAD_FAST] = LOAD_FAST, + [LOAD_GLOBAL] = LOAD_GLOBAL, + [LOAD_GLOBAL_ADAPTIVE] = LOAD_GLOBAL, + [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL, + [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL, + [LOAD_NAME] = LOAD_NAME, + [MAKE_CELL] = MAKE_CELL, + [MAKE_FUNCTION] = MAKE_FUNCTION, + [MAP_ADD] = MAP_ADD, + [MATCH_CLASS] = MATCH_CLASS, + [MATCH_KEYS] = MATCH_KEYS, + [MATCH_MAPPING] = MATCH_MAPPING, + [MATCH_SEQUENCE] = MATCH_SEQUENCE, + [NOP] = NOP, + [POP_EXCEPT] = POP_EXCEPT, + [POP_JUMP_BACKWARD_IF_FALSE] = POP_JUMP_BACKWARD_IF_FALSE, + [POP_JUMP_BACKWARD_IF_NONE] = POP_JUMP_BACKWARD_IF_NONE, + [POP_JUMP_BACKWARD_IF_NOT_NONE] = POP_JUMP_BACKWARD_IF_NOT_NONE, + [POP_JUMP_BACKWARD_IF_TRUE] = POP_JUMP_BACKWARD_IF_TRUE, + [POP_JUMP_FORWARD_IF_FALSE] = POP_JUMP_FORWARD_IF_FALSE, + [POP_JUMP_FORWARD_IF_NONE] = POP_JUMP_FORWARD_IF_NONE, + [POP_JUMP_FORWARD_IF_NOT_NONE] = POP_JUMP_FORWARD_IF_NOT_NONE, + [POP_JUMP_FORWARD_IF_TRUE] = POP_JUMP_FORWARD_IF_TRUE, + [POP_TOP] = POP_TOP, + [PREP_RERAISE_STAR] = PREP_RERAISE_STAR, + [PRINT_EXPR] = PRINT_EXPR, + [PUSH_EXC_INFO] = PUSH_EXC_INFO, + [PUSH_NULL] = PUSH_NULL, + [RAISE_VARARGS] = RAISE_VARARGS, + [RERAISE] = RERAISE, + [RESUME] = RESUME, + [RESUME_QUICK] = RESUME, + [RETURN_GENERATOR] = RETURN_GENERATOR, + [RETURN_VALUE] = RETURN_VALUE, + [SEND] = SEND, + [SETUP_ANNOTATIONS] = SETUP_ANNOTATIONS, + [SET_ADD] = SET_ADD, + [SET_UPDATE] = SET_UPDATE, + [STORE_ATTR] = STORE_ATTR, + [STORE_ATTR_ADAPTIVE] = STORE_ATTR, + [STORE_ATTR_INSTANCE_VALUE] = STORE_ATTR, + [STORE_ATTR_SLOT] = STORE_ATTR, + [STORE_ATTR_WITH_HINT] = STORE_ATTR, + [STORE_DEREF] = STORE_DEREF, + [STORE_FAST] = STORE_FAST, + [STORE_FAST__LOAD_FAST] = STORE_FAST, + [STORE_FAST__STORE_FAST] = STORE_FAST, + [STORE_GLOBAL] = STORE_GLOBAL, + [STORE_NAME] = STORE_NAME, + [STORE_SUBSCR] = STORE_SUBSCR, + [STORE_SUBSCR_ADAPTIVE] = STORE_SUBSCR, + [STORE_SUBSCR_DICT] = STORE_SUBSCR, + [STORE_SUBSCR_LIST_INT] = STORE_SUBSCR, + [SWAP] = SWAP, + [UNARY_INVERT] = UNARY_INVERT, + [UNARY_NEGATIVE] = UNARY_NEGATIVE, + [UNARY_NOT] = UNARY_NOT, + [UNARY_POSITIVE] = UNARY_POSITIVE, + [UNPACK_EX] = UNPACK_EX, + [UNPACK_SEQUENCE] = UNPACK_SEQUENCE, + [UNPACK_SEQUENCE_ADAPTIVE] = UNPACK_SEQUENCE, + [UNPACK_SEQUENCE_LIST] = UNPACK_SEQUENCE, + [UNPACK_SEQUENCE_TUPLE] = UNPACK_SEQUENCE, + [UNPACK_SEQUENCE_TWO_TUPLE] = UNPACK_SEQUENCE, + [WITH_EXCEPT_START] = WITH_EXCEPT_START, + [YIELD_VALUE] = YIELD_VALUE, +}; + +const uint8_t _PyOpcode_Original[256] = { + [ASYNC_GEN_WRAP] = ASYNC_GEN_WRAP, + [BEFORE_ASYNC_WITH] = BEFORE_ASYNC_WITH, + [BEFORE_WITH] = BEFORE_WITH, + [BINARY_OP] = BINARY_OP, + [BINARY_OP_ADAPTIVE] = BINARY_OP, + [BINARY_OP_ADD_FLOAT] = BINARY_OP, + [BINARY_OP_ADD_INT] = BINARY_OP, + [BINARY_OP_ADD_UNICODE] = BINARY_OP, + [BINARY_OP_INPLACE_ADD_UNICODE] = BINARY_OP, + [BINARY_OP_MULTIPLY_FLOAT] = BINARY_OP, + [BINARY_OP_MULTIPLY_INT] = BINARY_OP, + [BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP, + [BINARY_OP_SUBTRACT_INT] = BINARY_OP, + [BINARY_SUBSCR] = BINARY_SUBSCR, + [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, + [BUILD_CONST_KEY_MAP] = BUILD_CONST_KEY_MAP, + [BUILD_LIST] = BUILD_LIST, + [BUILD_MAP] = BUILD_MAP, + [BUILD_SET] = BUILD_SET, + [BUILD_SLICE] = BUILD_SLICE, + [BUILD_STRING] = BUILD_STRING, + [BUILD_TUPLE] = BUILD_TUPLE, + [CACHE] = CACHE, + [CALL] = CALL, + [CALL_ADAPTIVE] = CALL, + [CALL_BOUND_METHOD_EXACT_ARGS] = CALL, + [CALL_BUILTIN_CLASS] = CALL, + [CALL_BUILTIN_FAST_WITH_KEYWORDS] = CALL, + [CALL_FUNCTION_EX] = CALL_FUNCTION_EX, + [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = CALL, + [CALL_NO_KW_BUILTIN_FAST] = CALL, + [CALL_NO_KW_BUILTIN_O] = CALL, + [CALL_NO_KW_ISINSTANCE] = CALL, + [CALL_NO_KW_LEN] = CALL, + [CALL_NO_KW_LIST_APPEND] = CALL, + [CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = CALL, + [CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = CALL, + [CALL_NO_KW_METHOD_DESCRIPTOR_O] = CALL, + [CALL_NO_KW_STR_1] = CALL, + [CALL_NO_KW_TUPLE_1] = CALL, + [CALL_NO_KW_TYPE_1] = CALL, + [CALL_PY_EXACT_ARGS] = CALL, + [CALL_PY_WITH_DEFAULTS] = CALL, + [CHECK_EG_MATCH] = CHECK_EG_MATCH, + [CHECK_EXC_MATCH] = CHECK_EXC_MATCH, + [COMPARE_OP] = COMPARE_OP, + [COMPARE_OP_ADAPTIVE] = COMPARE_OP, + [COMPARE_OP_FLOAT_JUMP] = COMPARE_OP, + [COMPARE_OP_INT_JUMP] = COMPARE_OP, + [COMPARE_OP_STR_JUMP] = COMPARE_OP, + [CONTAINS_OP] = CONTAINS_OP, + [COPY] = COPY, + [COPY_FREE_VARS] = COPY_FREE_VARS, + [DELETE_ATTR] = DELETE_ATTR, + [DELETE_DEREF] = DELETE_DEREF, + [DELETE_FAST] = DELETE_FAST, + [DELETE_GLOBAL] = DELETE_GLOBAL, + [DELETE_NAME] = DELETE_NAME, + [DELETE_SUBSCR] = DELETE_SUBSCR, + [DICT_MERGE] = DICT_MERGE, + [DICT_UPDATE] = DICT_UPDATE, + [END_ASYNC_FOR] = END_ASYNC_FOR, + [EXTENDED_ARG] = EXTENDED_ARG_QUICK, + [EXTENDED_ARG_QUICK] = EXTENDED_ARG_QUICK, + [FORMAT_VALUE] = FORMAT_VALUE, + [FOR_ITER] = FOR_ITER, + [GET_AITER] = GET_AITER, + [GET_ANEXT] = GET_ANEXT, + [GET_AWAITABLE] = GET_AWAITABLE, + [GET_ITER] = GET_ITER, + [GET_LEN] = GET_LEN, + [GET_YIELD_FROM_ITER] = GET_YIELD_FROM_ITER, + [IMPORT_FROM] = IMPORT_FROM, + [IMPORT_NAME] = IMPORT_NAME, + [IMPORT_STAR] = IMPORT_STAR, + [IS_OP] = IS_OP, + [JUMP_BACKWARD] = JUMP_BACKWARD, + [JUMP_BACKWARD_NO_INTERRUPT] = JUMP_BACKWARD_NO_INTERRUPT, + [JUMP_BACKWARD_QUICK] = JUMP_BACKWARD, + [JUMP_FORWARD] = JUMP_FORWARD, + [JUMP_IF_FALSE_OR_POP] = JUMP_IF_FALSE_OR_POP, + [JUMP_IF_TRUE_OR_POP] = JUMP_IF_TRUE_OR_POP, + [KW_NAMES] = KW_NAMES, + [LIST_APPEND] = LIST_APPEND, + [LIST_EXTEND] = LIST_EXTEND, + [LIST_TO_TUPLE] = LIST_TO_TUPLE, + [LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR, + [LOAD_ATTR] = LOAD_ATTR, + [LOAD_ATTR_ADAPTIVE] = LOAD_ATTR, + [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR, + [LOAD_ATTR_METHOD_CLASS] = LOAD_ATTR, + [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR, + [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR, + [LOAD_ATTR_METHOD_WITH_DICT] = LOAD_ATTR, + [LOAD_ATTR_METHOD_WITH_VALUES] = LOAD_ATTR, + [LOAD_ATTR_MODULE] = LOAD_ATTR, + [LOAD_ATTR_SLOT] = LOAD_ATTR, + [LOAD_ATTR_WITH_HINT] = LOAD_ATTR, + [LOAD_BUILD_CLASS] = LOAD_BUILD_CLASS, + [LOAD_CLASSDEREF] = LOAD_CLASSDEREF, + [LOAD_CLOSURE] = LOAD_CLOSURE, + [LOAD_CONST] = LOAD_CONST, + [LOAD_CONST__LOAD_FAST] = LOAD_CONST, + [LOAD_DEREF] = LOAD_DEREF, + [LOAD_FAST] = LOAD_FAST, + [LOAD_FAST_CHECK] = LOAD_FAST_CHECK, + [LOAD_FAST__LOAD_CONST] = LOAD_FAST, + [LOAD_FAST__LOAD_FAST] = LOAD_FAST, + [LOAD_GLOBAL] = LOAD_GLOBAL, + [LOAD_GLOBAL_ADAPTIVE] = LOAD_GLOBAL, + [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL, + [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL, + [LOAD_NAME] = LOAD_NAME, + [MAKE_CELL] = MAKE_CELL, + [MAKE_FUNCTION] = MAKE_FUNCTION, + [MAP_ADD] = MAP_ADD, + [MATCH_CLASS] = MATCH_CLASS, + [MATCH_KEYS] = MATCH_KEYS, + [MATCH_MAPPING] = MATCH_MAPPING, + [MATCH_SEQUENCE] = MATCH_SEQUENCE, + [NOP] = NOP, + [POP_EXCEPT] = POP_EXCEPT, + [POP_JUMP_BACKWARD_IF_FALSE] = POP_JUMP_BACKWARD_IF_FALSE, + [POP_JUMP_BACKWARD_IF_NONE] = POP_JUMP_BACKWARD_IF_NONE, + [POP_JUMP_BACKWARD_IF_NOT_NONE] = POP_JUMP_BACKWARD_IF_NOT_NONE, + [POP_JUMP_BACKWARD_IF_TRUE] = POP_JUMP_BACKWARD_IF_TRUE, + [POP_JUMP_FORWARD_IF_FALSE] = POP_JUMP_FORWARD_IF_FALSE, + [POP_JUMP_FORWARD_IF_NONE] = POP_JUMP_FORWARD_IF_NONE, + [POP_JUMP_FORWARD_IF_NOT_NONE] = POP_JUMP_FORWARD_IF_NOT_NONE, + [POP_JUMP_FORWARD_IF_TRUE] = POP_JUMP_FORWARD_IF_TRUE, + [POP_TOP] = POP_TOP, + [PREP_RERAISE_STAR] = PREP_RERAISE_STAR, + [PRINT_EXPR] = PRINT_EXPR, + [PUSH_EXC_INFO] = PUSH_EXC_INFO, + [PUSH_NULL] = PUSH_NULL, + [RAISE_VARARGS] = RAISE_VARARGS, + [RERAISE] = RERAISE, + [RESUME] = RESUME, + [RESUME_QUICK] = RESUME, + [RETURN_GENERATOR] = RETURN_GENERATOR, + [RETURN_VALUE] = RETURN_VALUE, + [SEND] = SEND, + [SETUP_ANNOTATIONS] = SETUP_ANNOTATIONS, + [SET_ADD] = SET_ADD, + [SET_UPDATE] = SET_UPDATE, + [STORE_ATTR] = STORE_ATTR, + [STORE_ATTR_ADAPTIVE] = STORE_ATTR, + [STORE_ATTR_INSTANCE_VALUE] = STORE_ATTR, + [STORE_ATTR_SLOT] = STORE_ATTR, + [STORE_ATTR_WITH_HINT] = STORE_ATTR, + [STORE_DEREF] = STORE_DEREF, + [STORE_FAST] = STORE_FAST, + [STORE_FAST__LOAD_FAST] = STORE_FAST, + [STORE_FAST__STORE_FAST] = STORE_FAST, + [STORE_GLOBAL] = STORE_GLOBAL, + [STORE_NAME] = STORE_NAME, + [STORE_SUBSCR] = STORE_SUBSCR, + [STORE_SUBSCR_ADAPTIVE] = STORE_SUBSCR, + [STORE_SUBSCR_DICT] = STORE_SUBSCR, + [STORE_SUBSCR_LIST_INT] = STORE_SUBSCR, + [SWAP] = SWAP, + [UNARY_INVERT] = UNARY_INVERT, + [UNARY_NEGATIVE] = UNARY_NEGATIVE, + [UNARY_NOT] = UNARY_NOT, + [UNARY_POSITIVE] = UNARY_POSITIVE, + [UNPACK_EX] = UNPACK_EX, + [UNPACK_SEQUENCE] = UNPACK_SEQUENCE, + [UNPACK_SEQUENCE_ADAPTIVE] = UNPACK_SEQUENCE, + [UNPACK_SEQUENCE_LIST] = UNPACK_SEQUENCE, + [UNPACK_SEQUENCE_TUPLE] = UNPACK_SEQUENCE, + [UNPACK_SEQUENCE_TWO_TUPLE] = UNPACK_SEQUENCE, + [WITH_EXCEPT_START] = WITH_EXCEPT_START, + [YIELD_VALUE] = YIELD_VALUE, +}; +#endif // NEED_OPCODE_TABLES + +#ifdef Py_DEBUG +static const char *const _PyOpcode_OpName[256] = { + [CACHE] = "CACHE", + [POP_TOP] = "POP_TOP", + [PUSH_NULL] = "PUSH_NULL", + [BINARY_OP_ADAPTIVE] = "BINARY_OP_ADAPTIVE", + [BINARY_OP_ADD_FLOAT] = "BINARY_OP_ADD_FLOAT", + [BINARY_OP_ADD_INT] = "BINARY_OP_ADD_INT", + [BINARY_OP_ADD_UNICODE] = "BINARY_OP_ADD_UNICODE", + [BINARY_OP_INPLACE_ADD_UNICODE] = "BINARY_OP_INPLACE_ADD_UNICODE", + [BINARY_OP_MULTIPLY_FLOAT] = "BINARY_OP_MULTIPLY_FLOAT", + [NOP] = "NOP", + [UNARY_POSITIVE] = "UNARY_POSITIVE", + [UNARY_NEGATIVE] = "UNARY_NEGATIVE", + [UNARY_NOT] = "UNARY_NOT", + [BINARY_OP_MULTIPLY_INT] = "BINARY_OP_MULTIPLY_INT", + [BINARY_OP_SUBTRACT_FLOAT] = "BINARY_OP_SUBTRACT_FLOAT", + [UNARY_INVERT] = "UNARY_INVERT", + [BINARY_OP_SUBTRACT_INT] = "BINARY_OP_SUBTRACT_INT", + [BINARY_SUBSCR_ADAPTIVE] = "BINARY_SUBSCR_ADAPTIVE", + [BINARY_SUBSCR_DICT] = "BINARY_SUBSCR_DICT", + [BINARY_SUBSCR_GETITEM] = "BINARY_SUBSCR_GETITEM", + [BINARY_SUBSCR_LIST_INT] = "BINARY_SUBSCR_LIST_INT", + [BINARY_SUBSCR_TUPLE_INT] = "BINARY_SUBSCR_TUPLE_INT", + [CALL_ADAPTIVE] = "CALL_ADAPTIVE", + [CALL_PY_EXACT_ARGS] = "CALL_PY_EXACT_ARGS", + [CALL_PY_WITH_DEFAULTS] = "CALL_PY_WITH_DEFAULTS", + [BINARY_SUBSCR] = "BINARY_SUBSCR", + [CALL_BOUND_METHOD_EXACT_ARGS] = "CALL_BOUND_METHOD_EXACT_ARGS", + [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", + [MATCH_MAPPING] = "MATCH_MAPPING", + [MATCH_SEQUENCE] = "MATCH_SEQUENCE", + [MATCH_KEYS] = "MATCH_KEYS", + [CALL_NO_KW_BUILTIN_FAST] = "CALL_NO_KW_BUILTIN_FAST", + [PUSH_EXC_INFO] = "PUSH_EXC_INFO", + [CHECK_EXC_MATCH] = "CHECK_EXC_MATCH", + [CHECK_EG_MATCH] = "CHECK_EG_MATCH", + [CALL_NO_KW_BUILTIN_O] = "CALL_NO_KW_BUILTIN_O", + [CALL_NO_KW_ISINSTANCE] = "CALL_NO_KW_ISINSTANCE", + [CALL_NO_KW_LEN] = "CALL_NO_KW_LEN", + [CALL_NO_KW_LIST_APPEND] = "CALL_NO_KW_LIST_APPEND", + [CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = "CALL_NO_KW_METHOD_DESCRIPTOR_FAST", + [CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = "CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS", + [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_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", + [GET_AITER] = "GET_AITER", + [GET_ANEXT] = "GET_ANEXT", + [BEFORE_ASYNC_WITH] = "BEFORE_ASYNC_WITH", + [BEFORE_WITH] = "BEFORE_WITH", + [END_ASYNC_FOR] = "END_ASYNC_FOR", + [COMPARE_OP_FLOAT_JUMP] = "COMPARE_OP_FLOAT_JUMP", + [COMPARE_OP_INT_JUMP] = "COMPARE_OP_INT_JUMP", + [COMPARE_OP_STR_JUMP] = "COMPARE_OP_STR_JUMP", + [EXTENDED_ARG_QUICK] = "EXTENDED_ARG_QUICK", + [JUMP_BACKWARD_QUICK] = "JUMP_BACKWARD_QUICK", + [STORE_SUBSCR] = "STORE_SUBSCR", + [DELETE_SUBSCR] = "DELETE_SUBSCR", + [LOAD_ATTR_ADAPTIVE] = "LOAD_ATTR_ADAPTIVE", + [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE", + [LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE", + [LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT", + [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT", + [LOAD_ATTR_METHOD_CLASS] = "LOAD_ATTR_METHOD_CLASS", + [GET_ITER] = "GET_ITER", + [GET_YIELD_FROM_ITER] = "GET_YIELD_FROM_ITER", + [PRINT_EXPR] = "PRINT_EXPR", + [LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS", + [LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT", + [LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT", + [LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR", + [RETURN_GENERATOR] = "RETURN_GENERATOR", + [LOAD_ATTR_METHOD_WITH_DICT] = "LOAD_ATTR_METHOD_WITH_DICT", + [LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES", + [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST", + [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST", + [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST", + [LOAD_GLOBAL_ADAPTIVE] = "LOAD_GLOBAL_ADAPTIVE", + [LIST_TO_TUPLE] = "LIST_TO_TUPLE", + [RETURN_VALUE] = "RETURN_VALUE", + [IMPORT_STAR] = "IMPORT_STAR", + [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS", + [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", + [ASYNC_GEN_WRAP] = "ASYNC_GEN_WRAP", + [PREP_RERAISE_STAR] = "PREP_RERAISE_STAR", + [POP_EXCEPT] = "POP_EXCEPT", + [STORE_NAME] = "STORE_NAME", + [DELETE_NAME] = "DELETE_NAME", + [UNPACK_SEQUENCE] = "UNPACK_SEQUENCE", + [FOR_ITER] = "FOR_ITER", + [UNPACK_EX] = "UNPACK_EX", + [STORE_ATTR] = "STORE_ATTR", + [DELETE_ATTR] = "DELETE_ATTR", + [STORE_GLOBAL] = "STORE_GLOBAL", + [DELETE_GLOBAL] = "DELETE_GLOBAL", + [SWAP] = "SWAP", + [LOAD_CONST] = "LOAD_CONST", + [LOAD_NAME] = "LOAD_NAME", + [BUILD_TUPLE] = "BUILD_TUPLE", + [BUILD_LIST] = "BUILD_LIST", + [BUILD_SET] = "BUILD_SET", + [BUILD_MAP] = "BUILD_MAP", + [LOAD_ATTR] = "LOAD_ATTR", + [COMPARE_OP] = "COMPARE_OP", + [IMPORT_NAME] = "IMPORT_NAME", + [IMPORT_FROM] = "IMPORT_FROM", + [JUMP_FORWARD] = "JUMP_FORWARD", + [JUMP_IF_FALSE_OR_POP] = "JUMP_IF_FALSE_OR_POP", + [JUMP_IF_TRUE_OR_POP] = "JUMP_IF_TRUE_OR_POP", + [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", + [POP_JUMP_FORWARD_IF_FALSE] = "POP_JUMP_FORWARD_IF_FALSE", + [POP_JUMP_FORWARD_IF_TRUE] = "POP_JUMP_FORWARD_IF_TRUE", + [LOAD_GLOBAL] = "LOAD_GLOBAL", + [IS_OP] = "IS_OP", + [CONTAINS_OP] = "CONTAINS_OP", + [RERAISE] = "RERAISE", + [COPY] = "COPY", + [RESUME_QUICK] = "RESUME_QUICK", + [BINARY_OP] = "BINARY_OP", + [SEND] = "SEND", + [LOAD_FAST] = "LOAD_FAST", + [STORE_FAST] = "STORE_FAST", + [DELETE_FAST] = "DELETE_FAST", + [LOAD_FAST_CHECK] = "LOAD_FAST_CHECK", + [POP_JUMP_FORWARD_IF_NOT_NONE] = "POP_JUMP_FORWARD_IF_NOT_NONE", + [POP_JUMP_FORWARD_IF_NONE] = "POP_JUMP_FORWARD_IF_NONE", + [RAISE_VARARGS] = "RAISE_VARARGS", + [GET_AWAITABLE] = "GET_AWAITABLE", + [MAKE_FUNCTION] = "MAKE_FUNCTION", + [BUILD_SLICE] = "BUILD_SLICE", + [JUMP_BACKWARD_NO_INTERRUPT] = "JUMP_BACKWARD_NO_INTERRUPT", + [MAKE_CELL] = "MAKE_CELL", + [LOAD_CLOSURE] = "LOAD_CLOSURE", + [LOAD_DEREF] = "LOAD_DEREF", + [STORE_DEREF] = "STORE_DEREF", + [DELETE_DEREF] = "DELETE_DEREF", + [JUMP_BACKWARD] = "JUMP_BACKWARD", + [STORE_ATTR_ADAPTIVE] = "STORE_ATTR_ADAPTIVE", + [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX", + [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE", + [EXTENDED_ARG] = "EXTENDED_ARG", + [LIST_APPEND] = "LIST_APPEND", + [SET_ADD] = "SET_ADD", + [MAP_ADD] = "MAP_ADD", + [LOAD_CLASSDEREF] = "LOAD_CLASSDEREF", + [COPY_FREE_VARS] = "COPY_FREE_VARS", + [YIELD_VALUE] = "YIELD_VALUE", + [RESUME] = "RESUME", + [MATCH_CLASS] = "MATCH_CLASS", + [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT", + [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT", + [FORMAT_VALUE] = "FORMAT_VALUE", + [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP", + [BUILD_STRING] = "BUILD_STRING", + [STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST", + [STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST", + [STORE_SUBSCR_ADAPTIVE] = "STORE_SUBSCR_ADAPTIVE", + [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT", + [LIST_EXTEND] = "LIST_EXTEND", + [SET_UPDATE] = "SET_UPDATE", + [DICT_MERGE] = "DICT_MERGE", + [DICT_UPDATE] = "DICT_UPDATE", + [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT", + [UNPACK_SEQUENCE_ADAPTIVE] = "UNPACK_SEQUENCE_ADAPTIVE", + [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST", + [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE", + [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE", + [CALL] = "CALL", + [KW_NAMES] = "KW_NAMES", + [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_FALSE] = "POP_JUMP_BACKWARD_IF_FALSE", + [POP_JUMP_BACKWARD_IF_TRUE] = "POP_JUMP_BACKWARD_IF_TRUE", + [177] = "<177>", + [178] = "<178>", + [179] = "<179>", + [180] = "<180>", + [181] = "<181>", + [182] = "<182>", + [183] = "<183>", + [184] = "<184>", + [185] = "<185>", + [186] = "<186>", + [187] = "<187>", + [188] = "<188>", + [189] = "<189>", + [190] = "<190>", + [191] = "<191>", + [192] = "<192>", + [193] = "<193>", + [194] = "<194>", + [195] = "<195>", + [196] = "<196>", + [197] = "<197>", + [198] = "<198>", + [199] = "<199>", + [200] = "<200>", + [201] = "<201>", + [202] = "<202>", + [203] = "<203>", + [204] = "<204>", + [205] = "<205>", + [206] = "<206>", + [207] = "<207>", + [208] = "<208>", + [209] = "<209>", + [210] = "<210>", + [211] = "<211>", + [212] = "<212>", + [213] = "<213>", + [214] = "<214>", + [215] = "<215>", + [216] = "<216>", + [217] = "<217>", + [218] = "<218>", + [219] = "<219>", + [220] = "<220>", + [221] = "<221>", + [222] = "<222>", + [223] = "<223>", + [224] = "<224>", + [225] = "<225>", + [226] = "<226>", + [227] = "<227>", + [228] = "<228>", + [229] = "<229>", + [230] = "<230>", + [231] = "<231>", + [232] = "<232>", + [233] = "<233>", + [234] = "<234>", + [235] = "<235>", + [236] = "<236>", + [237] = "<237>", + [238] = "<238>", + [239] = "<239>", + [240] = "<240>", + [241] = "<241>", + [242] = "<242>", + [243] = "<243>", + [244] = "<244>", + [245] = "<245>", + [246] = "<246>", + [247] = "<247>", + [248] = "<248>", + [249] = "<249>", + [250] = "<250>", + [251] = "<251>", + [252] = "<252>", + [253] = "<253>", + [254] = "<254>", + [DO_TRACING] = "DO_TRACING", +}; +#endif + +#define EXTRA_CASES \ + case 177: \ + case 178: \ + case 179: \ + case 180: \ + case 181: \ + case 182: \ + case 183: \ + case 184: \ + case 185: \ + case 186: \ + case 187: \ + case 188: \ + case 189: \ + case 190: \ + case 191: \ + case 192: \ + case 193: \ + case 194: \ + case 195: \ + case 196: \ + case 197: \ + case 198: \ + case 199: \ + case 200: \ + case 201: \ + case 202: \ + case 203: \ + case 204: \ + case 205: \ + case 206: \ + case 207: \ + case 208: \ + case 209: \ + case 210: \ + case 211: \ + case 212: \ + case 213: \ + case 214: \ + case 215: \ + case 216: \ + case 217: \ + case 218: \ + case 219: \ + case 220: \ + case 221: \ + case 222: \ + case 223: \ + case 224: \ + case 225: \ + case 226: \ + case 227: \ + case 228: \ + case 229: \ + case 230: \ + case 231: \ + case 232: \ + case 233: \ + case 234: \ + case 235: \ + case 236: \ + case 237: \ + case 238: \ + case 239: \ + case 240: \ + case 241: \ + case 242: \ + case 243: \ + case 244: \ + case 245: \ + case 246: \ + case 247: \ + case 248: \ + case 249: \ + case 250: \ + case 251: \ + case 252: \ + case 253: \ + case 254: \ + ; + +#ifdef __cplusplus +} +#endif +#endif // !Py_INTERNAL_OPCODE_H diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index e69de29bb2d1d6..a0004582f227fd 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -0,0 +1,42 @@ +// Auto-generated by Programs/freeze_test_frozenmain.py +unsigned char M_test_frozenmain[] = { + 227,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0, + 0,0,0,0,0,243,184,0,0,0,151,0,100,0,100,1, + 108,0,90,0,100,0,100,1,108,1,90,1,2,0,101,2, + 100,2,171,1,0,0,0,0,0,0,0,0,1,0,2,0, + 101,2,100,3,101,0,106,6,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,171,2,0,0, + 0,0,0,0,0,0,1,0,2,0,101,1,106,8,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,171,0,0,0,0,0,0,0,0,0,100,4,25,0, + 0,0,0,0,0,0,0,0,90,5,100,5,68,0,93,23, + 90,6,2,0,101,2,100,6,101,6,155,0,100,7,101,5, + 101,6,25,0,0,0,0,0,0,0,0,0,155,0,157,4, + 171,1,0,0,0,0,0,0,0,0,1,0,140,24,100,1, + 83,0,41,8,233,0,0,0,0,78,122,18,70,114,111,122, + 101,110,32,72,101,108,108,111,32,87,111,114,108,100,122,8, + 115,121,115,46,97,114,103,118,218,6,99,111,110,102,105,103, + 41,5,218,12,112,114,111,103,114,97,109,95,110,97,109,101, + 218,10,101,120,101,99,117,116,97,98,108,101,218,15,117,115, + 101,95,101,110,118,105,114,111,110,109,101,110,116,218,17,99, + 111,110,102,105,103,117,114,101,95,99,95,115,116,100,105,111, + 218,14,98,117,102,102,101,114,101,100,95,115,116,100,105,111, + 122,7,99,111,110,102,105,103,32,122,2,58,32,41,7,218, + 3,115,121,115,218,17,95,116,101,115,116,105,110,116,101,114, + 110,97,108,99,97,112,105,218,5,112,114,105,110,116,218,4, + 97,114,103,118,218,11,103,101,116,95,99,111,110,102,105,103, + 115,114,3,0,0,0,218,3,107,101,121,169,0,243,0,0, + 0,0,250,18,116,101,115,116,95,102,114,111,122,101,110,109, + 97,105,110,46,112,121,250,8,60,109,111,100,117,108,101,62, + 114,18,0,0,0,1,0,0,0,115,145,0,0,0,248,240, + 6,0,1,11,128,10,128,10,128,10,216,0,24,208,0,24, + 208,0,24,208,0,24,224,0,5,128,5,208,6,26,212,0, + 27,208,0,27,216,0,5,128,5,128,106,144,35,151,40,146, + 40,212,0,27,208,0,27,216,9,38,208,9,26,215,9,38, + 210,9,38,212,9,40,168,24,212,9,50,128,6,240,2,6, + 12,2,240,0,7,1,42,240,0,7,1,42,128,67,240,14, + 0,5,10,128,69,208,10,40,144,67,208,10,40,208,10,40, + 152,54,160,35,156,59,208,10,40,208,10,40,212,4,41,208, + 4,41,208,4,41,240,15,7,1,42,240,0,7,1,42,114, + 16,0,0,0, +}; From 65e6abaef2b10d5208c695ce829b0af794691966 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Tue, 7 Jun 2022 18:11:20 +0800 Subject: [PATCH 06/14] Merge specialization code more (stats are still broken) --- Include/internal/pycore_opcode.h | 6 +-- Include/opcode.h | 10 ++--- Lib/opcode.py | 2 +- Python/ceval.c | 47 ++++++++++++----------- Python/opcode_targets.h | 2 +- Python/specialize.c | 65 ++++++++++++-------------------- 6 files changed, 59 insertions(+), 73 deletions(-) diff --git a/Include/internal/pycore_opcode.h b/Include/internal/pycore_opcode.h index 2a965e78d0e3f8..9d5de97b7994c2 100644 --- a/Include/internal/pycore_opcode.h +++ b/Include/internal/pycore_opcode.h @@ -146,8 +146,8 @@ const uint8_t _PyOpcode_Deopt[256] = { [LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR, [LOAD_ATTR] = LOAD_ATTR, [LOAD_ATTR_ADAPTIVE] = LOAD_ATTR, + [LOAD_ATTR_CLASS] = LOAD_ATTR, [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR, - [LOAD_ATTR_METHOD_CLASS] = LOAD_ATTR, [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR, [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR, [LOAD_ATTR_METHOD_WITH_DICT] = LOAD_ATTR, @@ -326,8 +326,8 @@ const uint8_t _PyOpcode_Original[256] = { [LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR, [LOAD_ATTR] = LOAD_ATTR, [LOAD_ATTR_ADAPTIVE] = LOAD_ATTR, + [LOAD_ATTR_CLASS] = LOAD_ATTR, [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR, - [LOAD_ATTR_METHOD_CLASS] = LOAD_ATTR, [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR, [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR, [LOAD_ATTR_METHOD_WITH_DICT] = LOAD_ATTR, @@ -478,11 +478,11 @@ static const char *const _PyOpcode_OpName[256] = { [STORE_SUBSCR] = "STORE_SUBSCR", [DELETE_SUBSCR] = "DELETE_SUBSCR", [LOAD_ATTR_ADAPTIVE] = "LOAD_ATTR_ADAPTIVE", + [LOAD_ATTR_CLASS] = "LOAD_ATTR_CLASS", [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE", [LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE", [LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT", [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT", - [LOAD_ATTR_METHOD_CLASS] = "LOAD_ATTR_METHOD_CLASS", [GET_ITER] = "GET_ITER", [GET_YIELD_FROM_ITER] = "GET_YIELD_FROM_ITER", [PRINT_EXPR] = "PRINT_EXPR", diff --git a/Include/opcode.h b/Include/opcode.h index 62b29de1ac617c..04e5bc8310ffb3 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -157,11 +157,11 @@ extern "C" { #define EXTENDED_ARG_QUICK 58 #define JUMP_BACKWARD_QUICK 59 #define LOAD_ATTR_ADAPTIVE 62 -#define LOAD_ATTR_INSTANCE_VALUE 63 -#define LOAD_ATTR_MODULE 64 -#define LOAD_ATTR_SLOT 65 -#define LOAD_ATTR_WITH_HINT 66 -#define LOAD_ATTR_METHOD_CLASS 67 +#define LOAD_ATTR_CLASS 63 +#define LOAD_ATTR_INSTANCE_VALUE 64 +#define LOAD_ATTR_MODULE 65 +#define LOAD_ATTR_SLOT 66 +#define LOAD_ATTR_WITH_HINT 67 #define LOAD_ATTR_METHOD_LAZY_DICT 72 #define LOAD_ATTR_METHOD_NO_DICT 73 #define LOAD_ATTR_METHOD_WITH_DICT 76 diff --git a/Lib/opcode.py b/Lib/opcode.py index ce5b610c708e97..78b36ce8684696 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -284,12 +284,12 @@ def jabs_op(name, op): "LOAD_ATTR": [ "LOAD_ATTR_ADAPTIVE", # LOAD_ATTR + "LOAD_ATTR_CLASS", "LOAD_ATTR_INSTANCE_VALUE", "LOAD_ATTR_MODULE", "LOAD_ATTR_SLOT", "LOAD_ATTR_WITH_HINT", # LOAD_METHOD - "LOAD_ATTR_METHOD_CLASS", "LOAD_ATTR_METHOD_LAZY_DICT", "LOAD_ATTR_METHOD_NO_DICT", "LOAD_ATTR_METHOD_WITH_DICT", diff --git a/Python/ceval.c b/Python/ceval.c index 7f8cd6c759b558..a9635879fe08e6 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3626,6 +3626,30 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int NOTRACE_DISPATCH(); } + TARGET(LOAD_ATTR_CLASS) { + /* LOAD_METHOD, for class methods */ + assert(cframe.use_tracing == 0); + _PyLoadMethodCache* cache = (_PyLoadMethodCache*)next_instr; + + PyObject* cls = TOP(); + DEOPT_IF(!PyType_Check(cls), LOAD_ATTR); + uint32_t type_version = read_u32(cache->type_version); + DEOPT_IF(((PyTypeObject*)cls)->tp_version_tag != type_version, + LOAD_ATTR); + assert(type_version != 0); + + STAT_INC(LOAD_ATTR, hit); + PyObject* res = read_obj(cache->descr); + assert(res != NULL); + Py_INCREF(res); + SET_TOP(NULL); + STACK_GROW((oparg & 1)); + SET_TOP(res); + Py_DECREF(cls); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + NOTRACE_DISPATCH(); + } + TARGET(STORE_ATTR_ADAPTIVE) { assert(cframe.use_tracing == 0); _PyAttrCache *cache = (_PyAttrCache *)next_instr; @@ -4621,29 +4645,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int NOTRACE_DISPATCH(); } - TARGET(LOAD_ATTR_METHOD_CLASS) { - /* LOAD_METHOD, for class methods */ - assert(cframe.use_tracing == 0); - _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; - - PyObject *cls = TOP(); - DEOPT_IF(!PyType_Check(cls), LOAD_ATTR); - uint32_t type_version = read_u32(cache->type_version); - DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != type_version, - LOAD_ATTR); - assert(type_version != 0); - - STAT_INC(LOAD_ATTR, hit); - PyObject *res = read_obj(cache->descr); - assert(res != NULL); - Py_INCREF(res); - SET_TOP(NULL); - Py_DECREF(cls); - PUSH(res); - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); - NOTRACE_DISPATCH(); - } - TARGET(CALL_BOUND_METHOD_EXACT_ARGS) { DEOPT_IF(is_method(stack_pointer, oparg), CALL); PyObject *function = PEEK(oparg + 1); diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 1c245b32045e06..a6523d4af2b783 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -62,11 +62,11 @@ static void *opcode_targets[256] = { &&TARGET_STORE_SUBSCR, &&TARGET_DELETE_SUBSCR, &&TARGET_LOAD_ATTR_ADAPTIVE, + &&TARGET_LOAD_ATTR_CLASS, &&TARGET_LOAD_ATTR_INSTANCE_VALUE, &&TARGET_LOAD_ATTR_MODULE, &&TARGET_LOAD_ATTR_SLOT, &&TARGET_LOAD_ATTR_WITH_HINT, - &&TARGET_LOAD_ATTR_METHOD_CLASS, &&TARGET_GET_ITER, &&TARGET_GET_YIELD_FROM_ITER, &&TARGET_PRINT_EXPR, diff --git a/Python/specialize.c b/Python/specialize.c index fe4ffe2cd1edea..448bc8d5cde83d 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -653,8 +653,9 @@ specialize_dict_access( return 1; } -static int -specialize_attr_loadmethod(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name); +static int specialize_attr_loadmethod(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name, + PyObject* descr, DescriptorClassification kind); +static int specialize_class_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name); int _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) @@ -669,25 +670,29 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) } goto success; } - int oparg = _Py_OPARG(*instr); - if (oparg & 1) { - int res = specialize_attr_loadmethod(owner, instr, name); - if (res < 0) { - return -1; - } - else if (res) { - goto success; + if (PyType_Check(owner)) { + int err = specialize_class_load_attr(owner, instr, name); + if (err) { + goto fail; } - /* res == 0 (fail), fall through and let LOAD_ATTR specialize for it */ + goto success; } - PyTypeObject *type = Py_TYPE(owner); + int oparg = _Py_OPARG(*instr); + PyTypeObject* type = Py_TYPE(owner); if (type->tp_dict == NULL) { if (PyType_Ready(type) < 0) { return -1; } } - PyObject *descr; + PyObject* descr = NULL; DescriptorClassification kind = analyze_descriptor(type, name, &descr, 0); + assert(descr != NULL || kind == ABSENT || kind == GETSET_OVERRIDDEN); + if ((oparg & 1) && kind == METHOD) { + if (specialize_attr_loadmethod(owner, instr, name, descr, kind)) { + goto success; + } + /* res == 0 (fail), fall through and let LOAD_ATTR specialize for it */ + } switch(kind) { case OVERRIDING: SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR); @@ -885,7 +890,7 @@ load_method_fail_kind(DescriptorClassification kind) #endif static int -specialize_class_load_method(PyObject *owner, _Py_CODEUNIT *instr, +specialize_class_load_attr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) { _PyLoadMethodCache *cache = (_PyLoadMethodCache *)(instr + 1); @@ -897,7 +902,7 @@ specialize_class_load_method(PyObject *owner, _Py_CODEUNIT *instr, case NON_DESCRIPTOR: write_u32(cache->type_version, ((PyTypeObject *)owner)->tp_version_tag); write_obj(cache->descr, descr); - _Py_SET_OPCODE(*instr, LOAD_ATTR_METHOD_CLASS); + _Py_SET_OPCODE(*instr, LOAD_ATTR_CLASS); return 0; #ifdef Py_STATS case ABSENT: @@ -927,32 +932,13 @@ typedef enum { // can cause a significant drop in cache hits. A possible test is // python.exe -m test_typing test_re test_dis test_zlib. static int -specialize_attr_loadmethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) +specialize_attr_loadmethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, +PyObject *descr, DescriptorClassification kind) { _PyLoadMethodCache *cache = (_PyLoadMethodCache *)(instr + 1); PyTypeObject *owner_cls = Py_TYPE(owner); - if (owner_cls->tp_dict == NULL) { - if (PyType_Ready(owner_cls) < 0) { - return -1; - } - } - if (PyType_Check(owner)) { - int err = specialize_class_load_method(owner, instr, name); - if (err) { - goto fail; - } - goto success; - } - - PyObject *descr = NULL; - DescriptorClassification kind = 0; - kind = analyze_descriptor(owner_cls, name, &descr, 0); - assert(descr != NULL || kind == ABSENT || kind == GETSET_OVERRIDDEN); - if (kind != METHOD) { - SPECIALIZATION_FAIL(LOAD_METHOD, load_method_fail_kind(kind)); - goto fail; - } + assert(kind == METHOD && descr != NULL); ObjectDictKind dictkind; PyDictKeysObject *keys; if (owner_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT) { @@ -968,7 +954,7 @@ specialize_attr_loadmethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) else { Py_ssize_t dictoffset = owner_cls->tp_dictoffset; if (dictoffset < 0 || dictoffset > INT16_MAX) { - SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OUT_OF_RANGE); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_RANGE); goto fail; } if (dictoffset == 0) { @@ -996,7 +982,7 @@ specialize_attr_loadmethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) } uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState(keys); if (keys_version == 0) { - SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OUT_OF_VERSIONS); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS); goto fail; } write_u32(cache->keys_version, keys_version); @@ -1037,7 +1023,6 @@ specialize_attr_loadmethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) write_u32(cache->type_version, owner_cls->tp_version_tag); write_obj(cache->descr, descr); // Fall through. -success: return 1; fail: return 0; From b8baebd75b9fdb351b2babd94789c97f665e3680 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Tue, 7 Jun 2022 20:48:07 +0800 Subject: [PATCH 07/14] fix up stats and comments --- Lib/opcode.py | 4 ++-- Python/specialize.c | 50 +++++++++++++++++++-------------------------- 2 files changed, 23 insertions(+), 31 deletions(-) diff --git a/Lib/opcode.py b/Lib/opcode.py index 78b36ce8684696..b78ac96e36e2d5 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -283,13 +283,13 @@ def jabs_op(name, op): ], "LOAD_ATTR": [ "LOAD_ATTR_ADAPTIVE", - # LOAD_ATTR + # These potentially push [NULL, bound method] onto the stack. "LOAD_ATTR_CLASS", "LOAD_ATTR_INSTANCE_VALUE", "LOAD_ATTR_MODULE", "LOAD_ATTR_SLOT", "LOAD_ATTR_WITH_HINT", - # LOAD_METHOD + # These will always push [unbound method, self] onto the stack. "LOAD_ATTR_METHOD_LAZY_DICT", "LOAD_ATTR_METHOD_NO_DICT", "LOAD_ATTR_METHOD_WITH_DICT", diff --git a/Python/specialize.c b/Python/specialize.c index 448bc8d5cde83d..3ff22ced614dc6 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -361,22 +361,14 @@ miss_counter_start(void) { /* Methods */ -#define SPEC_FAIL_LOAD_METHOD_OVERRIDING_DESCRIPTOR 8 -#define SPEC_FAIL_LOAD_METHOD_NON_OVERRIDING_DESCRIPTOR 9 -#define SPEC_FAIL_LOAD_METHOD_NOT_DESCRIPTOR 10 -#define SPEC_FAIL_LOAD_METHOD_METHOD 11 -#define SPEC_FAIL_LOAD_METHOD_MUTABLE_CLASS 12 -#define SPEC_FAIL_LOAD_METHOD_PROPERTY 13 -#define SPEC_FAIL_LOAD_METHOD_NON_OBJECT_SLOT 14 -#define SPEC_FAIL_LOAD_METHOD_IS_ATTR 15 -#define SPEC_FAIL_LOAD_METHOD_DICT_SUBCLASS 16 -#define SPEC_FAIL_LOAD_METHOD_BUILTIN_CLASS_METHOD 17 -#define SPEC_FAIL_LOAD_METHOD_CLASS_METHOD_OBJ 18 -#define SPEC_FAIL_LOAD_METHOD_OBJECT_SLOT 19 -#define SPEC_FAIL_LOAD_METHOD_HAS_DICT 20 -#define SPEC_FAIL_LOAD_METHOD_HAS_MANAGED_DICT 21 -#define SPEC_FAIL_LOAD_METHOD_INSTANCE_ATTRIBUTE 22 -#define SPEC_FAIL_LOAD_METHOD_METACLASS_ATTRIBUTE 23 +#define SPEC_FAIL_LOAD_METHOD_METHOD 20 +#define SPEC_FAIL_LOAD_METHOD_IS_ATTR 21 +#define SPEC_FAIL_LOAD_METHOD_BUILTIN_CLASS_METHOD 22 +#define SPEC_FAIL_LOAD_METHOD_CLASS_METHOD_OBJ 23 +#define SPEC_FAIL_LOAD_METHOD_OBJECT_SLOT 24 +#define SPEC_FAIL_LOAD_METHOD_HAS_MANAGED_DICT 25 +#define SPEC_FAIL_LOAD_METHOD_INSTANCE_ATTRIBUTE 26 +#define SPEC_FAIL_LOAD_METHOD_METACLASS_ATTRIBUTE 27 /* Binary subscr and store subscr */ @@ -691,7 +683,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) if (specialize_attr_loadmethod(owner, instr, name, descr, kind)) { goto success; } - /* res == 0 (fail), fall through and let LOAD_ATTR specialize for it */ + /* (fail), fall through and let LOAD_ATTR specialize for it */ } switch(kind) { case OVERRIDING: @@ -855,23 +847,23 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) #ifdef Py_STATS static int -load_method_fail_kind(DescriptorClassification kind) +load_attr_fail_kind(DescriptorClassification kind) { switch (kind) { case OVERRIDING: - return SPEC_FAIL_LOAD_METHOD_OVERRIDING_DESCRIPTOR; + return SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR; case METHOD: - return SPEC_FAIL_LOAD_METHOD_METHOD; + return SPEC_FAIL_ATTR_METHOD; case PROPERTY: - return SPEC_FAIL_LOAD_METHOD_PROPERTY; + return SPEC_FAIL_ATTR_PROPERTY; case OBJECT_SLOT: return SPEC_FAIL_LOAD_METHOD_OBJECT_SLOT; case OTHER_SLOT: - return SPEC_FAIL_LOAD_METHOD_NON_OBJECT_SLOT; + return SPEC_FAIL_ATTR_NON_OBJECT_SLOT; case DUNDER_CLASS: return SPEC_FAIL_OTHER; case MUTABLE: - return SPEC_FAIL_LOAD_METHOD_MUTABLE_CLASS; + return SPEC_FAIL_ATTR_MUTABLE_CLASS; case GETSET_OVERRIDDEN: return SPEC_FAIL_OVERRIDDEN; case BUILTIN_CLASSMETHOD: @@ -879,9 +871,9 @@ load_method_fail_kind(DescriptorClassification kind) case PYTHON_CLASSMETHOD: return SPEC_FAIL_LOAD_METHOD_CLASS_METHOD_OBJ; case NON_OVERRIDING: - return SPEC_FAIL_LOAD_METHOD_NON_OVERRIDING_DESCRIPTOR; + return SPEC_FAIL_ATTR_NON_OVERRIDING_DESCRIPTOR; case NON_DESCRIPTOR: - return SPEC_FAIL_LOAD_METHOD_NOT_DESCRIPTOR; + return SPEC_FAIL_ATTR_NOT_DESCRIPTOR; case ABSENT: return SPEC_FAIL_LOAD_METHOD_INSTANCE_ATTRIBUTE; } @@ -907,15 +899,15 @@ specialize_class_load_attr(PyObject *owner, _Py_CODEUNIT *instr, #ifdef Py_STATS case ABSENT: if (_PyType_Lookup(Py_TYPE(owner), name) != NULL) { - SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_LOAD_METHOD_METACLASS_ATTRIBUTE); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_LOAD_METHOD_METACLASS_ATTRIBUTE); } else { - SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_EXPECTED_ERROR); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_EXPECTED_ERROR); } return -1; #endif default: - SPECIALIZATION_FAIL(LOAD_METHOD, load_method_fail_kind(kind)); + SPECIALIZATION_FAIL(LOAD_ATTR, load_attr_fail_kind(kind)); return -1; } } @@ -977,7 +969,7 @@ PyObject *descr, DescriptorClassification kind) if (dictkind == MANAGED_VALUES || dictkind == OFFSET_DICT) { Py_ssize_t index = _PyDictKeys_StringLookup(keys, name); if (index != DKIX_EMPTY) { - SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_LOAD_METHOD_IS_ATTR); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_LOAD_METHOD_IS_ATTR); goto fail; } uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState(keys); From 56ea61a3739648d929f3a58c9f3ff659b1990702 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Tue, 7 Jun 2022 21:01:08 +0800 Subject: [PATCH 08/14] Shrink load method cache --- Include/internal/pycore_code.h | 12 +++--- Include/internal/pycore_opcode.h | 2 +- Lib/opcode.py | 1 - Lib/test/test_dis.py | 4 +- Programs/test_frozenmain.h | 69 ++++++++++++++++---------------- 5 files changed, 42 insertions(+), 46 deletions(-) diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index 398dfe54ed56be..805c82483eec76 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -58,21 +58,19 @@ typedef struct { _Py_CODEUNIT index; } _PyAttrCache; - -// MUST be the max(_PyAttrCache, _PyLoadMethodCache) -#define INLINE_CACHE_ENTRIES_LOAD_ATTR CACHE_ENTRIES(_PyLoadMethodCache) - -#define INLINE_CACHE_ENTRIES_STORE_ATTR CACHE_ENTRIES(_PyAttrCache) - typedef struct { _Py_CODEUNIT counter; _Py_CODEUNIT type_version[2]; - _Py_CODEUNIT UNUSED; _Py_CODEUNIT keys_version[2]; _Py_CODEUNIT descr[4]; } _PyLoadMethodCache; +// MUST be the max(_PyAttrCache, _PyLoadMethodCache) +#define INLINE_CACHE_ENTRIES_LOAD_ATTR CACHE_ENTRIES(_PyLoadMethodCache) + +#define INLINE_CACHE_ENTRIES_STORE_ATTR CACHE_ENTRIES(_PyAttrCache) + typedef struct { _Py_CODEUNIT counter; _Py_CODEUNIT func_version[2]; diff --git a/Include/internal/pycore_opcode.h b/Include/internal/pycore_opcode.h index 9d5de97b7994c2..62db22f1952550 100644 --- a/Include/internal/pycore_opcode.h +++ b/Include/internal/pycore_opcode.h @@ -45,7 +45,7 @@ const uint8_t _PyOpcode_Caches[256] = { [STORE_SUBSCR] = 1, [UNPACK_SEQUENCE] = 1, [STORE_ATTR] = 4, - [LOAD_ATTR] = 10, + [LOAD_ATTR] = 9, [COMPARE_OP] = 2, [LOAD_GLOBAL] = 5, [BINARY_OP] = 1, diff --git a/Lib/opcode.py b/Lib/opcode.py index b78ac96e36e2d5..90d88095e92359 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -369,7 +369,6 @@ def jabs_op(name, op): "LOAD_ATTR": { "counter": 1, "version": 2, - "index": 1, "keys_version": 2, "descr": 4, }, diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 410750d54e0030..dd222b42a59dc5 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -366,7 +366,7 @@ def bug42562(): %3d LOAD_GLOBAL 0 (Exception) CHECK_EXC_MATCH - POP_JUMP_FORWARD_IF_FALSE 24 (to 84) + POP_JUMP_FORWARD_IF_FALSE 23 (to 82) STORE_FAST 0 (e) %3d LOAD_FAST 0 (e) @@ -983,7 +983,7 @@ def test_load_attr_specialize(self): 1 2 LOAD_CONST 0 ('a') 4 LOAD_ATTR_SLOT 0 (__class__) - 26 RETURN_VALUE + 24 RETURN_VALUE """ co = compile("'a'.__class__", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index a0004582f227fd..5570ad01ce8f79 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -1,42 +1,41 @@ // Auto-generated by Programs/freeze_test_frozenmain.py unsigned char M_test_frozenmain[] = { 227,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0, - 0,0,0,0,0,243,184,0,0,0,151,0,100,0,100,1, + 0,0,0,0,0,243,180,0,0,0,151,0,100,0,100,1, 108,0,90,0,100,0,100,1,108,1,90,1,2,0,101,2, 100,2,171,1,0,0,0,0,0,0,0,0,1,0,2,0, 101,2,100,3,101,0,106,6,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,171,2,0,0, - 0,0,0,0,0,0,1,0,2,0,101,1,106,8,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,171,0,0,0,0,0,0,0,0,0,100,4,25,0, - 0,0,0,0,0,0,0,0,90,5,100,5,68,0,93,23, - 90,6,2,0,101,2,100,6,101,6,155,0,100,7,101,5, - 101,6,25,0,0,0,0,0,0,0,0,0,155,0,157,4, - 171,1,0,0,0,0,0,0,0,0,1,0,140,24,100,1, - 83,0,41,8,233,0,0,0,0,78,122,18,70,114,111,122, - 101,110,32,72,101,108,108,111,32,87,111,114,108,100,122,8, - 115,121,115,46,97,114,103,118,218,6,99,111,110,102,105,103, - 41,5,218,12,112,114,111,103,114,97,109,95,110,97,109,101, - 218,10,101,120,101,99,117,116,97,98,108,101,218,15,117,115, - 101,95,101,110,118,105,114,111,110,109,101,110,116,218,17,99, - 111,110,102,105,103,117,114,101,95,99,95,115,116,100,105,111, - 218,14,98,117,102,102,101,114,101,100,95,115,116,100,105,111, - 122,7,99,111,110,102,105,103,32,122,2,58,32,41,7,218, - 3,115,121,115,218,17,95,116,101,115,116,105,110,116,101,114, - 110,97,108,99,97,112,105,218,5,112,114,105,110,116,218,4, - 97,114,103,118,218,11,103,101,116,95,99,111,110,102,105,103, - 115,114,3,0,0,0,218,3,107,101,121,169,0,243,0,0, - 0,0,250,18,116,101,115,116,95,102,114,111,122,101,110,109, - 97,105,110,46,112,121,250,8,60,109,111,100,117,108,101,62, - 114,18,0,0,0,1,0,0,0,115,145,0,0,0,248,240, - 6,0,1,11,128,10,128,10,128,10,216,0,24,208,0,24, - 208,0,24,208,0,24,224,0,5,128,5,208,6,26,212,0, - 27,208,0,27,216,0,5,128,5,128,106,144,35,151,40,146, - 40,212,0,27,208,0,27,216,9,38,208,9,26,215,9,38, - 210,9,38,212,9,40,168,24,212,9,50,128,6,240,2,6, - 12,2,240,0,7,1,42,240,0,7,1,42,128,67,240,14, - 0,5,10,128,69,208,10,40,144,67,208,10,40,208,10,40, - 152,54,160,35,156,59,208,10,40,208,10,40,212,4,41,208, - 4,41,208,4,41,240,15,7,1,42,240,0,7,1,42,114, - 16,0,0,0, + 0,0,0,0,0,0,0,0,0,0,171,2,0,0,0,0, + 0,0,0,0,1,0,2,0,101,1,106,8,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,171,0, + 0,0,0,0,0,0,0,0,100,4,25,0,0,0,0,0, + 0,0,0,0,90,5,100,5,68,0,93,23,90,6,2,0, + 101,2,100,6,101,6,155,0,100,7,101,5,101,6,25,0, + 0,0,0,0,0,0,0,0,155,0,157,4,171,1,0,0, + 0,0,0,0,0,0,1,0,140,24,100,1,83,0,41,8, + 233,0,0,0,0,78,122,18,70,114,111,122,101,110,32,72, + 101,108,108,111,32,87,111,114,108,100,122,8,115,121,115,46, + 97,114,103,118,218,6,99,111,110,102,105,103,41,5,218,12, + 112,114,111,103,114,97,109,95,110,97,109,101,218,10,101,120, + 101,99,117,116,97,98,108,101,218,15,117,115,101,95,101,110, + 118,105,114,111,110,109,101,110,116,218,17,99,111,110,102,105, + 103,117,114,101,95,99,95,115,116,100,105,111,218,14,98,117, + 102,102,101,114,101,100,95,115,116,100,105,111,122,7,99,111, + 110,102,105,103,32,122,2,58,32,41,7,218,3,115,121,115, + 218,17,95,116,101,115,116,105,110,116,101,114,110,97,108,99, + 97,112,105,218,5,112,114,105,110,116,218,4,97,114,103,118, + 218,11,103,101,116,95,99,111,110,102,105,103,115,114,3,0, + 0,0,218,3,107,101,121,169,0,243,0,0,0,0,250,18, + 116,101,115,116,95,102,114,111,122,101,110,109,97,105,110,46, + 112,121,250,8,60,109,111,100,117,108,101,62,114,18,0,0, + 0,1,0,0,0,115,145,0,0,0,248,240,6,0,1,11, + 128,10,128,10,128,10,216,0,24,208,0,24,208,0,24,208, + 0,24,224,0,5,128,5,208,6,26,212,0,27,208,0,27, + 216,0,5,128,5,128,106,144,35,151,40,145,40,212,0,27, + 208,0,27,216,9,38,208,9,26,215,9,38,209,9,38,212, + 9,40,168,24,212,9,50,128,6,240,2,6,12,2,240,0, + 7,1,42,240,0,7,1,42,128,67,240,14,0,5,10,128, + 69,208,10,40,144,67,208,10,40,208,10,40,152,54,160,35, + 156,59,208,10,40,208,10,40,212,4,41,208,4,41,208,4, + 41,240,15,7,1,42,240,0,7,1,42,114,16,0,0,0, }; From 42340ee16bf55e635c8768419f84568e1be33d00 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Tue, 7 Jun 2022 21:03:20 +0800 Subject: [PATCH 09/14] fix formatting --- Python/specialize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/specialize.c b/Python/specialize.c index 3ff22ced614dc6..0b61cb5f7f1deb 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -676,7 +676,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) return -1; } } - PyObject* descr = NULL; + PyObject *descr = NULL; DescriptorClassification kind = analyze_descriptor(type, name, &descr, 0); assert(descr != NULL || kind == ABSENT || kind == GETSET_OVERRIDDEN); if ((oparg & 1) && kind == METHOD) { From b0e5b6b97a0e6abd921cd1b46eaaf7704abef0fb Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Tue, 7 Jun 2022 21:54:39 +0800 Subject: [PATCH 10/14] fail automatically when seeing a method --- Python/specialize.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Python/specialize.c b/Python/specialize.c index 0b61cb5f7f1deb..bce78bc6e0d647 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -679,19 +679,19 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) PyObject *descr = NULL; DescriptorClassification kind = analyze_descriptor(type, name, &descr, 0); assert(descr != NULL || kind == ABSENT || kind == GETSET_OVERRIDDEN); - if ((oparg & 1) && kind == METHOD) { - if (specialize_attr_loadmethod(owner, instr, name, descr, kind)) { - goto success; + if (kind == METHOD) { + if (oparg & 1) { + if (specialize_attr_loadmethod(owner, instr, name, descr, kind)) { + goto success; + } } - /* (fail), fall through and let LOAD_ATTR specialize for it */ + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD); + goto fail; } switch(kind) { case OVERRIDING: SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR); goto fail; - case METHOD: - SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD); - goto fail; case PROPERTY: SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_PROPERTY); goto fail; From 20b3352d3516305fefd92ba0b95f077e43d60600 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Tue, 7 Jun 2022 22:46:26 +0800 Subject: [PATCH 11/14] add back METHOD to the switch-case to avoid warnings --- Python/specialize.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Python/specialize.c b/Python/specialize.c index bce78bc6e0d647..c664d61ca80a65 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -679,19 +679,18 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) PyObject *descr = NULL; DescriptorClassification kind = analyze_descriptor(type, name, &descr, 0); assert(descr != NULL || kind == ABSENT || kind == GETSET_OVERRIDDEN); - if (kind == METHOD) { - if (oparg & 1) { - if (specialize_attr_loadmethod(owner, instr, name, descr, kind)) { - goto success; - } + if ((oparg & 1) && kind == METHOD) { + if (specialize_attr_loadmethod(owner, instr, name, descr, kind)) { + goto success; } - SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD); - goto fail; } switch(kind) { case OVERRIDING: SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR); goto fail; + case METHOD: + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD); + goto fail; case PROPERTY: SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_PROPERTY); goto fail; From 28ddf12c3544c5e2a028503ba11a8dec8b32f839 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Wed, 8 Jun 2022 14:57:11 +0800 Subject: [PATCH 12/14] fix a deopt --- Python/ceval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/ceval.c b/Python/ceval.c index a980844c118dce..1df8a953fb82d9 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3556,7 +3556,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(cache->index < dict->ma_keys->dk_nentries); PyDictUnicodeEntry* ep = DK_UNICODE_ENTRIES(dict->ma_keys) + cache->index; res = ep->me_value; - DEOPT_IF(res == NULL, LOAD_##attr_or_method); + DEOPT_IF(res == NULL, LOAD_ATTR); STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); SET_TOP(NULL); From 6fb980e7c90e89039d28254eb902540fd0d404a3 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Thu, 9 Jun 2022 21:24:41 +0800 Subject: [PATCH 13/14] PEP 7 nits --- Python/ceval.c | 18 +++++++++--------- Python/specialize.c | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index 1df8a953fb82d9..a0770bbdc98fad 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3451,8 +3451,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(LOAD_ATTR) { PREDICTED(LOAD_ATTR); - PyObject* name = GETITEM(names, oparg>>1); - PyObject* owner = TOP(); + PyObject *name = GETITEM(names, oparg >> 1); + PyObject *owner = TOP(); if (oparg & 1) { /* Designed to work in tandem with CALL. */ PyObject* meth = NULL; @@ -3546,15 +3546,15 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(cframe.use_tracing == 0); PyObject *owner = TOP(); PyObject *res; - _PyAttrCache* cache = (_PyAttrCache*)next_instr; + _PyAttrCache *cache = (_PyAttrCache *)next_instr; DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR); - PyDictObject* dict = (PyDictObject*)((PyModuleObject*)owner)->md_dict; + PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; assert(dict != NULL); DEOPT_IF(dict->ma_keys->dk_version != read_u32(cache->version), LOAD_ATTR); assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); assert(cache->index < dict->ma_keys->dk_nentries); - PyDictUnicodeEntry* ep = DK_UNICODE_ENTRIES(dict->ma_keys) + cache->index; + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + cache->index; res = ep->me_value; DEOPT_IF(res == NULL, LOAD_ATTR); STAT_INC(LOAD_ATTR, hit); @@ -3629,17 +3629,17 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(LOAD_ATTR_CLASS) { /* LOAD_METHOD, for class methods */ assert(cframe.use_tracing == 0); - _PyLoadMethodCache* cache = (_PyLoadMethodCache*)next_instr; + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; - PyObject* cls = TOP(); + PyObject *cls = TOP(); DEOPT_IF(!PyType_Check(cls), LOAD_ATTR); uint32_t type_version = read_u32(cache->type_version); - DEOPT_IF(((PyTypeObject*)cls)->tp_version_tag != type_version, + DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != type_version, LOAD_ATTR); assert(type_version != 0); STAT_INC(LOAD_ATTR, hit); - PyObject* res = read_obj(cache->descr); + PyObject *res = read_obj(cache->descr); assert(res != NULL); Py_INCREF(res); SET_TOP(NULL); diff --git a/Python/specialize.c b/Python/specialize.c index c664d61ca80a65..25589ab8aea373 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -670,7 +670,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) goto success; } int oparg = _Py_OPARG(*instr); - PyTypeObject* type = Py_TYPE(owner); + PyTypeObject *type = Py_TYPE(owner); if (type->tp_dict == NULL) { if (PyType_Ready(type) < 0) { return -1; From 5cc98f22132fb9edb5d492c20ca3998e3fd85ff0 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Mon, 13 Jun 2022 23:44:33 +0800 Subject: [PATCH 14/14] Apply mark's suggestions --- Python/specialize.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Python/specialize.c b/Python/specialize.c index 25589ab8aea373..1e1dbb41124448 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -669,7 +669,6 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) } goto success; } - int oparg = _Py_OPARG(*instr); PyTypeObject *type = Py_TYPE(owner); if (type->tp_dict == NULL) { if (PyType_Ready(type) < 0) { @@ -679,18 +678,21 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) PyObject *descr = NULL; DescriptorClassification kind = analyze_descriptor(type, name, &descr, 0); assert(descr != NULL || kind == ABSENT || kind == GETSET_OVERRIDDEN); - if ((oparg & 1) && kind == METHOD) { - if (specialize_attr_loadmethod(owner, instr, name, descr, kind)) { - goto success; - } - } switch(kind) { case OVERRIDING: SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR); goto fail; case METHOD: + { + int oparg = _Py_OPARG(*instr); + if (oparg & 1) { + if (specialize_attr_loadmethod(owner, instr, name, descr, kind)) { + goto success; + } + } SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD); goto fail; + } case PROPERTY: SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_PROPERTY); goto fail; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy