mirror of
https://github.com/python/cpython.git
synced 2025-08-28 20:56:54 +00:00
bpo-45107: Specialize LOAD_METHOD
for instances with dict. (GH-31531)
This commit is contained in:
parent
4dc746310b
commit
2a6ece572c
7 changed files with 143 additions and 66 deletions
|
@ -4424,7 +4424,7 @@ handle_eval_breaker:
|
|||
}
|
||||
}
|
||||
|
||||
TARGET(LOAD_METHOD_CACHED) {
|
||||
TARGET(LOAD_METHOD_WITH_VALUES) {
|
||||
/* LOAD_METHOD, with cached method object */
|
||||
assert(cframe.use_tracing == 0);
|
||||
PyObject *self = TOP();
|
||||
|
@ -4432,7 +4432,7 @@ handle_eval_breaker:
|
|||
SpecializedCacheEntry *caches = GET_CACHE();
|
||||
_PyAttrCache *cache1 = &caches[-1].attr;
|
||||
_PyObjectCache *cache2 = &caches[-2].obj;
|
||||
|
||||
assert(cache1->tp_version != 0);
|
||||
DEOPT_IF(self_cls->tp_version_tag != cache1->tp_version, LOAD_METHOD);
|
||||
assert(self_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT);
|
||||
PyDictObject *dict = *(PyDictObject**)_PyObject_ManagedDictPointer(self);
|
||||
|
@ -4448,6 +4448,38 @@ handle_eval_breaker:
|
|||
NOTRACE_DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(LOAD_METHOD_WITH_DICT) {
|
||||
/* LOAD_METHOD, with a dict
|
||||
Can be either a managed dict, or a tp_dictoffset offset.*/
|
||||
assert(cframe.use_tracing == 0);
|
||||
PyObject *self = TOP();
|
||||
PyTypeObject *self_cls = Py_TYPE(self);
|
||||
SpecializedCacheEntry *caches = GET_CACHE();
|
||||
_PyAdaptiveEntry *cache0 = &caches[0].adaptive;
|
||||
_PyAttrCache *cache1 = &caches[-1].attr;
|
||||
_PyObjectCache *cache2 = &caches[-2].obj;
|
||||
|
||||
DEOPT_IF(self_cls->tp_version_tag != cache1->tp_version, LOAD_METHOD);
|
||||
/* Treat index as a signed 16 bit value */
|
||||
int dictoffset = *(int16_t *)&cache0->index;
|
||||
PyDictObject **dictptr = (PyDictObject**)(((char *)self)+dictoffset);
|
||||
assert(
|
||||
dictoffset == MANAGED_DICT_OFFSET ||
|
||||
(dictoffset == self_cls->tp_dictoffset && dictoffset > 0)
|
||||
);
|
||||
PyDictObject *dict = *dictptr;
|
||||
DEOPT_IF(dict == NULL, LOAD_METHOD);
|
||||
DEOPT_IF(dict->ma_keys->dk_version != cache1->dk_version, LOAD_METHOD);
|
||||
STAT_INC(LOAD_METHOD, hit);
|
||||
PyObject *res = cache2->obj;
|
||||
assert(res != NULL);
|
||||
assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR));
|
||||
Py_INCREF(res);
|
||||
SET_TOP(res);
|
||||
PUSH(self);
|
||||
NOTRACE_DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(LOAD_METHOD_NO_DICT) {
|
||||
assert(cframe.use_tracing == 0);
|
||||
PyObject *self = TOP();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue