gh-87729: improve hit rate of LOAD_SUPER_ATTR specialization (#104270)

This commit is contained in:
Carl Meyer 2023-05-11 08:08:13 -06:00 committed by GitHub
parent ddc0e70a32
commit 77262458fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 374 additions and 352 deletions

View file

@ -1562,17 +1562,18 @@ dummy_func(
family(load_super_attr, INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR) = {
LOAD_SUPER_ATTR,
LOAD_SUPER_ATTR_ATTR,
LOAD_SUPER_ATTR_METHOD,
};
inst(LOAD_SUPER_ATTR, (unused/9, global_super, class, self -- res2 if (oparg & 1), res)) {
inst(LOAD_SUPER_ATTR, (unused/1, global_super, class, self -- res2 if (oparg & 1), res)) {
PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2);
int load_method = oparg & 1;
#if ENABLE_SPECIALIZATION
_PySuperAttrCache *cache = (_PySuperAttrCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
next_instr--;
_Py_Specialize_LoadSuperAttr(global_super, class, self, next_instr, name, load_method);
_Py_Specialize_LoadSuperAttr(global_super, class, next_instr, load_method);
DISPATCH_SAME_OPARG();
}
STAT_INC(LOAD_SUPER_ATTR, deferred);
@ -1590,17 +1591,38 @@ dummy_func(
ERROR_IF(res == NULL, error);
}
inst(LOAD_SUPER_ATTR_METHOD, (unused/1, class_version/2, self_type_version/2, method/4, global_super, class, self -- res2, res)) {
inst(LOAD_SUPER_ATTR_ATTR, (unused/1, global_super, class, self -- res2 if (oparg & 1), res)) {
assert(!(oparg & 1));
DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR);
DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR);
DEOPT_IF(((PyTypeObject *)class)->tp_version_tag != class_version, LOAD_SUPER_ATTR);
PyTypeObject *self_type = Py_TYPE(self);
DEOPT_IF(self_type->tp_version_tag != self_type_version, LOAD_SUPER_ATTR);
res2 = method;
res = self; // transfer ownership
Py_INCREF(res2);
STAT_INC(LOAD_SUPER_ATTR, hit);
PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2);
res = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL);
ERROR_IF(res == NULL, error);
DECREF_INPUTS();
}
inst(LOAD_SUPER_ATTR_METHOD, (unused/1, global_super, class, self -- res2, res)) {
assert(oparg & 1);
DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR);
DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR);
STAT_INC(LOAD_SUPER_ATTR, hit);
PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2);
int method_found = 0;
res2 = _PySuper_Lookup((PyTypeObject *)class, self, name, &method_found);
Py_DECREF(global_super);
Py_DECREF(class);
if (res2 == NULL) {
Py_DECREF(self);
ERROR_IF(true, error);
}
if (method_found) {
res = self; // transfer ownership
} else {
Py_DECREF(self);
res = res2;
res2 = NULL;
}
}
family(load_attr, INLINE_CACHE_ENTRIES_LOAD_ATTR) = {