mirror of
https://github.com/python/cpython.git
synced 2025-08-22 17:55:18 +00:00
GH-100288: Specialize LOAD_ATTR for simple class attributes. (#105990)
* Add two more specializations of LOAD_ATTR.
This commit is contained in:
parent
34c14147a2
commit
0c90e75610
10 changed files with 405 additions and 290 deletions
|
@ -1809,6 +1809,8 @@ dummy_func(
|
|||
LOAD_ATTR_METHOD_WITH_VALUES,
|
||||
LOAD_ATTR_METHOD_NO_DICT,
|
||||
LOAD_ATTR_METHOD_LAZY_DICT,
|
||||
LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES,
|
||||
LOAD_ATTR_NONDESCRIPTOR_NO_DICT,
|
||||
};
|
||||
|
||||
inst(LOAD_ATTR, (unused/9, owner -- res2 if (oparg & 1), res)) {
|
||||
|
@ -2657,7 +2659,8 @@ dummy_func(
|
|||
exc_info->exc_value = Py_NewRef(new_exc);
|
||||
}
|
||||
|
||||
inst(LOAD_ATTR_METHOD_WITH_VALUES, (unused/1, type_version/2, keys_version/2, descr/4, self -- res2 if (oparg & 1), res)) {
|
||||
inst(LOAD_ATTR_METHOD_WITH_VALUES, (unused/1, type_version/2, keys_version/2, descr/4, self -- res2 if (1), res)) {
|
||||
assert(oparg & 1);
|
||||
/* Cached method object */
|
||||
PyTypeObject *self_cls = Py_TYPE(self);
|
||||
assert(type_version != 0);
|
||||
|
@ -2673,10 +2676,10 @@ dummy_func(
|
|||
res2 = Py_NewRef(descr);
|
||||
assert(_PyType_HasFeature(Py_TYPE(res2), Py_TPFLAGS_METHOD_DESCRIPTOR));
|
||||
res = self;
|
||||
assert(oparg & 1);
|
||||
}
|
||||
|
||||
inst(LOAD_ATTR_METHOD_NO_DICT, (unused/1, type_version/2, unused/2, descr/4, self -- res2 if (oparg & 1), res)) {
|
||||
inst(LOAD_ATTR_METHOD_NO_DICT, (unused/1, type_version/2, unused/2, descr/4, self -- res2 if (1), res)) {
|
||||
assert(oparg & 1);
|
||||
PyTypeObject *self_cls = Py_TYPE(self);
|
||||
DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR);
|
||||
assert(self_cls->tp_dictoffset == 0);
|
||||
|
@ -2685,10 +2688,39 @@ dummy_func(
|
|||
assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
|
||||
res2 = Py_NewRef(descr);
|
||||
res = self;
|
||||
assert(oparg & 1);
|
||||
}
|
||||
|
||||
inst(LOAD_ATTR_METHOD_LAZY_DICT, (unused/1, type_version/2, unused/2, descr/4, self -- res2 if (oparg & 1), res)) {
|
||||
inst(LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, (unused/1, type_version/2, keys_version/2, descr/4, self -- res2 if (0), res)) {
|
||||
assert((oparg & 1) == 0);
|
||||
PyTypeObject *self_cls = Py_TYPE(self);
|
||||
assert(type_version != 0);
|
||||
DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR);
|
||||
assert(self_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT);
|
||||
PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(self);
|
||||
DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR);
|
||||
PyHeapTypeObject *self_heap_type = (PyHeapTypeObject *)self_cls;
|
||||
DEOPT_IF(self_heap_type->ht_cached_keys->dk_version !=
|
||||
keys_version, LOAD_ATTR);
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
assert(descr != NULL);
|
||||
DECREF_INPUTS();
|
||||
res = Py_NewRef(descr);
|
||||
}
|
||||
|
||||
inst(LOAD_ATTR_NONDESCRIPTOR_NO_DICT, (unused/1, type_version/2, unused/2, descr/4, self -- res2 if (0), res)) {
|
||||
assert((oparg & 1) == 0);
|
||||
PyTypeObject *self_cls = Py_TYPE(self);
|
||||
assert(type_version != 0);
|
||||
DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR);
|
||||
assert(self_cls->tp_dictoffset == 0);
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
assert(descr != NULL);
|
||||
DECREF_INPUTS();
|
||||
res = Py_NewRef(descr);
|
||||
}
|
||||
|
||||
inst(LOAD_ATTR_METHOD_LAZY_DICT, (unused/1, type_version/2, unused/2, descr/4, self -- res2 if (1), res)) {
|
||||
assert(oparg & 1);
|
||||
PyTypeObject *self_cls = Py_TYPE(self);
|
||||
DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR);
|
||||
Py_ssize_t dictoffset = self_cls->tp_dictoffset;
|
||||
|
@ -2701,7 +2733,6 @@ dummy_func(
|
|||
assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR));
|
||||
res2 = Py_NewRef(descr);
|
||||
res = self;
|
||||
assert(oparg & 1);
|
||||
}
|
||||
|
||||
inst(KW_NAMES, (--)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue