Commit 4008df8e authored by Kevin Modzelewski's avatar Kevin Modzelewski

Improve exception-matching speed

- Add a has_subclasscheck class slot
- Add a fast path for when the exception matches exactly (though
  we have to check that there isn't a metaclass involved first).
parent 527b1694
......@@ -797,8 +797,15 @@ extern "C" int PyObject_IsSubclass(PyObject* derived, PyObject* cls) noexcept {
return r;
}
if (!(PyClass_Check(cls) || PyInstance_Check(cls))) {
PyObject* checker;
checker = _PyObject_LookupSpecial(cls, "__subclasscheck__", &name);
PyObject* checker = NULL;
if (cls->cls->has_subclasscheck) {
checker = _PyObject_LookupSpecial(cls, "__subclasscheck__", &name);
if (!checker && PyErr_Occurred())
return -1;
assert(checker);
}
if (checker != NULL) {
PyObject* res;
int ok = -1;
......
......@@ -1645,6 +1645,7 @@ static slotdef slotdefs[]
TPSLOT("__del__", tp_del, slot_tp_del, NULL, ""),
FLSLOT("__class__", has___class__, NULL, NULL, "", PyWrapperFlag_BOOL),
FLSLOT("__instancecheck__", has_instancecheck, NULL, NULL, "", PyWrapperFlag_BOOL),
FLSLOT("__subclasscheck__", has_subclasscheck, NULL, NULL, "", PyWrapperFlag_BOOL),
FLSLOT("__getattribute__", has_getattribute, NULL, NULL, "", PyWrapperFlag_BOOL),
TPPSLOT("__hasnext__", tpp_hasnext, slotTppHasnext, wrapInquirypred, "hasnext"),
......
......@@ -984,6 +984,13 @@ extern "C" int PyErr_GivenExceptionMatches(PyObject* err, PyObject* exc) noexcep
err = PyExceptionInstance_Class(err);
if (PyExceptionClass_Check(err) && PyExceptionClass_Check(exc)) {
// Pyston addition: fast-path the check for if the exception exactly-matches the specifier.
// Note that we have to check that the exception specifier doesn't have a custom metaclass
// (ie it's cls is type_cls), since otherwise we would have to check for subclasscheck overloading.
// (TODO actually, that should be fast now)
if (exc->cls == type_cls && exc == err)
return 1;
int res = 0, reclimit;
PyObject* exception, *value, *tb;
PyErr_Fetch(&exception, &value, &tb);
......
......@@ -232,6 +232,7 @@ public:
bool has___class__; // Has a custom __class__ attribute (ie different from object's __class__ descriptor)
bool has_instancecheck;
bool has_subclasscheck;
bool has_getattribute;
typedef bool (*pyston_inquiry)(Box*);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment