From 0f2129fd4a2c949ac8d658bb240607a9cdc7e356 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Wed, 1 Feb 2023 11:20:45 -0800 Subject: [PATCH 1/3] Modernize LOAD_GLOBAL --- Python/bytecodes.c | 28 +++++++++++----------------- Python/generated_cases.c.h | 23 +++++++++++------------ Python/opcode_metadata.h | 8 ++++---- 3 files changed, 26 insertions(+), 33 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index bb1deaf3fbeb4b..4683d9a83bc9d4 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1068,8 +1068,13 @@ dummy_func( } } - // error: LOAD_GLOBAL has irregular stack effect - inst(LOAD_GLOBAL) { + // family(load_global, INLINE_CACHE_ENTRIES_LOAD_GLOBAL) = { + // LOAD_GLOBAL, + // LOAD_GLOBAL_BUILTIN, + // LOAD_GLOBAL_MODULE, + // }; + + inst(LOAD_GLOBAL, (unused/1, unused/1, unused/2, unused/1 -- null if (oparg & 1), v)) { #if ENABLE_SPECIALIZATION _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1082,10 +1087,7 @@ dummy_func( STAT_INC(LOAD_GLOBAL, deferred); DECREMENT_ADAPTIVE_COUNTER(cache->counter); #endif /* ENABLE_SPECIALIZATION */ - int push_null = oparg & 1; - PEEK(0) = NULL; PyObject *name = GETITEM(names, oparg>>1); - PyObject *v; if (PyDict_CheckExact(GLOBALS()) && PyDict_CheckExact(BUILTINS())) { @@ -1099,7 +1101,7 @@ dummy_func( format_exc_check_arg(tstate, PyExc_NameError, NAME_ERROR_MSG, name); } - goto error; + ERROR_IF(true, error); } Py_INCREF(v); } @@ -1109,9 +1111,7 @@ dummy_func( /* namespace 1: globals */ v = PyObject_GetItem(GLOBALS(), name); if (v == NULL) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - goto error; - } + ERROR_IF(!_PyErr_ExceptionMatches(tstate, PyExc_KeyError), error); _PyErr_Clear(tstate); /* namespace 2: builtins */ @@ -1122,14 +1122,11 @@ dummy_func( tstate, PyExc_NameError, NAME_ERROR_MSG, name); } - goto error; + ERROR_IF(true, error); } } } - /* Skip over inline cache */ - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); - STACK_GROW(push_null); - PUSH(v); + null = NULL; } // error: LOAD_GLOBAL has irregular stack effect @@ -3227,9 +3224,6 @@ family(call, INLINE_CACHE_ENTRIES_CALL) = { family(for_iter, INLINE_CACHE_ENTRIES_FOR_ITER) = { FOR_ITER, FOR_ITER_LIST, FOR_ITER_RANGE }; -family(load_global, INLINE_CACHE_ENTRIES_LOAD_GLOBAL) = { - LOAD_GLOBAL, LOAD_GLOBAL_BUILTIN, - LOAD_GLOBAL_MODULE }; family(store_fast) = { STORE_FAST, STORE_FAST__LOAD_FAST, STORE_FAST__STORE_FAST }; family(unpack_sequence, INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE) = { UNPACK_SEQUENCE, UNPACK_SEQUENCE_LIST, diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index e5c5c7e557a37c..fe60c99c28d906 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -1311,6 +1311,8 @@ TARGET(LOAD_GLOBAL) { PREDICTED(LOAD_GLOBAL); + PyObject *null = NULL; + PyObject *v; #if ENABLE_SPECIALIZATION _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1323,10 +1325,7 @@ STAT_INC(LOAD_GLOBAL, deferred); DECREMENT_ADAPTIVE_COUNTER(cache->counter); #endif /* ENABLE_SPECIALIZATION */ - int push_null = oparg & 1; - PEEK(0) = NULL; PyObject *name = GETITEM(names, oparg>>1); - PyObject *v; if (PyDict_CheckExact(GLOBALS()) && PyDict_CheckExact(BUILTINS())) { @@ -1340,7 +1339,7 @@ format_exc_check_arg(tstate, PyExc_NameError, NAME_ERROR_MSG, name); } - goto error; + if (true) goto error; } Py_INCREF(v); } @@ -1350,9 +1349,7 @@ /* namespace 1: globals */ v = PyObject_GetItem(GLOBALS(), name); if (v == NULL) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - goto error; - } + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) goto error; _PyErr_Clear(tstate); /* namespace 2: builtins */ @@ -1363,14 +1360,16 @@ tstate, PyExc_NameError, NAME_ERROR_MSG, name); } - goto error; + if (true) goto error; } } } - /* Skip over inline cache */ - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); - STACK_GROW(push_null); - PUSH(v); + null = NULL; + STACK_GROW(1); + STACK_GROW(((oparg & 1) ? 1 : 0)); + POKE(1, v); + if (oparg & 1) { POKE(1 + ((oparg & 1) ? 1 : 0), null); } + JUMPBY(5); DISPATCH(); } diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h index 96e57be8cf5dea..f58588db6d87a0 100644 --- a/Python/opcode_metadata.h +++ b/Python/opcode_metadata.h @@ -141,7 +141,7 @@ _PyOpcode_num_popped(int opcode, int oparg) { case LOAD_NAME: return 0; case LOAD_GLOBAL: - return -1; + return 0; case LOAD_GLOBAL_MODULE: return -1; case LOAD_GLOBAL_BUILTIN: @@ -487,7 +487,7 @@ _PyOpcode_num_pushed(int opcode, int oparg) { case LOAD_NAME: return 1; case LOAD_GLOBAL: - return -1; + return ((oparg & 1) ? 1 : 0) + 1; case LOAD_GLOBAL_MODULE: return -1; case LOAD_GLOBAL_BUILTIN: @@ -694,7 +694,7 @@ _PyOpcode_num_pushed(int opcode, int oparg) { } #endif enum Direction { DIR_NONE, DIR_READ, DIR_WRITE }; -enum InstructionFormat { INSTR_FMT_IB, INSTR_FMT_IBC, INSTR_FMT_IBC0, INSTR_FMT_IBC000, INSTR_FMT_IBC00000000, INSTR_FMT_IBIB, INSTR_FMT_IX, INSTR_FMT_IXC, INSTR_FMT_IXC000 }; +enum InstructionFormat { INSTR_FMT_IB, INSTR_FMT_IBC, INSTR_FMT_IBC0, INSTR_FMT_IBC000, INSTR_FMT_IBC0000, INSTR_FMT_IBC00000000, INSTR_FMT_IBIB, INSTR_FMT_IX, INSTR_FMT_IXC, INSTR_FMT_IXC000 }; struct opcode_metadata { enum Direction dir_op1; enum Direction dir_op2; @@ -769,7 +769,7 @@ struct opcode_metadata { [STORE_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, [DELETE_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, [LOAD_NAME] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, - [LOAD_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC0000 }, [LOAD_GLOBAL_MODULE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, [LOAD_GLOBAL_BUILTIN] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, [DELETE_FAST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, From 995822a3fff0b47fae03f1c3a176a47902933519 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Wed, 1 Feb 2023 11:25:18 -0800 Subject: [PATCH 2/3] Modernize LOAD_GLOBAL_MODULE --- Python/bytecodes.c | 22 ++++++++-------------- Python/generated_cases.c.h | 21 +++++++++++++-------- Python/opcode_metadata.h | 6 +++--- 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 4683d9a83bc9d4..4ce212d25ebd83 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1068,11 +1068,11 @@ dummy_func( } } - // family(load_global, INLINE_CACHE_ENTRIES_LOAD_GLOBAL) = { - // LOAD_GLOBAL, + family(load_global, INLINE_CACHE_ENTRIES_LOAD_GLOBAL) = { + LOAD_GLOBAL, + LOAD_GLOBAL_MODULE, // LOAD_GLOBAL_BUILTIN, - // LOAD_GLOBAL_MODULE, - // }; + }; inst(LOAD_GLOBAL, (unused/1, unused/1, unused/2, unused/1 -- null if (oparg & 1), v)) { #if ENABLE_SPECIALIZATION @@ -1129,24 +1129,18 @@ dummy_func( null = NULL; } - // error: LOAD_GLOBAL has irregular stack effect - inst(LOAD_GLOBAL_MODULE) { + inst(LOAD_GLOBAL_MODULE, (unused/1, index/1, version/2, unused/1 -- null if (oparg & 1), res)) { assert(cframe.use_tracing == 0); DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); PyDictObject *dict = (PyDictObject *)GLOBALS(); - _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; - uint32_t version = read_u32(cache->module_keys_version); DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); assert(DK_IS_UNICODE(dict->ma_keys)); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); - PyObject *res = entries[cache->index].me_value; + res = entries[index].me_value; DEOPT_IF(res == NULL, LOAD_GLOBAL); - int push_null = oparg & 1; - PEEK(0) = NULL; - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); + Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); - STACK_GROW(push_null+1); - SET_TOP(Py_NewRef(res)); + null = NULL; } // error: LOAD_GLOBAL has irregular stack effect diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index fe60c99c28d906..a656b51717e36d 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -1311,6 +1311,7 @@ TARGET(LOAD_GLOBAL) { PREDICTED(LOAD_GLOBAL); + static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 5, "incorrect cache size"); PyObject *null = NULL; PyObject *v; #if ENABLE_SPECIALIZATION @@ -1374,22 +1375,26 @@ } TARGET(LOAD_GLOBAL_MODULE) { + PyObject *null = NULL; + PyObject *res; + uint16_t index = read_u16(&next_instr[1].cache); + uint32_t version = read_u32(&next_instr[2].cache); assert(cframe.use_tracing == 0); DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); PyDictObject *dict = (PyDictObject *)GLOBALS(); - _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; - uint32_t version = read_u32(cache->module_keys_version); DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); assert(DK_IS_UNICODE(dict->ma_keys)); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); - PyObject *res = entries[cache->index].me_value; + res = entries[index].me_value; DEOPT_IF(res == NULL, LOAD_GLOBAL); - int push_null = oparg & 1; - PEEK(0) = NULL; - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); + Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); - STACK_GROW(push_null+1); - SET_TOP(Py_NewRef(res)); + null = NULL; + STACK_GROW(1); + STACK_GROW(((oparg & 1) ? 1 : 0)); + POKE(1, res); + if (oparg & 1) { POKE(1 + ((oparg & 1) ? 1 : 0), null); } + JUMPBY(5); DISPATCH(); } diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h index f58588db6d87a0..74330752686277 100644 --- a/Python/opcode_metadata.h +++ b/Python/opcode_metadata.h @@ -143,7 +143,7 @@ _PyOpcode_num_popped(int opcode, int oparg) { case LOAD_GLOBAL: return 0; case LOAD_GLOBAL_MODULE: - return -1; + return 0; case LOAD_GLOBAL_BUILTIN: return -1; case DELETE_FAST: @@ -489,7 +489,7 @@ _PyOpcode_num_pushed(int opcode, int oparg) { case LOAD_GLOBAL: return ((oparg & 1) ? 1 : 0) + 1; case LOAD_GLOBAL_MODULE: - return -1; + return ((oparg & 1) ? 1 : 0) + 1; case LOAD_GLOBAL_BUILTIN: return -1; case DELETE_FAST: @@ -770,7 +770,7 @@ struct opcode_metadata { [DELETE_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, [LOAD_NAME] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, [LOAD_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC0000 }, - [LOAD_GLOBAL_MODULE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_GLOBAL_MODULE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC0000 }, [LOAD_GLOBAL_BUILTIN] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, [DELETE_FAST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, [MAKE_CELL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, From 68687673476d3eb95284d72e0b92e2c3107fe5f3 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Wed, 1 Feb 2023 11:28:50 -0800 Subject: [PATCH 3/3] Modernize LOAD_GLOBAL_BUILTIN --- Python/bytecodes.c | 17 +++++------------ Python/generated_cases.c.h | 22 +++++++++++++--------- Python/opcode_metadata.h | 6 +++--- 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 4ce212d25ebd83..8f7144a12a4daf 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1071,7 +1071,7 @@ dummy_func( family(load_global, INLINE_CACHE_ENTRIES_LOAD_GLOBAL) = { LOAD_GLOBAL, LOAD_GLOBAL_MODULE, - // LOAD_GLOBAL_BUILTIN, + LOAD_GLOBAL_BUILTIN, }; inst(LOAD_GLOBAL, (unused/1, unused/1, unused/2, unused/1 -- null if (oparg & 1), v)) { @@ -1143,28 +1143,21 @@ dummy_func( null = NULL; } - // error: LOAD_GLOBAL has irregular stack effect - inst(LOAD_GLOBAL_BUILTIN) { + inst(LOAD_GLOBAL_BUILTIN, (unused/1, index/1, mod_version/2, bltn_version/1 -- null if (oparg & 1), res)) { assert(cframe.use_tracing == 0); DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL); PyDictObject *mdict = (PyDictObject *)GLOBALS(); PyDictObject *bdict = (PyDictObject *)BUILTINS(); - _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; - uint32_t mod_version = read_u32(cache->module_keys_version); - uint16_t bltn_version = cache->builtin_keys_version; DEOPT_IF(mdict->ma_keys->dk_version != mod_version, LOAD_GLOBAL); DEOPT_IF(bdict->ma_keys->dk_version != bltn_version, LOAD_GLOBAL); assert(DK_IS_UNICODE(bdict->ma_keys)); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys); - PyObject *res = entries[cache->index].me_value; + res = entries[index].me_value; DEOPT_IF(res == NULL, LOAD_GLOBAL); - int push_null = oparg & 1; - PEEK(0) = NULL; - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); + Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); - STACK_GROW(push_null+1); - SET_TOP(Py_NewRef(res)); + null = NULL; } inst(DELETE_FAST, (--)) { diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index a656b51717e36d..ac144f3b872406 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -1399,26 +1399,30 @@ } TARGET(LOAD_GLOBAL_BUILTIN) { + PyObject *null = NULL; + PyObject *res; + uint16_t index = read_u16(&next_instr[1].cache); + uint32_t mod_version = read_u32(&next_instr[2].cache); + uint16_t bltn_version = read_u16(&next_instr[4].cache); assert(cframe.use_tracing == 0); DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL); PyDictObject *mdict = (PyDictObject *)GLOBALS(); PyDictObject *bdict = (PyDictObject *)BUILTINS(); - _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; - uint32_t mod_version = read_u32(cache->module_keys_version); - uint16_t bltn_version = cache->builtin_keys_version; DEOPT_IF(mdict->ma_keys->dk_version != mod_version, LOAD_GLOBAL); DEOPT_IF(bdict->ma_keys->dk_version != bltn_version, LOAD_GLOBAL); assert(DK_IS_UNICODE(bdict->ma_keys)); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys); - PyObject *res = entries[cache->index].me_value; + res = entries[index].me_value; DEOPT_IF(res == NULL, LOAD_GLOBAL); - int push_null = oparg & 1; - PEEK(0) = NULL; - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); + Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); - STACK_GROW(push_null+1); - SET_TOP(Py_NewRef(res)); + null = NULL; + STACK_GROW(1); + STACK_GROW(((oparg & 1) ? 1 : 0)); + POKE(1, res); + if (oparg & 1) { POKE(1 + ((oparg & 1) ? 1 : 0), null); } + JUMPBY(5); DISPATCH(); } diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h index 74330752686277..f7012af98b3d0e 100644 --- a/Python/opcode_metadata.h +++ b/Python/opcode_metadata.h @@ -145,7 +145,7 @@ _PyOpcode_num_popped(int opcode, int oparg) { case LOAD_GLOBAL_MODULE: return 0; case LOAD_GLOBAL_BUILTIN: - return -1; + return 0; case DELETE_FAST: return 0; case MAKE_CELL: @@ -491,7 +491,7 @@ _PyOpcode_num_pushed(int opcode, int oparg) { case LOAD_GLOBAL_MODULE: return ((oparg & 1) ? 1 : 0) + 1; case LOAD_GLOBAL_BUILTIN: - return -1; + return ((oparg & 1) ? 1 : 0) + 1; case DELETE_FAST: return 0; case MAKE_CELL: @@ -771,7 +771,7 @@ struct opcode_metadata { [LOAD_NAME] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, [LOAD_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC0000 }, [LOAD_GLOBAL_MODULE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC0000 }, - [LOAD_GLOBAL_BUILTIN] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_GLOBAL_BUILTIN] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC0000 }, [DELETE_FAST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, [MAKE_CELL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, [DELETE_DEREF] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB },