diff options
author | Mark Shannon <mark@hotpy.org> | 2022-12-14 11:12:53 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-14 11:12:53 (GMT) |
commit | 6997e77bdf2297375962aaf82876da4e7ecdd61a (patch) | |
tree | 7f6540eecbb66fd373b22e944163bdcb436f245b | |
parent | 985a71032bf055240e61259285a0b4925c925383 (diff) | |
download | cpython-6997e77bdf2297375962aaf82876da4e7ecdd61a.zip cpython-6997e77bdf2297375962aaf82876da4e7ecdd61a.tar.gz cpython-6997e77bdf2297375962aaf82876da4e7ecdd61a.tar.bz2 |
GH-100222: Redefine _Py_CODEUNIT as a union to clarify structure of code unit. (GH-100223)
-rw-r--r-- | Include/cpython/code.h | 31 | ||||
-rw-r--r-- | Include/internal/pycore_code.h | 48 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2022-12-13-16-05-18.gh-issue-100222.OVVvYe.rst | 2 | ||||
-rw-r--r-- | Objects/codeobject.c | 11 | ||||
-rw-r--r-- | Python/ceval.c | 4 | ||||
-rw-r--r-- | Python/compile.c | 20 | ||||
-rw-r--r-- | Python/generated_cases.c.h | 26 | ||||
-rw-r--r-- | Python/specialize.c | 142 | ||||
-rw-r--r-- | Tools/cases_generator/generate_cases.py | 2 |
9 files changed, 151 insertions, 135 deletions
diff --git a/Include/cpython/code.h b/Include/cpython/code.h index fc7c5ed..6a13ff2 100644 --- a/Include/cpython/code.h +++ b/Include/cpython/code.h @@ -16,21 +16,24 @@ extern "C" { * 2**32 - 1, rather than INT_MAX. */ -typedef uint16_t _Py_CODEUNIT; - -#ifdef WORDS_BIGENDIAN -# define _Py_OPCODE(word) ((word) >> 8) -# define _Py_OPARG(word) ((word) & 255) -# define _Py_MAKECODEUNIT(opcode, oparg) (((opcode)<<8)|(oparg)) -#else -# define _Py_OPCODE(word) ((word) & 255) -# define _Py_OPARG(word) ((word) >> 8) -# define _Py_MAKECODEUNIT(opcode, oparg) ((opcode)|((oparg)<<8)) -#endif +typedef union { + uint16_t cache; + struct { + uint8_t opcode; + uint8_t oparg; + }; +} _Py_CODEUNIT; + +#define _Py_OPCODE(word) ((word).opcode) +#define _Py_OPARG(word) ((word).oparg) + +static inline void +_py_set_opocde(_Py_CODEUNIT *word, uint8_t opcode) +{ + word->opcode = opcode; +} -// Use "unsigned char" instead of "uint8_t" here to avoid illegal aliasing: -#define _Py_SET_OPCODE(word, opcode) \ - do { ((unsigned char *)&(word))[0] = (opcode); } while (0) +#define _Py_SET_OPCODE(word, opcode) _py_set_opocde(&(word), opcode) typedef struct { PyObject *_co_code; diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index f22fd45..9e59fc9 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -18,53 +18,53 @@ extern "C" { #define CACHE_ENTRIES(cache) (sizeof(cache)/sizeof(_Py_CODEUNIT)) typedef struct { - _Py_CODEUNIT counter; - _Py_CODEUNIT index; - _Py_CODEUNIT module_keys_version[2]; - _Py_CODEUNIT builtin_keys_version; + uint16_t counter; + uint16_t index; + uint16_t module_keys_version[2]; + uint16_t builtin_keys_version; } _PyLoadGlobalCache; #define INLINE_CACHE_ENTRIES_LOAD_GLOBAL CACHE_ENTRIES(_PyLoadGlobalCache) typedef struct { - _Py_CODEUNIT counter; + uint16_t counter; } _PyBinaryOpCache; #define INLINE_CACHE_ENTRIES_BINARY_OP CACHE_ENTRIES(_PyBinaryOpCache) typedef struct { - _Py_CODEUNIT counter; + uint16_t counter; } _PyUnpackSequenceCache; #define INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE \ CACHE_ENTRIES(_PyUnpackSequenceCache) typedef struct { - _Py_CODEUNIT counter; - _Py_CODEUNIT mask; + uint16_t counter; + uint16_t mask; } _PyCompareOpCache; #define INLINE_CACHE_ENTRIES_COMPARE_OP CACHE_ENTRIES(_PyCompareOpCache) typedef struct { - _Py_CODEUNIT counter; - _Py_CODEUNIT type_version[2]; - _Py_CODEUNIT func_version; + uint16_t counter; + uint16_t type_version[2]; + uint16_t func_version; } _PyBinarySubscrCache; #define INLINE_CACHE_ENTRIES_BINARY_SUBSCR CACHE_ENTRIES(_PyBinarySubscrCache) typedef struct { - _Py_CODEUNIT counter; - _Py_CODEUNIT version[2]; - _Py_CODEUNIT index; + uint16_t counter; + uint16_t version[2]; + uint16_t index; } _PyAttrCache; typedef struct { - _Py_CODEUNIT counter; - _Py_CODEUNIT type_version[2]; - _Py_CODEUNIT keys_version[2]; - _Py_CODEUNIT descr[4]; + uint16_t counter; + uint16_t type_version[2]; + uint16_t keys_version[2]; + uint16_t descr[4]; } _PyLoadMethodCache; @@ -74,21 +74,21 @@ typedef struct { #define INLINE_CACHE_ENTRIES_STORE_ATTR CACHE_ENTRIES(_PyAttrCache) typedef struct { - _Py_CODEUNIT counter; - _Py_CODEUNIT func_version[2]; - _Py_CODEUNIT min_args; + uint16_t counter; + uint16_t func_version[2]; + uint16_t min_args; } _PyCallCache; #define INLINE_CACHE_ENTRIES_CALL CACHE_ENTRIES(_PyCallCache) typedef struct { - _Py_CODEUNIT counter; + uint16_t counter; } _PyStoreSubscrCache; #define INLINE_CACHE_ENTRIES_STORE_SUBSCR CACHE_ENTRIES(_PyStoreSubscrCache) typedef struct { - _Py_CODEUNIT counter; + uint16_t counter; } _PyForIterCache; #define INLINE_CACHE_ENTRIES_FOR_ITER CACHE_ENTRIES(_PyForIterCache) @@ -409,7 +409,7 @@ write_location_entry_start(uint8_t *ptr, int code, int length) static inline uint16_t adaptive_counter_bits(int value, int backoff) { return (value << ADAPTIVE_BACKOFF_BITS) | - (backoff & ((1<<ADAPTIVE_BACKOFF_BITS)-1)); + (backoff & ((1<<ADAPTIVE_BACKOFF_BITS)-1)); } static inline uint16_t diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-12-13-16-05-18.gh-issue-100222.OVVvYe.rst b/Misc/NEWS.d/next/Core and Builtins/2022-12-13-16-05-18.gh-issue-100222.OVVvYe.rst new file mode 100644 index 0000000..032b494 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-12-13-16-05-18.gh-issue-100222.OVVvYe.rst @@ -0,0 +1,2 @@ +Redefine the ``_Py_CODEUNIT`` typedef as a union to describe its layout to +the C compiler, avoiding type punning and improving clarity. diff --git a/Objects/codeobject.c b/Objects/codeobject.c index c92c7de..f455cc6 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1520,9 +1520,10 @@ deopt_code(_Py_CODEUNIT *instructions, Py_ssize_t len) _Py_CODEUNIT instruction = instructions[i]; int opcode = _PyOpcode_Deopt[_Py_OPCODE(instruction)]; int caches = _PyOpcode_Caches[opcode]; - instructions[i] = _Py_MAKECODEUNIT(opcode, _Py_OPARG(instruction)); + instructions[i].opcode = opcode; while (caches--) { - instructions[++i] = _Py_MAKECODEUNIT(CACHE, 0); + instructions[++i].opcode = CACHE; + instructions[i].oparg = 0; } } } @@ -1775,9 +1776,9 @@ code_richcompare(PyObject *self, PyObject *other, int op) for (int i = 0; i < Py_SIZE(co); i++) { _Py_CODEUNIT co_instr = _PyCode_CODE(co)[i]; _Py_CODEUNIT cp_instr = _PyCode_CODE(cp)[i]; - _Py_SET_OPCODE(co_instr, _PyOpcode_Deopt[_Py_OPCODE(co_instr)]); - _Py_SET_OPCODE(cp_instr, _PyOpcode_Deopt[_Py_OPCODE(cp_instr)]); - eq = co_instr == cp_instr; + co_instr.opcode = _PyOpcode_Deopt[_Py_OPCODE(co_instr)]; + cp_instr.opcode =_PyOpcode_Deopt[_Py_OPCODE(cp_instr)]; + eq = co_instr.cache == cp_instr.cache; if (!eq) { goto unequal; } diff --git a/Python/ceval.c b/Python/ceval.c index 9e4179e..45f4280 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -864,7 +864,7 @@ GETITEM(PyObject *v, Py_ssize_t i) { STAT_INC(opcode, miss); \ STAT_INC((INSTNAME), miss); \ /* The counter is always the first cache entry: */ \ - if (ADAPTIVE_COUNTER_IS_ZERO(*next_instr)) { \ + if (ADAPTIVE_COUNTER_IS_ZERO(next_instr->cache)) { \ STAT_INC((INSTNAME), deopt); \ } \ else { \ @@ -1289,7 +1289,7 @@ handle_eval_breaker: } opcode = _PyOpcode_Deopt[opcode]; if (_PyOpcode_Caches[opcode]) { - _Py_CODEUNIT *counter = &next_instr[1]; + uint16_t *counter = &next_instr[1].cache; // The instruction is going to decrement the counter, so we need to // increment it here to make sure it doesn't try to specialize: if (!ADAPTIVE_COUNTER_IS_MAX(*counter)) { diff --git a/Python/compile.c b/Python/compile.c index 813e0d5..09eb401 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -263,22 +263,32 @@ write_instr(_Py_CODEUNIT *codestr, struct instr *instruction, int ilen) int caches = _PyOpcode_Caches[opcode]; switch (ilen - caches) { case 4: - *codestr++ = _Py_MAKECODEUNIT(EXTENDED_ARG, (oparg >> 24) & 0xFF); + codestr->opcode = EXTENDED_ARG; + codestr->oparg = (oparg >> 24) & 0xFF; + codestr++; /* fall through */ case 3: - *codestr++ = _Py_MAKECODEUNIT(EXTENDED_ARG, (oparg >> 16) & 0xFF); + codestr->opcode = EXTENDED_ARG; + codestr->oparg = (oparg >> 16) & 0xFF; + codestr++; /* fall through */ case 2: - *codestr++ = _Py_MAKECODEUNIT(EXTENDED_ARG, (oparg >> 8) & 0xFF); + codestr->opcode = EXTENDED_ARG; + codestr->oparg = (oparg >> 8) & 0xFF; + codestr++; /* fall through */ case 1: - *codestr++ = _Py_MAKECODEUNIT(opcode, oparg & 0xFF); + codestr->opcode = opcode; + codestr->oparg = oparg & 0xFF; + codestr++; break; default: Py_UNREACHABLE(); } while (caches--) { - *codestr++ = _Py_MAKECODEUNIT(CACHE, 0); + codestr->opcode = CACHE; + codestr->oparg = 0; + codestr++; } } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 45382a4..63635fb 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -562,8 +562,8 @@ TARGET(BINARY_SUBSCR_GETITEM) { PyObject *sub = PEEK(1); PyObject *container = PEEK(2); - uint32_t type_version = read_u32(next_instr + 1); - uint16_t func_version = read_u16(next_instr + 3); + uint32_t type_version = read_u32(&next_instr[1].cache); + uint16_t func_version = read_u16(&next_instr[3].cache); PyTypeObject *tp = Py_TYPE(container); DEOPT_IF(tp->tp_version_tag != type_version, BINARY_SUBSCR); assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE); @@ -612,7 +612,7 @@ PyObject *sub = PEEK(1); PyObject *container = PEEK(2); PyObject *v = PEEK(3); - uint16_t counter = read_u16(next_instr + 0); + uint16_t counter = read_u16(&next_instr[0].cache); if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { assert(cframe.use_tracing == 0); next_instr--; @@ -1249,7 +1249,7 @@ PREDICTED(STORE_ATTR); PyObject *owner = PEEK(1); PyObject *v = PEEK(2); - uint16_t counter = read_u16(next_instr + 0); + uint16_t counter = read_u16(&next_instr[0].cache); if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { assert(cframe.use_tracing == 0); PyObject *name = GETITEM(names, oparg); @@ -2083,8 +2083,8 @@ TARGET(STORE_ATTR_INSTANCE_VALUE) { PyObject *owner = PEEK(1); PyObject *value = PEEK(2); - uint32_t type_version = read_u32(next_instr + 1); - uint16_t index = read_u16(next_instr + 3); + uint32_t type_version = read_u32(&next_instr[1].cache); + uint16_t index = read_u16(&next_instr[3].cache); assert(cframe.use_tracing == 0); PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); @@ -2111,8 +2111,8 @@ TARGET(STORE_ATTR_WITH_HINT) { PyObject *owner = PEEK(1); PyObject *value = PEEK(2); - uint32_t type_version = read_u32(next_instr + 1); - uint16_t hint = read_u16(next_instr + 3); + uint32_t type_version = read_u32(&next_instr[1].cache); + uint16_t hint = read_u16(&next_instr[3].cache); assert(cframe.use_tracing == 0); PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); @@ -2160,8 +2160,8 @@ TARGET(STORE_ATTR_SLOT) { PyObject *owner = PEEK(1); PyObject *value = PEEK(2); - uint32_t type_version = read_u32(next_instr + 1); - uint16_t index = read_u16(next_instr + 3); + uint32_t type_version = read_u32(&next_instr[1].cache); + uint16_t index = read_u16(&next_instr[3].cache); assert(cframe.use_tracing == 0); PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); @@ -2209,7 +2209,7 @@ PyObject *right = _tmp_1; PyObject *left = _tmp_2; size_t jump; - uint16_t when_to_jump_mask = read_u16(next_instr + 1); + uint16_t when_to_jump_mask = read_u16(&next_instr[1].cache); assert(cframe.use_tracing == 0); // Combined: COMPARE_OP (float ? float) + POP_JUMP_IF_(true/false) DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP); @@ -2247,7 +2247,7 @@ PyObject *right = _tmp_1; PyObject *left = _tmp_2; size_t jump; - uint16_t when_to_jump_mask = read_u16(next_instr + 1); + uint16_t when_to_jump_mask = read_u16(&next_instr[1].cache); assert(cframe.use_tracing == 0); // Combined: COMPARE_OP (int ? int) + POP_JUMP_IF_(true/false) DEOPT_IF(!PyLong_CheckExact(left), COMPARE_OP); @@ -2286,7 +2286,7 @@ PyObject *right = _tmp_1; PyObject *left = _tmp_2; size_t jump; - uint16_t invert = read_u16(next_instr + 1); + uint16_t invert = read_u16(&next_instr[1].cache); assert(cframe.use_tracing == 0); // Combined: COMPARE_OP (str == str or str != str) + POP_JUMP_IF_(true/false) DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP); diff --git a/Python/specialize.c b/Python/specialize.c index 785088e..678c5d6 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -267,26 +267,26 @@ _PyCode_Quicken(PyCodeObject *code) int opcode = _PyOpcode_Deopt[_Py_OPCODE(instructions[i])]; int caches = _PyOpcode_Caches[opcode]; if (caches) { - instructions[i + 1] = adaptive_counter_warmup(); + instructions[i + 1].cache = adaptive_counter_warmup(); previous_opcode = 0; i += caches; continue; } switch (previous_opcode << 8 | opcode) { case LOAD_CONST << 8 | LOAD_FAST: - _Py_SET_OPCODE(instructions[i - 1], LOAD_CONST__LOAD_FAST); + instructions[i - 1].opcode = LOAD_CONST__LOAD_FAST; break; case LOAD_FAST << 8 | LOAD_CONST: - _Py_SET_OPCODE(instructions[i - 1], LOAD_FAST__LOAD_CONST); + instructions[i - 1].opcode = LOAD_FAST__LOAD_CONST; break; case LOAD_FAST << 8 | LOAD_FAST: - _Py_SET_OPCODE(instructions[i - 1], LOAD_FAST__LOAD_FAST); + instructions[i - 1].opcode = LOAD_FAST__LOAD_FAST; break; case STORE_FAST << 8 | LOAD_FAST: - _Py_SET_OPCODE(instructions[i - 1], STORE_FAST__LOAD_FAST); + instructions[i - 1].opcode = STORE_FAST__LOAD_FAST; break; case STORE_FAST << 8 | STORE_FAST: - _Py_SET_OPCODE(instructions[i - 1], STORE_FAST__STORE_FAST); + instructions[i - 1].opcode = STORE_FAST__STORE_FAST; break; } previous_opcode = opcode; @@ -482,7 +482,7 @@ specialize_module_load_attr(PyObject *owner, _Py_CODEUNIT *instr, } write_u32(cache->version, keys_version); cache->index = (uint16_t)index; - _Py_SET_OPCODE(*instr, opcode_module); + _py_set_opocde(instr, opcode_module); return 0; } @@ -634,7 +634,7 @@ specialize_dict_access( } write_u32(cache->version, type->tp_version_tag); cache->index = (uint16_t)index; - _Py_SET_OPCODE(*instr, values_op); + _py_set_opocde(instr, values_op); } else { PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); @@ -651,7 +651,7 @@ specialize_dict_access( } cache->index = (uint16_t)index; write_u32(cache->version, type->tp_version_tag); - _Py_SET_OPCODE(*instr, hint_op); + _py_set_opocde(instr, hint_op); } return 1; } @@ -730,7 +730,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) write_u32(lm_cache->type_version, type->tp_version_tag); /* borrowed */ write_obj(lm_cache->descr, fget); - _Py_SET_OPCODE(*instr, LOAD_ATTR_PROPERTY); + _py_set_opocde(instr, LOAD_ATTR_PROPERTY); goto success; } case OBJECT_SLOT: @@ -754,7 +754,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) assert(offset > 0); cache->index = (uint16_t)offset; write_u32(cache->version, type->tp_version_tag); - _Py_SET_OPCODE(*instr, LOAD_ATTR_SLOT); + _py_set_opocde(instr, LOAD_ATTR_SLOT); goto success; } case DUNDER_CLASS: @@ -763,7 +763,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) assert(offset == (uint16_t)offset); cache->index = (uint16_t)offset; write_u32(cache->version, type->tp_version_tag); - _Py_SET_OPCODE(*instr, LOAD_ATTR_SLOT); + _py_set_opocde(instr, LOAD_ATTR_SLOT); goto success; } case OTHER_SLOT: @@ -791,7 +791,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) /* borrowed */ write_obj(lm_cache->descr, descr); write_u32(lm_cache->type_version, type->tp_version_tag); - _Py_SET_OPCODE(*instr, LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN); + _py_set_opocde(instr, LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN); goto success; } case BUILTIN_CLASSMETHOD: @@ -809,7 +809,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) fail: STAT_INC(LOAD_ATTR, failure); assert(!PyErr_Occurred()); - _Py_SET_OPCODE(*instr, LOAD_ATTR); + _py_set_opocde(instr, LOAD_ATTR); cache->counter = adaptive_counter_backoff(cache->counter); return; success: @@ -868,7 +868,7 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) assert(offset > 0); cache->index = (uint16_t)offset; write_u32(cache->version, type->tp_version_tag); - _Py_SET_OPCODE(*instr, STORE_ATTR_SLOT); + _py_set_opocde(instr, STORE_ATTR_SLOT); goto success; } case DUNDER_CLASS: @@ -897,7 +897,7 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) fail: STAT_INC(STORE_ATTR, failure); assert(!PyErr_Occurred()); - _Py_SET_OPCODE(*instr, STORE_ATTR); + _py_set_opocde(instr, STORE_ATTR); cache->counter = adaptive_counter_backoff(cache->counter); return; success: @@ -961,7 +961,7 @@ specialize_class_load_attr(PyObject *owner, _Py_CODEUNIT *instr, case NON_DESCRIPTOR: write_u32(cache->type_version, ((PyTypeObject *)owner)->tp_version_tag); write_obj(cache->descr, descr); - _Py_SET_OPCODE(*instr, LOAD_ATTR_CLASS); + _py_set_opocde(instr, LOAD_ATTR_CLASS); return 0; #ifdef Py_STATS case ABSENT: @@ -1043,21 +1043,21 @@ PyObject *descr, DescriptorClassification kind) } switch(dictkind) { case NO_DICT: - _Py_SET_OPCODE(*instr, LOAD_ATTR_METHOD_NO_DICT); + _py_set_opocde(instr, LOAD_ATTR_METHOD_NO_DICT); break; case MANAGED_VALUES: - _Py_SET_OPCODE(*instr, LOAD_ATTR_METHOD_WITH_VALUES); + _py_set_opocde(instr, LOAD_ATTR_METHOD_WITH_VALUES); break; case MANAGED_DICT: SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_HAS_MANAGED_DICT); goto fail; case OFFSET_DICT: assert(owner_cls->tp_dictoffset > 0 && owner_cls->tp_dictoffset <= INT16_MAX); - _Py_SET_OPCODE(*instr, LOAD_ATTR_METHOD_WITH_DICT); + _py_set_opocde(instr, LOAD_ATTR_METHOD_WITH_DICT); break; case LAZY_DICT: assert(owner_cls->tp_dictoffset > 0 && owner_cls->tp_dictoffset <= INT16_MAX); - _Py_SET_OPCODE(*instr, LOAD_ATTR_METHOD_LAZY_DICT); + _py_set_opocde(instr, LOAD_ATTR_METHOD_LAZY_DICT); break; } /* `descr` is borrowed. This is safe for methods (even inherited ones from @@ -1114,7 +1114,7 @@ _Py_Specialize_LoadGlobal( } cache->index = (uint16_t)index; write_u32(cache->module_keys_version, keys_version); - _Py_SET_OPCODE(*instr, LOAD_GLOBAL_MODULE); + _py_set_opocde(instr, LOAD_GLOBAL_MODULE); goto success; } if (!PyDict_CheckExact(builtins)) { @@ -1150,12 +1150,12 @@ _Py_Specialize_LoadGlobal( cache->index = (uint16_t)index; write_u32(cache->module_keys_version, globals_version); cache->builtin_keys_version = (uint16_t)builtins_version; - _Py_SET_OPCODE(*instr, LOAD_GLOBAL_BUILTIN); + _py_set_opocde(instr, LOAD_GLOBAL_BUILTIN); goto success; fail: STAT_INC(LOAD_GLOBAL, failure); assert(!PyErr_Occurred()); - _Py_SET_OPCODE(*instr, LOAD_GLOBAL); + _py_set_opocde(instr, LOAD_GLOBAL); cache->counter = adaptive_counter_backoff(cache->counter); return; success: @@ -1259,7 +1259,7 @@ _Py_Specialize_BinarySubscr( PyTypeObject *container_type = Py_TYPE(container); if (container_type == &PyList_Type) { if (PyLong_CheckExact(sub)) { - _Py_SET_OPCODE(*instr, BINARY_SUBSCR_LIST_INT); + _py_set_opocde(instr, BINARY_SUBSCR_LIST_INT); goto success; } SPECIALIZATION_FAIL(BINARY_SUBSCR, @@ -1268,7 +1268,7 @@ _Py_Specialize_BinarySubscr( } if (container_type == &PyTuple_Type) { if (PyLong_CheckExact(sub)) { - _Py_SET_OPCODE(*instr, BINARY_SUBSCR_TUPLE_INT); + _py_set_opocde(instr, BINARY_SUBSCR_TUPLE_INT); goto success; } SPECIALIZATION_FAIL(BINARY_SUBSCR, @@ -1276,7 +1276,7 @@ _Py_Specialize_BinarySubscr( goto fail; } if (container_type == &PyDict_Type) { - _Py_SET_OPCODE(*instr, BINARY_SUBSCR_DICT); + _py_set_opocde(instr, BINARY_SUBSCR_DICT); goto success; } PyTypeObject *cls = Py_TYPE(container); @@ -1307,7 +1307,7 @@ _Py_Specialize_BinarySubscr( } cache->func_version = version; ((PyHeapTypeObject *)container_type)->_spec_cache.getitem = descriptor; - _Py_SET_OPCODE(*instr, BINARY_SUBSCR_GETITEM); + _py_set_opocde(instr, BINARY_SUBSCR_GETITEM); goto success; } SPECIALIZATION_FAIL(BINARY_SUBSCR, @@ -1315,7 +1315,7 @@ _Py_Specialize_BinarySubscr( fail: STAT_INC(BINARY_SUBSCR, failure); assert(!PyErr_Occurred()); - _Py_SET_OPCODE(*instr, BINARY_SUBSCR); + _py_set_opocde(instr, BINARY_SUBSCR); cache->counter = adaptive_counter_backoff(cache->counter); return; success: @@ -1334,7 +1334,7 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins if ((Py_SIZE(sub) == 0 || Py_SIZE(sub) == 1) && ((PyLongObject *)sub)->ob_digit[0] < (size_t)PyList_GET_SIZE(container)) { - _Py_SET_OPCODE(*instr, STORE_SUBSCR_LIST_INT); + _py_set_opocde(instr, STORE_SUBSCR_LIST_INT); goto success; } else { @@ -1352,7 +1352,7 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins } } if (container_type == &PyDict_Type) { - _Py_SET_OPCODE(*instr, STORE_SUBSCR_DICT); + _py_set_opocde(instr, STORE_SUBSCR_DICT); goto success; } #ifdef Py_STATS @@ -1419,7 +1419,7 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins fail: STAT_INC(STORE_SUBSCR, failure); assert(!PyErr_Occurred()); - _Py_SET_OPCODE(*instr, STORE_SUBSCR); + _py_set_opocde(instr, STORE_SUBSCR); cache->counter = adaptive_counter_backoff(cache->counter); return; success: @@ -1441,20 +1441,20 @@ specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, int oparg = _Py_OPARG(*instr); if (nargs == 1 && kwnames == NULL && oparg == 1) { if (tp == &PyUnicode_Type) { - _Py_SET_OPCODE(*instr, CALL_NO_KW_STR_1); + _py_set_opocde(instr, CALL_NO_KW_STR_1); return 0; } else if (tp == &PyType_Type) { - _Py_SET_OPCODE(*instr, CALL_NO_KW_TYPE_1); + _py_set_opocde(instr, CALL_NO_KW_TYPE_1); return 0; } else if (tp == &PyTuple_Type) { - _Py_SET_OPCODE(*instr, CALL_NO_KW_TUPLE_1); + _py_set_opocde(instr, CALL_NO_KW_TUPLE_1); return 0; } } if (tp->tp_vectorcall != NULL) { - _Py_SET_OPCODE(*instr, CALL_BUILTIN_CLASS); + _py_set_opocde(instr, CALL_BUILTIN_CLASS); return 0; } SPECIALIZATION_FAIL(CALL, tp == &PyUnicode_Type ? @@ -1506,7 +1506,7 @@ specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr, SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); return -1; } - _Py_SET_OPCODE(*instr, CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS); + _py_set_opocde(instr, CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS); return 0; } case METH_O: { @@ -1520,18 +1520,18 @@ specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr, bool pop = (_Py_OPCODE(next) == POP_TOP); int oparg = _Py_OPARG(*instr); if ((PyObject *)descr == list_append && oparg == 1 && pop) { - _Py_SET_OPCODE(*instr, CALL_NO_KW_LIST_APPEND); + _py_set_opocde(instr, CALL_NO_KW_LIST_APPEND); return 0; } - _Py_SET_OPCODE(*instr, CALL_NO_KW_METHOD_DESCRIPTOR_O); + _py_set_opocde(instr, CALL_NO_KW_METHOD_DESCRIPTOR_O); return 0; } case METH_FASTCALL: { - _Py_SET_OPCODE(*instr, CALL_NO_KW_METHOD_DESCRIPTOR_FAST); + _py_set_opocde(instr, CALL_NO_KW_METHOD_DESCRIPTOR_FAST); return 0; } case METH_FASTCALL|METH_KEYWORDS: { - _Py_SET_OPCODE(*instr, CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS); + _py_set_opocde(instr, CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS); return 0; } } @@ -1582,14 +1582,14 @@ specialize_py_call(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs, write_u32(cache->func_version, version); cache->min_args = min_args; if (argcount == nargs) { - _Py_SET_OPCODE(*instr, bound_method ? CALL_BOUND_METHOD_EXACT_ARGS : CALL_PY_EXACT_ARGS); + _py_set_opocde(instr, bound_method ? CALL_BOUND_METHOD_EXACT_ARGS : CALL_PY_EXACT_ARGS); } else if (bound_method) { SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_BOUND_METHOD); return -1; } else { - _Py_SET_OPCODE(*instr, CALL_PY_WITH_DEFAULTS); + _py_set_opocde(instr, CALL_PY_WITH_DEFAULTS); } return 0; } @@ -1616,10 +1616,10 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, /* len(o) */ PyInterpreterState *interp = _PyInterpreterState_GET(); if (callable == interp->callable_cache.len) { - _Py_SET_OPCODE(*instr, CALL_NO_KW_LEN); + _py_set_opocde(instr, CALL_NO_KW_LEN); return 0; } - _Py_SET_OPCODE(*instr, CALL_NO_KW_BUILTIN_O); + _py_set_opocde(instr, CALL_NO_KW_BUILTIN_O); return 0; } case METH_FASTCALL: { @@ -1631,15 +1631,15 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, /* isinstance(o1, o2) */ PyInterpreterState *interp = _PyInterpreterState_GET(); if (callable == interp->callable_cache.isinstance) { - _Py_SET_OPCODE(*instr, CALL_NO_KW_ISINSTANCE); + _py_set_opocde(instr, CALL_NO_KW_ISINSTANCE); return 0; } } - _Py_SET_OPCODE(*instr, CALL_NO_KW_BUILTIN_FAST); + _py_set_opocde(instr, CALL_NO_KW_BUILTIN_FAST); return 0; } case METH_FASTCALL | METH_KEYWORDS: { - _Py_SET_OPCODE(*instr, CALL_BUILTIN_FAST_WITH_KEYWORDS); + _py_set_opocde(instr, CALL_BUILTIN_FAST_WITH_KEYWORDS); return 0; } default: @@ -1732,7 +1732,7 @@ _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, if (fail) { STAT_INC(CALL, failure); assert(!PyErr_Occurred()); - _Py_SET_OPCODE(*instr, CALL); + _py_set_opocde(instr, CALL); cache->counter = adaptive_counter_backoff(cache->counter); } else { @@ -1829,18 +1829,18 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, bool to_store = (_Py_OPCODE(next) == STORE_FAST || _Py_OPCODE(next) == STORE_FAST__LOAD_FAST); if (to_store && locals[_Py_OPARG(next)] == lhs) { - _Py_SET_OPCODE(*instr, BINARY_OP_INPLACE_ADD_UNICODE); + _py_set_opocde(instr, BINARY_OP_INPLACE_ADD_UNICODE); goto success; } - _Py_SET_OPCODE(*instr, BINARY_OP_ADD_UNICODE); + _py_set_opocde(instr, BINARY_OP_ADD_UNICODE); goto success; } if (PyLong_CheckExact(lhs)) { - _Py_SET_OPCODE(*instr, BINARY_OP_ADD_INT); + _py_set_opocde(instr, BINARY_OP_ADD_INT); goto success; } if (PyFloat_CheckExact(lhs)) { - _Py_SET_OPCODE(*instr, BINARY_OP_ADD_FLOAT); + _py_set_opocde(instr, BINARY_OP_ADD_FLOAT); goto success; } break; @@ -1850,11 +1850,11 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, break; } if (PyLong_CheckExact(lhs)) { - _Py_SET_OPCODE(*instr, BINARY_OP_MULTIPLY_INT); + _py_set_opocde(instr, BINARY_OP_MULTIPLY_INT); goto success; } if (PyFloat_CheckExact(lhs)) { - _Py_SET_OPCODE(*instr, BINARY_OP_MULTIPLY_FLOAT); + _py_set_opocde(instr, BINARY_OP_MULTIPLY_FLOAT); goto success; } break; @@ -1864,18 +1864,18 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, break; } if (PyLong_CheckExact(lhs)) { - _Py_SET_OPCODE(*instr, BINARY_OP_SUBTRACT_INT); + _py_set_opocde(instr, BINARY_OP_SUBTRACT_INT); goto success; } if (PyFloat_CheckExact(lhs)) { - _Py_SET_OPCODE(*instr, BINARY_OP_SUBTRACT_FLOAT); + _py_set_opocde(instr, BINARY_OP_SUBTRACT_FLOAT); goto success; } break; } SPECIALIZATION_FAIL(BINARY_OP, binary_op_fail_kind(oparg, lhs, rhs)); STAT_INC(BINARY_OP, failure); - _Py_SET_OPCODE(*instr, BINARY_OP); + _py_set_opocde(instr, BINARY_OP); cache->counter = adaptive_counter_backoff(cache->counter); return; success: @@ -1957,13 +1957,13 @@ _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, goto failure; } if (PyFloat_CheckExact(lhs)) { - _Py_SET_OPCODE(*instr, COMPARE_OP_FLOAT_JUMP); + _py_set_opocde(instr, COMPARE_OP_FLOAT_JUMP); cache->mask = when_to_jump_mask; goto success; } if (PyLong_CheckExact(lhs)) { if (Py_ABS(Py_SIZE(lhs)) <= 1 && Py_ABS(Py_SIZE(rhs)) <= 1) { - _Py_SET_OPCODE(*instr, COMPARE_OP_INT_JUMP); + _py_set_opocde(instr, COMPARE_OP_INT_JUMP); cache->mask = when_to_jump_mask; goto success; } @@ -1978,7 +1978,7 @@ _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, goto failure; } else { - _Py_SET_OPCODE(*instr, COMPARE_OP_STR_JUMP); + _py_set_opocde(instr, COMPARE_OP_STR_JUMP); cache->mask = (when_to_jump_mask & 2) == 0; goto success; } @@ -1986,7 +1986,7 @@ _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, SPECIALIZATION_FAIL(COMPARE_OP, compare_op_fail_kind(lhs, rhs)); failure: STAT_INC(COMPARE_OP, failure); - _Py_SET_OPCODE(*instr, COMPARE_OP); + _py_set_opocde(instr, COMPARE_OP); cache->counter = adaptive_counter_backoff(cache->counter); return; success: @@ -2020,10 +2020,10 @@ _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, int oparg) goto failure; } if (PyTuple_GET_SIZE(seq) == 2) { - _Py_SET_OPCODE(*instr, UNPACK_SEQUENCE_TWO_TUPLE); + _py_set_opocde(instr, UNPACK_SEQUENCE_TWO_TUPLE); goto success; } - _Py_SET_OPCODE(*instr, UNPACK_SEQUENCE_TUPLE); + _py_set_opocde(instr, UNPACK_SEQUENCE_TUPLE); goto success; } if (PyList_CheckExact(seq)) { @@ -2031,13 +2031,13 @@ _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, int oparg) SPECIALIZATION_FAIL(UNPACK_SEQUENCE, SPEC_FAIL_EXPECTED_ERROR); goto failure; } - _Py_SET_OPCODE(*instr, UNPACK_SEQUENCE_LIST); + _py_set_opocde(instr, UNPACK_SEQUENCE_LIST); goto success; } SPECIALIZATION_FAIL(UNPACK_SEQUENCE, unpack_sequence_fail_kind(seq)); failure: STAT_INC(UNPACK_SEQUENCE, failure); - _Py_SET_OPCODE(*instr, UNPACK_SEQUENCE); + _py_set_opocde(instr, UNPACK_SEQUENCE); cache->counter = adaptive_counter_backoff(cache->counter); return; success: @@ -2126,26 +2126,26 @@ _Py_Specialize_ForIter(PyObject *iter, _Py_CODEUNIT *instr, int oparg) _Py_CODEUNIT next = instr[1+INLINE_CACHE_ENTRIES_FOR_ITER]; int next_op = _PyOpcode_Deopt[_Py_OPCODE(next)]; if (tp == &PyListIter_Type) { - _Py_SET_OPCODE(*instr, FOR_ITER_LIST); + _py_set_opocde(instr, FOR_ITER_LIST); goto success; } else if (tp == &PyTupleIter_Type) { - _Py_SET_OPCODE(*instr, FOR_ITER_TUPLE); + _py_set_opocde(instr, FOR_ITER_TUPLE); goto success; } else if (tp == &PyRangeIter_Type && next_op == STORE_FAST) { - _Py_SET_OPCODE(*instr, FOR_ITER_RANGE); + _py_set_opocde(instr, FOR_ITER_RANGE); goto success; } else if (tp == &PyGen_Type && oparg <= SHRT_MAX) { assert(_Py_OPCODE(instr[oparg + INLINE_CACHE_ENTRIES_FOR_ITER + 1]) == END_FOR); - _Py_SET_OPCODE(*instr, FOR_ITER_GEN); + _py_set_opocde(instr, FOR_ITER_GEN); goto success; } SPECIALIZATION_FAIL(FOR_ITER, _PySpecialization_ClassifyIterator(iter)); STAT_INC(FOR_ITER, failure); - _Py_SET_OPCODE(*instr, FOR_ITER); + _py_set_opocde(instr, FOR_ITER); cache->counter = adaptive_counter_backoff(cache->counter); return; success: diff --git a/Tools/cases_generator/generate_cases.py b/Tools/cases_generator/generate_cases.py index 5930c79..2dfc76f 100644 --- a/Tools/cases_generator/generate_cases.py +++ b/Tools/cases_generator/generate_cases.py @@ -205,7 +205,7 @@ class Instruction: else: typ = f"uint{bits}_t " func = f"read_u{bits}" - out.emit(f"{typ}{ceffect.name} = {func}(next_instr + {cache_offset});") + out.emit(f"{typ}{ceffect.name} = {func}(&next_instr[{cache_offset}].cache);") cache_offset += ceffect.size assert cache_offset == self.cache_offset + cache_adjust |