From a20963469638b76f451899bef634fa2e8161fef2 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 18 Feb 2022 13:00:58 +0000 Subject: [PATCH 01/11] Experiment: Make 'inline' cache for LOAD_GLOBAL actually inline. --- Include/internal/pycore_code.h | 36 +++++++++++++---- Include/opcode.h | 1 + Lib/importlib/_bootstrap_external.py | 4 +- Lib/opcode.py | 2 + Python/ceval.c | 58 +++++++++++++++++++--------- Python/compile.c | 13 ++++++- Python/opcode_targets.h | 2 +- Python/specialize.c | 33 +++++++++------- 8 files changed, 107 insertions(+), 42 deletions(-) diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index ead9541c298438..a223de0d2f26a4 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -26,11 +26,6 @@ typedef struct { uint32_t dk_version_or_hint; } _PyAttrCache; -typedef struct { - uint32_t module_keys_version; - uint32_t builtin_keys_version; -} _PyLoadGlobalCache; - typedef struct { /* Borrowed ref in LOAD_METHOD */ PyObject *obj; @@ -57,13 +52,26 @@ typedef union { _PyEntryZero zero; _PyAdaptiveEntry adaptive; _PyAttrCache attr; - _PyLoadGlobalCache load_global; _PyObjectCache obj; _PyCallCache call; } SpecializedCacheEntry; #define INSTRUCTIONS_PER_ENTRY (sizeof(SpecializedCacheEntry)/sizeof(_Py_CODEUNIT)) +/* Inline caches */ + +typedef struct { + _Py_CODEUNIT counter; + _Py_CODEUNIT index; + _Py_CODEUNIT module_keys_version; + _Py_CODEUNIT _m1; + _Py_CODEUNIT builtin_keys_version; + _Py_CODEUNIT _b1; +} _PyLoadGlobalCache; + +#define LOAD_GLOBAL_INLINE_CACHE_SIZE (sizeof(_PyLoadGlobalCache)/sizeof(_Py_CODEUNIT)) + + /* Maximum size of code to quicken, in code units. */ #define MAX_SIZE_TO_QUICKEN 5000 @@ -267,7 +275,7 @@ cache_backoff(_PyAdaptiveEntry *entry) { int _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache); int _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache); -int _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache); +int _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins, _Py_CODEUNIT *instr, PyObject *name); int _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache); int _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container, _Py_CODEUNIT *instr, SpecializedCacheEntry *cache); int _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *instr); @@ -346,6 +354,20 @@ PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void); #define OBJECT_STAT_INC(name) ((void)0) #endif +/* TO DO -- Move these somewhere sensible and use native endianness */ +static inline void +write32(uint16_t *p, uint32_t val) +{ + p[0] = (uint16_t)val; + p[1] = val >> 16; +} + +static inline uint32_t +read32(uint16_t *p) +{ + return p[0] | (p[1] << 16); +} + #ifdef __cplusplus } diff --git a/Include/opcode.h b/Include/opcode.h index df45e7b5e5a30c..1bd4de2ff071b2 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -113,6 +113,7 @@ extern "C" { #define PRECALL_METHOD 168 #define CALL 171 #define KW_NAMES 172 +#define CACHE_ENTRY 240 #define BINARY_OP_ADAPTIVE 2 #define BINARY_OP_ADD_INT 3 #define BINARY_OP_ADD_FLOAT 4 diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 7b9803d27fa618..b944e5a9294c3b 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -386,6 +386,8 @@ def _write_atomic(path, data, mode=0o666): # ROT_TWO/ROT_THREE/ROT_FOUR/ROT_N with SWAP) # Python 3.11a5 3478 (New CALL opcodes) +# Python 3.11a5 3485 Inline caches. + # Python 3.12 will start with magic number 3500 @@ -402,7 +404,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 = (3478).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3485).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _PYCACHE = '__pycache__' diff --git a/Lib/opcode.py b/Lib/opcode.py index 8237aa7fa3d116..920a32fe4d7468 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -195,6 +195,8 @@ def jabs_op(name, op): def_op('KW_NAMES', 172) hasconst.append(172) +def_op('CACHE_ENTRY', 240) + del def_op, name_op, jrel_op, jabs_op _nb_ops = [ diff --git a/Python/ceval.c b/Python/ceval.c index b900de53c8c928..28d5cf230cf134 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1733,6 +1733,11 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr DISPATCH(); } + TARGET(CACHE_ENTRY) { + _PyErr_SetString(tstate, PyExc_SystemError, "Attempting to execute a cache entry"); + goto error; + } + TARGET(RESUME) { int err = _Py_IncrementCountAndMaybeQuicken(frame->f_code); if (err) { @@ -2980,25 +2985,26 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr } } } + /* Skip over inline cache */ + next_instr += LOAD_GLOBAL_INLINE_CACHE_SIZE; PUSH(v); DISPATCH(); } TARGET(LOAD_GLOBAL_ADAPTIVE) { assert(cframe.use_tracing == 0); - SpecializedCacheEntry *cache = GET_CACHE(); - if (cache->adaptive.counter == 0) { - PyObject *name = GETITEM(names, cache->adaptive.original_oparg); + uint16_t counter = *next_instr; + if (counter == 0) { + PyObject *name = GETITEM(names, oparg); next_instr--; - if (_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name, cache) < 0) { + if (_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name) < 0) { goto error; } DISPATCH(); } else { STAT_INC(LOAD_GLOBAL, deferred); - cache->adaptive.counter--; - oparg = cache->adaptive.original_oparg; + *next_instr = counter-1; JUMP_TO_INSTRUCTION(LOAD_GLOBAL); } } @@ -3007,13 +3013,13 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr assert(cframe.use_tracing == 0); DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); PyDictObject *dict = (PyDictObject *)GLOBALS(); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - _PyLoadGlobalCache *cache1 = &caches[-1].load_global; - DEOPT_IF(dict->ma_keys->dk_version != cache1->module_keys_version, LOAD_GLOBAL); - PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + cache0->index; + _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; + uint32_t version = read32(&cache->module_keys_version); + DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); + PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + cache->index; PyObject *res = ep->me_value; DEOPT_IF(res == NULL, LOAD_GLOBAL); + next_instr += LOAD_GLOBAL_INLINE_CACHE_SIZE; STAT_INC(LOAD_GLOBAL, hit); Py_INCREF(res); PUSH(res); @@ -3026,14 +3032,15 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL); PyDictObject *mdict = (PyDictObject *)GLOBALS(); PyDictObject *bdict = (PyDictObject *)BUILTINS(); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - _PyLoadGlobalCache *cache1 = &caches[-1].load_global; - DEOPT_IF(mdict->ma_keys->dk_version != cache1->module_keys_version, LOAD_GLOBAL); - DEOPT_IF(bdict->ma_keys->dk_version != cache1->builtin_keys_version, LOAD_GLOBAL); - PyDictKeyEntry *ep = DK_ENTRIES(bdict->ma_keys) + cache0->index; + _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; + uint32_t mod_version = read32(&cache->module_keys_version); + uint32_t bltn_version = read32(&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); + PyDictKeyEntry *ep = DK_ENTRIES(bdict->ma_keys) + cache->index; PyObject *res = ep->me_value; DEOPT_IF(res == NULL, LOAD_GLOBAL); + next_instr += LOAD_GLOBAL_INLINE_CACHE_SIZE; STAT_INC(LOAD_GLOBAL, hit); Py_INCREF(res); PUSH(res); @@ -5389,6 +5396,21 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr /* Specialization misses */ +#define MISS_INLINE_CACHE(opname) \ +opname ## _miss: \ + { \ + STAT_INC(opcode, miss); \ + STAT_INC(opname, miss); \ + uint16_t *counter = next_instr; \ + *counter = *counter-1; \ + if (*counter == 0) { \ + next_instr[-1] = _Py_MAKECODEUNIT(opname ## _ADAPTIVE, _Py_OPARG(next_instr[-1])); \ + STAT_INC(opname, deopt); \ + *counter = ADAPTIVE_CACHE_BACKOFF; \ + } \ + JUMP_TO_INSTRUCTION(opname); \ + } + #define MISS_WITH_CACHE(opname) \ opname ## _miss: \ { \ @@ -5422,7 +5444,7 @@ opname ## _miss: \ MISS_WITH_CACHE(LOAD_ATTR) MISS_WITH_CACHE(STORE_ATTR) -MISS_WITH_CACHE(LOAD_GLOBAL) +MISS_INLINE_CACHE(LOAD_GLOBAL) MISS_WITH_CACHE(LOAD_METHOD) MISS_WITH_CACHE(CALL) MISS_WITH_CACHE(BINARY_OP) diff --git a/Python/compile.c b/Python/compile.c index 786ef4e8ad3e28..a81894bb4d9369 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -854,6 +854,7 @@ stack_effect(int opcode, int oparg, int jump) case NOP: case EXTENDED_ARG: case RESUME: + case CACHE_ENTRY: return 0; /* Stack manipulation */ @@ -4112,6 +4113,7 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) /* XXX Leave assert here, but handle __doc__ and the like better */ assert(scope || PyUnicode_READ_CHAR(name, 0) == '_'); + int cache_size = 0; switch (optype) { case OP_DEREF: switch (ctx) { @@ -4132,7 +4134,10 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) return 1; case OP_GLOBAL: switch (ctx) { - case Load: op = LOAD_GLOBAL; break; + case Load: + op = LOAD_GLOBAL; + cache_size = LOAD_GLOBAL_INLINE_CACHE_SIZE; + break; case Store: op = STORE_GLOBAL; break; case Del: op = DELETE_GLOBAL; break; } @@ -4151,7 +4156,11 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) Py_DECREF(mangled); if (arg < 0) return 0; - return compiler_addop_i(c, op, arg); + RETURN_IF_FALSE(compiler_addop_i(c, op, arg)); + for (int i = 0; i < cache_size; i++) { + compiler_addop_i_noline(c, CACHE_ENTRY, i); + } + return 1; } static int diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 1e137f93c72922..b0c0587752a884 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -239,7 +239,7 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&_unknown_opcode, + &&TARGET_CACHE_ENTRY, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, diff --git a/Python/specialize.c b/Python/specialize.c index 5fd7d0923a6983..3c350c098a2028 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -43,7 +43,6 @@ Values of zero are ignored. */ static uint8_t adaptive_opcodes[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, @@ -54,10 +53,13 @@ static uint8_t adaptive_opcodes[256] = { [UNPACK_SEQUENCE] = UNPACK_SEQUENCE_ADAPTIVE, }; +static uint8_t inline_opcodes[256] = { + [LOAD_GLOBAL] = LOAD_GLOBAL_ADAPTIVE, +}; + /* The number of cache entries required for a "family" of instructions. */ static uint8_t cache_requirements[256] = { [LOAD_ATTR] = 2, /* _PyAdaptiveEntry and _PyAttrCache */ - [LOAD_GLOBAL] = 2, /* _PyAdaptiveEntry and _PyLoadGlobalCache */ [LOAD_METHOD] = 3, /* _PyAdaptiveEntry, _PyAttrCache and _PyObjectCache */ [BINARY_SUBSCR] = 2, /* _PyAdaptiveEntry, _PyObjectCache */ [STORE_SUBSCR] = 0, @@ -409,6 +411,12 @@ optimize(SpecializedCacheOrInstruction *quickened, int len) } instructions[i] = _Py_MAKECODEUNIT(adaptive_opcode, new_oparg); } + else if (inline_opcodes[opcode] && previous_opcode != EXTENDED_ARG) { + instructions[i] = _Py_MAKECODEUNIT(inline_opcodes[opcode], oparg); + instructions[i+1] = 0; /* counter */ + i++; + previous_opcode = opcode; + } else { /* Super instructions don't use the cache, * so no need to update the offset. */ @@ -1156,11 +1164,10 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, int _Py_Specialize_LoadGlobal( PyObject *globals, PyObject *builtins, - _Py_CODEUNIT *instr, PyObject *name, - SpecializedCacheEntry *cache) + _Py_CODEUNIT *instr, PyObject *name) { - _PyAdaptiveEntry *cache0 = &cache->adaptive; - _PyLoadGlobalCache *cache1 = &cache[-1].load_global; + /* Use inline cache */ + _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)(instr+1); assert(PyUnicode_CheckExact(name)); if (!PyDict_CheckExact(globals)) { goto fail; @@ -1179,8 +1186,8 @@ _Py_Specialize_LoadGlobal( if (keys_version == 0) { goto fail; } - cache1->module_keys_version = keys_version; - cache0->index = (uint16_t)index; + cache->index = (uint16_t)index; + write32(&cache->module_keys_version, keys_version); *instr = _Py_MAKECODEUNIT(LOAD_GLOBAL_MODULE, _Py_OPARG(*instr)); goto success; } @@ -1206,20 +1213,20 @@ _Py_Specialize_LoadGlobal( SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_VERSIONS); goto fail; } - cache1->module_keys_version = globals_version; - cache1->builtin_keys_version = builtins_version; - cache0->index = (uint16_t)index; + cache->index = (uint16_t)index; + write32(&cache->module_keys_version, globals_version); + write32(&cache->builtin_keys_version, builtins_version); *instr = _Py_MAKECODEUNIT(LOAD_GLOBAL_BUILTIN, _Py_OPARG(*instr)); goto success; fail: STAT_INC(LOAD_GLOBAL, failure); assert(!PyErr_Occurred()); - cache_backoff(cache0); + cache->counter = ADAPTIVE_CACHE_BACKOFF; return 0; success: STAT_INC(LOAD_GLOBAL, success); assert(!PyErr_Occurred()); - cache0->counter = initial_counter_value(); + cache->counter = initial_counter_value(); return 0; } From 8ceabb5cab9c640b851df0bb660fd20f0573987f Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 23 Feb 2022 19:07:15 +0000 Subject: [PATCH 02/11] Emit cache entry space in assembler. --- Include/internal/pycore_code.h | 1 - Python/ceval.c | 2 +- Python/compile.c | 32 +++++++++++++++++--------------- Python/specialize.c | 12 ++++++++++-- Python/wordcode_helpers.h | 2 ++ 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index a223de0d2f26a4..6a5ff0f1023fdc 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -66,7 +66,6 @@ typedef struct { _Py_CODEUNIT module_keys_version; _Py_CODEUNIT _m1; _Py_CODEUNIT builtin_keys_version; - _Py_CODEUNIT _b1; } _PyLoadGlobalCache; #define LOAD_GLOBAL_INLINE_CACHE_SIZE (sizeof(_PyLoadGlobalCache)/sizeof(_Py_CODEUNIT)) diff --git a/Python/ceval.c b/Python/ceval.c index 28d5cf230cf134..2156e653e3aabb 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3034,7 +3034,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr PyDictObject *bdict = (PyDictObject *)BUILTINS(); _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; uint32_t mod_version = read32(&cache->module_keys_version); - uint32_t bltn_version = read32(&cache->builtin_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); PyDictKeyEntry *ep = DK_ENTRIES(bdict->ma_keys) + cache->index; diff --git a/Python/compile.c b/Python/compile.c index a81894bb4d9369..ceab4a07e79751 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -4113,7 +4113,6 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) /* XXX Leave assert here, but handle __doc__ and the like better */ assert(scope || PyUnicode_READ_CHAR(name, 0) == '_'); - int cache_size = 0; switch (optype) { case OP_DEREF: switch (ctx) { @@ -4134,10 +4133,7 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) return 1; case OP_GLOBAL: switch (ctx) { - case Load: - op = LOAD_GLOBAL; - cache_size = LOAD_GLOBAL_INLINE_CACHE_SIZE; - break; + case Load: op = LOAD_GLOBAL; break; case Store: op = STORE_GLOBAL; break; case Del: op = DELETE_GLOBAL; break; } @@ -4157,9 +4153,6 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) if (arg < 0) return 0; RETURN_IF_FALSE(compiler_addop_i(c, op, arg)); - for (int i = 0; i < cache_size; i++) { - compiler_addop_i_noline(c, CACHE_ENTRY, i); - } return 1; } @@ -7105,8 +7098,10 @@ blocksize(basicblock *b) int i; int size = 0; - for (i = 0; i < b->b_iused; i++) + for (i = 0; i < b->b_iused; i++) { size += instrsize(b->b_instr[i].i_oparg); + size += _Py_InlineCacheSize[b->b_instr[i].i_opcode]; + } return size; } @@ -7371,6 +7366,7 @@ assemble_exception_table(struct assembler *a) handler = instr->i_except; } ioffset += instrsize(instr->i_oparg); + ioffset += _Py_InlineCacheSize[instr->i_opcode]; } } if (handler != NULL) { @@ -7499,30 +7495,35 @@ assemble_cnotab(struct assembler* a, struct instr* i, int instr_size) static int assemble_emit(struct assembler *a, struct instr *i) { - int size, arg = 0; + int isize, tsize, arg = 0; Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode); _Py_CODEUNIT *code; arg = i->i_oparg; - size = instrsize(arg); + isize = instrsize(arg); + tsize = isize + _Py_InlineCacheSize[i->i_opcode]; if (i->i_lineno && !assemble_lnotab(a, i)) { return 0; } if (!assemble_enotab(a, i)) { return 0; } - if (!assemble_cnotab(a, i, size)) { + if (!assemble_cnotab(a, i, tsize)) { return 0; } - if (a->a_offset + size >= len / (int)sizeof(_Py_CODEUNIT)) { + if (a->a_offset + tsize >= len / (int)sizeof(_Py_CODEUNIT)) { if (len > PY_SSIZE_T_MAX / 2) return 0; if (_PyBytes_Resize(&a->a_bytecode, len * 2) < 0) return 0; } code = (_Py_CODEUNIT *)PyBytes_AS_STRING(a->a_bytecode) + a->a_offset; - a->a_offset += size; - write_op_arg(code, i->i_opcode, arg, size); + a->a_offset += tsize; + write_op_arg(code, i->i_opcode, arg, isize); + code += isize; + for (int j = 0; j < _Py_InlineCacheSize[i->i_opcode]; j++) { + *code++ = PACKOPARG(CACHE_ENTRY, j); + } return 1; } @@ -7587,6 +7588,7 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c) extended_arg_recompile = 1; } } + bsize += _Py_InlineCacheSize[instr->i_opcode]; } } diff --git a/Python/specialize.c b/Python/specialize.c index 3c350c098a2028..cd29f3cfcca9bc 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -53,10 +53,14 @@ static uint8_t adaptive_opcodes[256] = { [UNPACK_SEQUENCE] = UNPACK_SEQUENCE_ADAPTIVE, }; -static uint8_t inline_opcodes[256] = { +static const uint8_t inline_opcodes[256] = { [LOAD_GLOBAL] = LOAD_GLOBAL_ADAPTIVE, }; +const uint8_t _Py_InlineCacheSize[256] = { + [LOAD_GLOBAL] = LOAD_GLOBAL_INLINE_CACHE_SIZE, +}; + /* The number of cache entries required for a "family" of instructions. */ static uint8_t cache_requirements[256] = { [LOAD_ATTR] = 2, /* _PyAdaptiveEntry and _PyAttrCache */ @@ -1213,9 +1217,13 @@ _Py_Specialize_LoadGlobal( SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_VERSIONS); goto fail; } + if (builtins_version > UINT16_MAX) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE); + goto fail; + } cache->index = (uint16_t)index; write32(&cache->module_keys_version, globals_version); - write32(&cache->builtin_keys_version, builtins_version); + cache->builtin_keys_version = (uint16_t)builtins_version; *instr = _Py_MAKECODEUNIT(LOAD_GLOBAL_BUILTIN, _Py_OPARG(*instr)); goto success; fail: diff --git a/Python/wordcode_helpers.h b/Python/wordcode_helpers.h index c8f7a0f41f9035..3615b6b495f978 100644 --- a/Python/wordcode_helpers.h +++ b/Python/wordcode_helpers.h @@ -19,6 +19,8 @@ instrsize(unsigned int oparg) 4; } +extern const uint8_t _Py_InlineCacheSize[256]; + /* Spits out op/oparg pair using ilen bytes. codestr should be pointed at the desired location of the first EXTENDED_ARG */ static void From 98f73a169cca90835ffa3a074a4ae786b135e6c6 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Feb 2022 13:03:40 +0000 Subject: [PATCH 03/11] Use native endianness for 32 bit cache entries. --- Include/internal/pycore_code.h | 29 ++++++++++++++++++++++++++++- Python/specialize.c | 2 ++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index 04b62cb8574015..e8f942fecf4982 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -362,7 +362,33 @@ PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void); #define OBJECT_STAT_INC(name) ((void)0) #endif -/* TO DO -- Move these somewhere sensible and use native endianness */ + +unsigned int unaligned_load_big(unsigned short *p) { + return (p[0] << 16) | p[1]; +} + +unsigned int unaligned_load_little(unsigned short *p) { + return (p[1] << 16) | p[0]; +} + +// Cache values are only valid in memory, so use native endianness. +#ifdef WORDS_BIGENDIAN + +static inline void +write32(uint16_t *p, uint32_t val) +{ + p[0] = val >> 16; + p[1] = (uint16_t)val; +} + +static inline uint32_t +read32(uint16_t *p) +{ + return (p[0] << 16) | p[1]; +} + +#else + static inline void write32(uint16_t *p, uint32_t val) { @@ -376,6 +402,7 @@ read32(uint16_t *p) return p[0] | (p[1] << 16); } +#endif #ifdef __cplusplus } diff --git a/Python/specialize.c b/Python/specialize.c index ba62dac9d4405c..fd9ea1f88924e6 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -1208,6 +1208,8 @@ _Py_Specialize_LoadGlobal( PyObject *globals, PyObject *builtins, _Py_CODEUNIT *instr, PyObject *name) { + assert(_PyOpcode_InlineCacheEntries[LOAD_GLOBAL] == + INLINE_CACHE_ENTRIES_LOAD_GLOBAL); /* Use inline cache */ _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)(instr+1); assert(PyUnicode_CheckExact(name)); From 87b63f9700e9678cf7952b0ef63c2a110c65f9cf Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Feb 2022 13:08:36 +0000 Subject: [PATCH 04/11] Remove unused code. --- Include/internal/pycore_code.h | 9 --------- Include/opcode.h | 1 - Lib/opcode.py | 1 - Python/ceval.c | 5 ----- Python/opcode_targets.h | 2 +- 5 files changed, 1 insertion(+), 17 deletions(-) diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index e8f942fecf4982..b112fa737fee43 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -362,15 +362,6 @@ PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void); #define OBJECT_STAT_INC(name) ((void)0) #endif - -unsigned int unaligned_load_big(unsigned short *p) { - return (p[0] << 16) | p[1]; -} - -unsigned int unaligned_load_little(unsigned short *p) { - return (p[1] << 16) | p[0]; -} - // Cache values are only valid in memory, so use native endianness. #ifdef WORDS_BIGENDIAN diff --git a/Include/opcode.h b/Include/opcode.h index 8c0869c76b6e66..faa72c7ad2408b 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -114,7 +114,6 @@ extern "C" { #define PRECALL 166 #define CALL 171 #define KW_NAMES 172 -#define CACHE_ENTRY 240 #define BINARY_OP_ADAPTIVE 4 #define BINARY_OP_ADD_INT 5 #define BINARY_OP_ADD_FLOAT 6 diff --git a/Lib/opcode.py b/Lib/opcode.py index 3e692b7b034d00..a2206b023a4ccb 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -198,7 +198,6 @@ def jabs_op(name, op, entries=0): def_op('KW_NAMES', 172) hasconst.append(172) -def_op('CACHE_ENTRY', 240) del def_op, name_op, jrel_op, jabs_op diff --git a/Python/ceval.c b/Python/ceval.c index 3c6d4467054aa7..355b90f0c2b002 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1731,11 +1731,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr DISPATCH(); } - TARGET(CACHE_ENTRY) { - _PyErr_SetString(tstate, PyExc_SystemError, "Attempting to execute a cache entry"); - goto error; - } - TARGET(RESUME) { int err = _Py_IncrementCountAndMaybeQuicken(frame->f_code); if (err) { diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 1684c8b44b619b..d463e303e27ac7 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -239,7 +239,7 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&TARGET_CACHE_ENTRY, + &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, From cca4d6b23d55386953cfe6554b1ced84f67b0ec0 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Feb 2022 13:18:42 +0000 Subject: [PATCH 05/11] Add news --- .../Core and Builtins/2022-02-25-13-18-18.bpo-46841.86QiQu.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-02-25-13-18-18.bpo-46841.86QiQu.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-25-13-18-18.bpo-46841.86QiQu.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-25-13-18-18.bpo-46841.86QiQu.rst new file mode 100644 index 00000000000000..de8261fe4784ea --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-02-25-13-18-18.bpo-46841.86QiQu.rst @@ -0,0 +1 @@ +Use inline cache for :opcode:`LOAD_GLOBAL`. From 26d0d70f50e686ed79f086bee80d3f7a4f2f916e Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Feb 2022 13:26:58 +0000 Subject: [PATCH 06/11] Fix up test_dis --- Lib/test/test_dis.py | 346 +++++++++++++++++++++---------------------- 1 file changed, 173 insertions(+), 173 deletions(-) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index e478ca966612ba..a0639afdf01e84 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -149,10 +149,10 @@ def bug708901(): %3d PRECALL 2 CALL 2 GET_ITER - >> FOR_ITER 2 (to 22) + >> FOR_ITER 2 (to 32) STORE_FAST 0 (res) -%3d JUMP_ABSOLUTE 8 (to 16) +%3d JUMP_ABSOLUTE 13 (to 26) %3d >> LOAD_CONST 0 (None) RETURN_VALUE @@ -375,7 +375,7 @@ def bug42562(): >> PUSH_EXC_INFO %3d LOAD_GLOBAL 0 (Exception) - JUMP_IF_NOT_EXC_MATCH 26 (to 52) + JUMP_IF_NOT_EXC_MATCH 31 (to 62) STORE_FAST 0 (e) %3d LOAD_FAST 0 (e) @@ -1140,7 +1140,7 @@ def _prepare_test_cases(): ',\n '.join(map(_stringify_instruction, _instructions)), ',\n]', sep='') dis.dis(outer) -#_prepare_test_cases() +_prepare_test_cases() Instruction = dis.Instruction expected_opinfo_outer = [ @@ -1156,18 +1156,18 @@ def _prepare_test_cases(): Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='f', argrepr='f', offset=18, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=20, starts_line=7, is_jump_target=False, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=22, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='a', argrepr='a', offset=24, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='b', argrepr='b', offset=26, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='', argrepr="''", offset=28, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=30, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=32, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=34, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Hello world!', argrepr="'Hello world!'", offset=36, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=7, argval=7, argrepr='', offset=38, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=7, argval=7, argrepr='', offset=40, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=42, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=44, starts_line=8, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=46, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='a', argrepr='a', offset=34, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='b', argrepr='b', offset=36, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='', argrepr="''", offset=38, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=40, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=42, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=44, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Hello world!', argrepr="'Hello world!'", offset=46, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=7, argval=7, argrepr='', offset=48, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=7, argval=7, argrepr='', offset=50, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=52, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=54, starts_line=8, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=56, starts_line=None, is_jump_target=False, positions=None), ] expected_opinfo_f = [ @@ -1186,15 +1186,15 @@ def _prepare_test_cases(): Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='inner', argrepr='inner', offset=24, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=26, starts_line=5, is_jump_target=False, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=28, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='a', argrepr='a', offset=30, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='b', argrepr='b', offset=32, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='c', argrepr='c', offset=34, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='d', argrepr='d', offset=36, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=4, argval=4, argrepr='', offset=38, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=4, argval=4, argrepr='', offset=40, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=42, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=44, starts_line=6, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=46, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='a', argrepr='a', offset=40, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='b', argrepr='b', offset=42, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='c', argrepr='c', offset=44, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='d', argrepr='d', offset=46, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=4, argval=4, argrepr='', offset=48, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=4, argval=4, argrepr='', offset=50, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=52, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=54, starts_line=6, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=56, starts_line=None, is_jump_target=False, positions=None), ] expected_opinfo_inner = [ @@ -1202,160 +1202,160 @@ def _prepare_test_cases(): Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=2, starts_line=3, is_jump_target=False, positions=None), Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=4, starts_line=4, is_jump_target=False, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=6, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=2, argval='a', argrepr='a', offset=8, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='b', argrepr='b', offset=10, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='c', argrepr='c', offset=12, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=5, argval='d', argrepr='d', offset=14, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='e', argrepr='e', offset=16, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=1, argval='f', argrepr='f', offset=18, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=6, argval=6, argrepr='', offset=20, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=6, argval=6, argrepr='', offset=22, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=24, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=26, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=28, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=2, argval='a', argrepr='a', offset=18, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='b', argrepr='b', offset=20, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='c', argrepr='c', offset=22, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=5, argval='d', argrepr='d', offset=24, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='e', argrepr='e', offset=26, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=1, argval='f', argrepr='f', offset=28, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=6, argval=6, argrepr='', offset=30, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=6, argval=6, argrepr='', offset=32, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=34, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=36, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=38, starts_line=None, is_jump_target=False, positions=None), ] expected_opinfo_jumpy = [ Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=0, starts_line=1, is_jump_target=False, positions=None), Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=2, starts_line=3, is_jump_target=False, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='range', argrepr='range', offset=4, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=10, argrepr='10', offset=6, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=8, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=10, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=12, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='FOR_ITER', opcode=93, arg=19, argval=54, argrepr='to 54', offset=14, starts_line=None, is_jump_target=True, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=16, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=18, starts_line=4, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=20, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=22, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=24, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=26, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=28, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=30, starts_line=5, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=32, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=34, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=20, argval=40, argrepr='to 40', offset=36, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=7, argval=14, argrepr='to 14', offset=38, starts_line=6, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=40, starts_line=7, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=42, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=44, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=26, argval=52, argrepr='to 52', offset=46, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=48, starts_line=8, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=7, argval=66, argrepr='to 66', offset=50, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=7, argval=14, argrepr='to 14', offset=52, starts_line=7, is_jump_target=True, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=54, starts_line=10, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=56, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=58, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=60, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=62, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=64, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=66, starts_line=11, is_jump_target=True, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=58, argval=116, argrepr='to 116', offset=68, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=70, starts_line=12, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=72, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=74, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=76, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=78, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=80, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=82, starts_line=13, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=84, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BINARY_OP', opcode=122, arg=23, argval=23, argrepr='-=', offset=86, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=90, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=92, starts_line=14, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=94, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=96, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=51, argval=102, argrepr='to 102', offset=98, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=33, argval=66, argrepr='to 66', offset=100, starts_line=15, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=102, starts_line=16, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=104, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=106, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=56, argval=112, argrepr='to 112', offset=108, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=8, argval=128, argrepr='to 128', offset=110, starts_line=17, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=112, starts_line=11, is_jump_target=True, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=35, argval=70, argrepr='to 70', offset=114, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=116, starts_line=19, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=118, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=120, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=122, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=124, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=126, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=128, starts_line=20, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=130, starts_line=21, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=132, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BINARY_OP', opcode=122, arg=11, argval=11, argrepr='/', offset=134, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=138, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=140, starts_line=25, is_jump_target=False, positions=None), - Instruction(opname='BEFORE_WITH', opcode=53, arg=None, argval=None, argrepr='', offset=142, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=144, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=146, starts_line=26, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=148, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=150, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=152, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=154, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=156, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=158, starts_line=25, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=160, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=162, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=2, argval=2, argrepr='', offset=164, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=2, argval=2, argrepr='', offset=166, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=168, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=11, argval=194, argrepr='to 194', offset=170, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=172, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=174, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=93, argval=186, argrepr='to 186', offset=176, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=2, argval=2, argrepr='', offset=178, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=180, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=182, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=184, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=186, starts_line=None, is_jump_target=True, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=188, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=190, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=192, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=16, argval=228, argrepr='to 228', offset=194, starts_line=None, is_jump_target=True, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=196, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=2, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=198, starts_line=22, is_jump_target=False, positions=None), - Instruction(opname='JUMP_IF_NOT_EXC_MATCH', opcode=121, arg=110, argval=220, argrepr='to 220', offset=200, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=202, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=204, starts_line=23, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=206, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=208, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=210, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=212, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=214, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=216, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=12, argval=244, argrepr='to 244', offset=218, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=220, starts_line=22, is_jump_target=True, positions=None), - Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=222, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=224, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=226, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=228, starts_line=28, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=230, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=232, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=234, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=236, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=238, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=240, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=242, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=244, starts_line=23, is_jump_target=True, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=246, starts_line=28, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=248, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=250, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=252, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=254, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=256, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=258, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=260, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=262, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=264, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=266, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=268, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=270, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=272, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=274, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=276, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=278, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=280, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=282, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=10, argrepr='10', offset=16, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=18, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=20, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=22, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='FOR_ITER', opcode=93, arg=24, argval=74, argrepr='to 74', offset=24, starts_line=None, is_jump_target=True, positions=None), + Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=26, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=28, starts_line=4, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=30, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=42, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=44, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=46, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=48, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=50, starts_line=5, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=52, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=54, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=30, argval=60, argrepr='to 60', offset=56, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=12, argval=24, argrepr='to 24', offset=58, starts_line=6, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=60, starts_line=7, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=62, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=64, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=36, argval=72, argrepr='to 72', offset=66, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=68, starts_line=8, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=12, argval=96, argrepr='to 96', offset=70, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=12, argval=24, argrepr='to 24', offset=72, starts_line=7, is_jump_target=True, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=74, starts_line=10, is_jump_target=True, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=76, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=88, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=90, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=92, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=94, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=96, starts_line=11, is_jump_target=True, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=78, argval=156, argrepr='to 156', offset=98, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=100, starts_line=12, is_jump_target=True, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=102, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=114, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=116, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=118, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=120, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=122, starts_line=13, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=124, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BINARY_OP', opcode=122, arg=23, argval=23, argrepr='-=', offset=126, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=130, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=132, starts_line=14, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=134, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=136, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=71, argval=142, argrepr='to 142', offset=138, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=48, argval=96, argrepr='to 96', offset=140, starts_line=15, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=142, starts_line=16, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=144, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=146, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=76, argval=152, argrepr='to 152', offset=148, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=13, argval=178, argrepr='to 178', offset=150, starts_line=17, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=152, starts_line=11, is_jump_target=True, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=50, argval=100, argrepr='to 100', offset=154, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=156, starts_line=19, is_jump_target=True, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=158, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=170, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=172, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=174, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=176, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=178, starts_line=20, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=180, starts_line=21, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=182, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BINARY_OP', opcode=122, arg=11, argval=11, argrepr='/', offset=184, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=188, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=190, starts_line=25, is_jump_target=False, positions=None), + Instruction(opname='BEFORE_WITH', opcode=53, arg=None, argval=None, argrepr='', offset=192, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=194, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=196, starts_line=26, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=198, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=210, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=212, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=214, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=216, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=218, starts_line=25, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=220, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=222, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=2, argval=2, argrepr='', offset=224, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=2, argval=2, argrepr='', offset=226, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=228, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=11, argval=254, argrepr='to 254', offset=230, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=232, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=234, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=123, argval=246, argrepr='to 246', offset=236, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=2, argval=2, argrepr='', offset=238, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=240, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=242, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=244, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=246, starts_line=None, is_jump_target=True, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=248, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=250, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=252, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=26, argval=308, argrepr='to 308', offset=254, starts_line=None, is_jump_target=True, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=256, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=2, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=258, starts_line=22, is_jump_target=False, positions=None), + Instruction(opname='JUMP_IF_NOT_EXC_MATCH', opcode=121, arg=150, argval=300, argrepr='to 300', offset=270, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=272, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=274, starts_line=23, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=276, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=288, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=290, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=292, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=294, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=296, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=17, argval=334, argrepr='to 334', offset=298, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=300, starts_line=22, is_jump_target=True, positions=None), + Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=302, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=304, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=306, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=308, starts_line=28, is_jump_target=True, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=310, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=322, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=324, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=326, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=328, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=330, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=332, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=334, starts_line=23, is_jump_target=True, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=336, starts_line=28, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=338, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=350, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=352, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=354, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=356, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=358, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=360, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=362, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=364, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=366, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=378, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=380, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=382, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=384, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=386, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=388, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=390, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=392, starts_line=None, is_jump_target=False, positions=None), ] # One last piece of inspect fodder to check the default line number handling From c49f156565fd934e410ff0be9f9e6d208066836e Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Feb 2022 15:34:24 +0000 Subject: [PATCH 07/11] Restore specialization of LOAD_GLOBAL. --- Python/specialize.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Python/specialize.c b/Python/specialize.c index fd9ea1f88924e6..8c7b0c68f66306 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -42,6 +42,7 @@ /* Map from opcode to adaptive opcode. Values of zero are ignored. */ static uint8_t adaptive_opcodes[256] = { + [LOAD_GLOBAL] = LOAD_GLOBAL_ADAPTIVE, [LOAD_ATTR] = LOAD_ATTR_ADAPTIVE, [LOAD_METHOD] = LOAD_METHOD_ADAPTIVE, [BINARY_SUBSCR] = BINARY_SUBSCR_ADAPTIVE, From f65ae9ff024037fcee750f9dd078df81567fb881 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 25 Feb 2022 15:44:05 +0000 Subject: [PATCH 08/11] Turn off test_dis test output generation. --- Lib/test/test_dis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index a0639afdf01e84..a13e0f6edb8748 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -1140,7 +1140,7 @@ def _prepare_test_cases(): ',\n '.join(map(_stringify_instruction, _instructions)), ',\n]', sep='') dis.dis(outer) -_prepare_test_cases() +#_prepare_test_cases() Instruction = dis.Instruction expected_opinfo_outer = [ From c6c052758f4e88f3999daacd84d964e2047488af Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 28 Feb 2022 11:13:33 +0000 Subject: [PATCH 09/11] Clean up messy merge. --- Python/ceval.c | 17 +---------------- Python/specialize.c | 2 +- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index 470d8eaef8f134..83c7e06caa122a 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -5546,21 +5546,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int /* Specialization misses */ -#define MISS_INLINE_CACHE(opname) \ -opname ## _miss: \ - { \ - STAT_INC(opcode, miss); \ - STAT_INC(opname, miss); \ - uint16_t *counter = next_instr; \ - *counter = *counter-1; \ - if (*counter == 0) { \ - next_instr[-1] = _Py_MAKECODEUNIT(opname ## _ADAPTIVE, _Py_OPARG(next_instr[-1])); \ - STAT_INC(opname, deopt); \ - *counter = ADAPTIVE_CACHE_BACKOFF; \ - } \ - JUMP_TO_INSTRUCTION(opname); \ - } - #define MISS_WITH_CACHE(opname) \ opname ## _miss: \ { \ @@ -5610,7 +5595,7 @@ opname ## _miss: \ MISS_WITH_CACHE(LOAD_ATTR) MISS_WITH_CACHE(STORE_ATTR) -MISS_INLINE_CACHE(LOAD_GLOBAL) +MISS_WITH_INLINE_CACHE(LOAD_GLOBAL) MISS_WITH_CACHE(LOAD_METHOD) MISS_WITH_CACHE(PRECALL) MISS_WITH_CACHE(CALL) diff --git a/Python/specialize.c b/Python/specialize.c index f7bcdf035ed23f..42f635237d0cad 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -43,8 +43,8 @@ /* Map from opcode to adaptive opcode. Values of zero are ignored. */ static uint8_t adaptive_opcodes[256] = { - [LOAD_GLOBAL] = LOAD_GLOBAL_ADAPTIVE, [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, From 0a853aff3f176d8e7fcb36d420ffb7b126cf5eaa Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 28 Feb 2022 11:25:26 +0000 Subject: [PATCH 10/11] Address review comments. --- Include/opcode.h | 1 + Python/specialize.c | 2 +- Tools/scripts/generate_opcode_h.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Include/opcode.h b/Include/opcode.h index faa72c7ad2408b..99b2ee5c0a6ea8 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -187,6 +187,7 @@ extern "C" { #define DO_TRACING 255 extern const uint8_t _PyOpcode_InlineCacheEntries[256]; + #ifdef NEED_OPCODE_TABLES static const uint32_t _PyOpcode_RelativeJump[8] = { 0U, diff --git a/Python/specialize.c b/Python/specialize.c index 42f635237d0cad..bdbdff9d153ea6 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -1213,7 +1213,7 @@ _Py_Specialize_LoadGlobal( assert(_PyOpcode_InlineCacheEntries[LOAD_GLOBAL] == INLINE_CACHE_ENTRIES_LOAD_GLOBAL); /* Use inline cache */ - _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)(instr+1); + _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)(instr + 1); assert(PyUnicode_CheckExact(name)); if (!PyDict_CheckExact(globals)) { goto fail; diff --git a/Tools/scripts/generate_opcode_h.py b/Tools/scripts/generate_opcode_h.py index b9c6afc588e0b9..75a9c3f3bfadbc 100644 --- a/Tools/scripts/generate_opcode_h.py +++ b/Tools/scripts/generate_opcode_h.py @@ -76,7 +76,7 @@ def main(opcode_py, outfile='Include/opcode.h'): used[next_op] = True fobj.write(DEFINE.format('DO_TRACING', 255)) fobj.write("\nextern const uint8_t _PyOpcode_InlineCacheEntries[256];\n") - fobj.write("#ifdef NEED_OPCODE_TABLES\n") + fobj.write("\n#ifdef NEED_OPCODE_TABLES\n") write_int_array_from_ops("_PyOpcode_RelativeJump", opcode['hasjrel'], fobj) write_int_array_from_ops("_PyOpcode_Jump", opcode['hasjrel'] + opcode['hasjabs'], fobj) From 92a4b04ec39ba0721608e745eda11ad5198b3170 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 28 Feb 2022 11:42:19 +0000 Subject: [PATCH 11/11] Bump version number. --- Lib/importlib/_bootstrap_external.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 53fe1b8fc217a8..ff721e5d53f6e8 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -387,7 +387,8 @@ def _write_atomic(path, data, mode=0o666): # Python 3.11a5 3478 (New CALL opcodes) # Python 3.11a5 3479 (Add PUSH_NULL opcode) # Python 3.11a5 3480 (New CALL opcodes, second iteration) -# Python 3.11a5 3481 (Use inline CACHE instructions) +# Python 3.11a5 3481 (Use inline cache for BINARY_OP) +# Python 3.11a5 3482 (Use inline cache for LOAD_GLOBAL) # Python 3.12 will start with magic number 3500 @@ -402,7 +403,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 = (3481).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3482).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _PYCACHE = '__pycache__'