--- /dev/null
+Relax optimization requirements to allow fast attribute access to module
+subclasses.
op(_CHECK_ATTR_MODULE, (dict_version/2, owner -- owner)) {
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
- DEOPT_IF(!PyModule_CheckExact(owner_o));
+ DEOPT_IF(Py_TYPE(owner_o)->tp_getattro != PyModule_Type.tp_getattro);
PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner_o)->md_dict;
assert(dict != NULL);
DEOPT_IF(dict->ma_keys->dk_version != dict_version);
owner = stack_pointer[-1];
uint32_t dict_version = (uint32_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
- if (!PyModule_CheckExact(owner_o)) {
+ if (Py_TYPE(owner_o)->tp_getattro != PyModule_Type.tp_getattro) {
UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET();
}
owner = stack_pointer[-1];
uint32_t dict_version = read_u32(&this_instr[2].cache);
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
- DEOPT_IF(!PyModule_CheckExact(owner_o), LOAD_ATTR);
+ DEOPT_IF(Py_TYPE(owner_o)->tp_getattro != PyModule_Type.tp_getattro, LOAD_ATTR);
PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner_o)->md_dict;
assert(dict != NULL);
DEOPT_IF(dict->ma_keys->dk_version != dict_version, LOAD_ATTR);
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OTHER);
fail = true;
}
- else if (PyModule_CheckExact(owner)) {
+ else if (Py_TYPE(owner)->tp_getattro == PyModule_Type.tp_getattro) {
fail = specialize_module_load_attr(owner, instr, name);
}
else if (PyType_Check(owner)) {