diff options
Diffstat (limited to 'Python')
-rw-r--r-- | Python/bytecodes.c | 19 | ||||
-rw-r--r-- | Python/executor_cases.c.h | 18 | ||||
-rw-r--r-- | Python/generated_cases.c.h | 59 |
3 files changed, 72 insertions, 24 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 18862f8..176dbb5 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1816,14 +1816,21 @@ dummy_func( LOAD_ATTR, }; - inst(LOAD_ATTR_INSTANCE_VALUE, (unused/1, type_version/2, index/1, unused/5, owner -- res2 if (oparg & 1), res)) { + op(_GUARD_TYPE_VERSION, (type_version/2, owner -- owner)) { PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); - assert(tp->tp_dictoffset < 0); - assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + } + + op(_CHECK_MANAGED_OBJECT_HAS_VALUES, (owner -- owner)) { + assert(Py_TYPE(owner)->tp_dictoffset < 0); + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + } + + op(_LOAD_ATTR_INSTANCE_VALUE, (index/1, unused/5, owner -- res2 if (oparg & 1), res)) { + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); res = _PyDictOrValues_GetValues(dorv)->values[index]; DEOPT_IF(res == NULL, LOAD_ATTR); STAT_INC(LOAD_ATTR, hit); @@ -1832,6 +1839,12 @@ dummy_func( DECREF_INPUTS(); } + macro(LOAD_ATTR_INSTANCE_VALUE) = + _SKIP_CACHE + // Skip over the counter + _GUARD_TYPE_VERSION + + _CHECK_MANAGED_OBJECT_HAS_VALUES + + _LOAD_ATTR_INSTANCE_VALUE; + inst(LOAD_ATTR_MODULE, (unused/1, type_version/2, index/1, unused/5, owner -- res2 if (oparg & 1), res)) { DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR); PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 2c2dbf4..805ea06 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -1425,6 +1425,24 @@ break; } + case _GUARD_TYPE_VERSION: { + PyObject *owner = stack_pointer[-1]; + uint32_t type_version = (uint32_t)operand; + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + break; + } + + case _CHECK_MANAGED_OBJECT_HAS_VALUES: { + PyObject *owner = stack_pointer[-1]; + assert(Py_TYPE(owner)->tp_dictoffset < 0); + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + break; + } + case COMPARE_OP: { static_assert(INLINE_CACHE_ENTRIES_COMPARE_OP == 1, "incorrect cache size"); PyObject *right = stack_pointer[-1]; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 383432f..d43c738 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -2240,28 +2240,45 @@ } TARGET(LOAD_ATTR_INSTANCE_VALUE) { - PyObject *owner = stack_pointer[-1]; - PyObject *res2 = NULL; - PyObject *res; - uint32_t type_version = read_u32(&next_instr[1].cache); - uint16_t index = read_u16(&next_instr[3].cache); - PyTypeObject *tp = Py_TYPE(owner); - assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); - assert(tp->tp_dictoffset < 0); - assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); - DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); - res = _PyDictOrValues_GetValues(dorv)->values[index]; - DEOPT_IF(res == NULL, LOAD_ATTR); - STAT_INC(LOAD_ATTR, hit); - Py_INCREF(res); - res2 = NULL; - Py_DECREF(owner); - STACK_GROW(((oparg & 1) ? 1 : 0)); - stack_pointer[-1] = res; - if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + PyObject *_tmp_1; + PyObject *_tmp_2 = stack_pointer[-1]; + { + } + { + PyObject *owner = _tmp_2; + uint32_t type_version = read_u32(&next_instr[1].cache); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + _tmp_2 = owner; + } + { + PyObject *owner = _tmp_2; + assert(Py_TYPE(owner)->tp_dictoffset < 0); + assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + _tmp_2 = owner; + } + { + PyObject *owner = _tmp_2; + PyObject *res2 = NULL; + PyObject *res; + uint16_t index = read_u16(&next_instr[3].cache); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + res = _PyDictOrValues_GetValues(dorv)->values[index]; + DEOPT_IF(res == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(res); + res2 = NULL; + Py_DECREF(owner); + if (oparg & 1) { _tmp_2 = res2; } + _tmp_1 = res; + } next_instr += 9; + STACK_GROW(((oparg & 1) ? 1 : 0)); + stack_pointer[-1] = _tmp_1; + if (oparg & 1) { stack_pointer[-2] = _tmp_2; } DISPATCH(); } |