-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
bpo-44889: Specialize LOAD_METHOD with PEP 659 adaptive interpreter #27722
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
60ab351
e0f7ebe
ffd7ff3
2b014a2
b200887
d977986
187fddb
c71f142
f3082f4
0f32d60
8a31db3
06d606e
608f6d0
1f5e64a
29daf44
a3d6dd3
d7ee4ac
c944af0
2f5cc63
70ad1ea
f4487fc
afcf51e
e551d7a
6f1f1f0
dc152ed
dd77f75
601e9b8
94b6106
1d87e53
3697d4f
1d83667
5db1d3b
d12205b
8af701d
ad4ff6e
a3d1b50
d8384bc
ae2a520
a12406b
33445d5
6d806a2
020a326
d27e388
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -700,17 +700,18 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, | |
SPECIALIZATION_FAIL(LOAD_METHOD, owner_cls, name, "not a method"); | ||
goto fail; | ||
} | ||
if (owner_cls->tp_dictoffset > 0) { | ||
PyObject **cls_dictptr = _PyObject_GetDictPtr((PyObject *)owner_cls); | ||
if (cls_dictptr == NULL || *cls_dictptr == NULL || | ||
!PyDict_CheckExact(*cls_dictptr)) { | ||
// Maybe a builtin type | ||
SPECIALIZATION_FAIL(LOAD_METHOD, owner_cls, name, | ||
"cls no dict or not a dict"); | ||
goto fail; | ||
} | ||
PyObject **cls_dictptr = _PyObject_GetDictPtr((PyObject *)owner_cls); | ||
Fidget-Spinner marked this conversation as resolved.
Show resolved
Hide resolved
|
||
int cls_has_dict = (cls_dictptr != NULL && | ||
*cls_dictptr != NULL && | ||
PyDict_CheckExact(*cls_dictptr)); | ||
PyObject **owner_dictptr = _PyObject_GetDictPtr(owner); | ||
int owner_has_dict = (owner_dictptr != NULL && | ||
*owner_dictptr != NULL && | ||
!PyDict_CheckExact(*owner_dictptr)); | ||
PyDictObject *cls_dict = cls_has_dict ? (PyDictObject *)*cls_dictptr : NULL; | ||
PyDictObject *owner_dict = owner_has_dict ? (PyDictObject *)*owner_dictptr : NULL; | ||
if (owner_cls->tp_dictoffset >= 0 && cls_has_dict) { | ||
// We found a type with a __dict__. | ||
PyDictObject *cls_dict = (PyDictObject *)*cls_dictptr; | ||
if ((owner_cls->tp_flags & Py_TPFLAGS_HEAPTYPE) | ||
&& cls_dict->ma_keys == ((PyHeapTypeObject*)owner_cls)->ht_cached_keys) { | ||
// Keys are shared. Rare for LOAD_METHOD. | ||
|
@@ -719,12 +720,9 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, | |
} | ||
|
||
// if o.__dict__ changes, the method might be found in o.__dict__ | ||
// instead of type lookup. So record o.__dict__. | ||
PyObject **owner_dictptr = _PyObject_GetDictPtr(owner); | ||
// instead of old type lookup. So record o.__dict__. | ||
uint32_t keys_version = UINT32_MAX; | ||
// o.__dict__ exists | ||
if (*owner_dictptr != NULL && !PyDict_CheckExact(*owner_dictptr)) { | ||
PyDictObject *owner_dict = (PyDictObject *)*owner_dictptr; | ||
if (owner_has_dict) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code looks similar to the code for checking indexes for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought so too, but upon inspection, the similarity is skin deep. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The specializer shouldn't care whether the If we factor out the code that determines if the class has cached keys and the index of the name: The problem is that there is no API for determining the index of a key in a dictionary-keys, only in a dictionary. |
||
// check if its an attr | ||
int is_attr = PyDict_Contains((PyObject *)owner_dict, name); | ||
if (is_attr < 0) { | ||
|
@@ -757,19 +755,6 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, | |
goto success; | ||
|
||
} | ||
#if SPECIALIZATION_STATS | ||
else if (owner_cls->tp_dictoffset == 0) { | ||
PyObject **owner_dictptr = _PyObject_GetDictPtr(owner); | ||
if (owner_dictptr == NULL || | ||
*owner_dictptr == NULL || | ||
!PyDict_CheckExact(*owner_dictptr)) { | ||
SPECIALIZATION_FAIL(LOAD_METHOD, owner_cls, name, "builtin no dict"); | ||
goto fail; | ||
} | ||
SPECIALIZATION_FAIL(LOAD_METHOD, owner_cls, name, "builtin with dict"); | ||
goto fail; | ||
} | ||
#endif | ||
fail: | ||
STAT_INC(LOAD_METHOD, specialization_failure); | ||
assert(!PyErr_Occurred()); | ||
|
Uh oh!
There was an error while loading. Please reload this page.