Bug 1456035: Part 2 - Add fast path for XPCWrappedJS QueryInterface with native helper. r=mccr8

When the QueryInterface method for an XPCWrappedJS class is implemented by the
native helper, we can avoid a lot of overhead by simply asking it if it
supports a given interface rather than going through all of the JSAPI call and
exception handling overhead we'd need otherwise.

MozReview-Commit-ID: FVAN3oYRE9I

--HG--
extra : rebase_source : 23a42374e83ee4314fa89ead135fd2e8f9968296
This commit is contained in:
Kris Maglione 2018-04-22 20:37:51 -07:00
Родитель dc8ba3688b
Коммит 8b53374e1d
1 изменённых файлов: 12 добавлений и 5 удалений

Просмотреть файл

@ -20,6 +20,7 @@
#include "mozilla/dom/DOMException.h" #include "mozilla/dom/DOMException.h"
#include "mozilla/dom/DOMExceptionBinding.h" #include "mozilla/dom/DOMExceptionBinding.h"
#include "mozilla/dom/DOMPrefs.h" #include "mozilla/dom/DOMPrefs.h"
#include "mozilla/dom/MozQueryInterface.h"
#include "mozilla/jsipc/CrossProcessObjectWrappers.h" #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
#include "jsapi.h" #include "jsapi.h"
@ -232,8 +233,14 @@ nsXPCWrappedJSClass::CallQueryInterfaceOnJSObject(JSContext* cx,
} }
} }
id = xpc_NewIDObject(cx, jsobj, aIID); dom::MozQueryInterface* mozQI = nullptr;
if (id) { if (NS_SUCCEEDED(UNWRAP_OBJECT(MozQueryInterface, &fun, mozQI))) {
if (mozQI->QueriesTo(aIID))
return jsobj.get();
return nullptr;
}
if ((id = xpc_NewIDObject(cx, jsobj, aIID))) {
// Throwing NS_NOINTERFACE is the prescribed way to fail QI from JS. It // Throwing NS_NOINTERFACE is the prescribed way to fail QI from JS. It
// is not an exception that is ever worth reporting, but we don't want // is not an exception that is ever worth reporting, but we don't want
// to eat all exceptions either. // to eat all exceptions either.
@ -275,10 +282,10 @@ nsXPCWrappedJSClass::CallQueryInterfaceOnJSObject(JSContext* cx,
} else if (!success) { } else if (!success) {
NS_WARNING("QI hook ran OOMed - this is probably a bug!"); NS_WARNING("QI hook ran OOMed - this is probably a bug!");
} }
}
if (success) if (success)
success = JS_ValueToObject(cx, retval, &retObj); success = JS_ValueToObject(cx, retval, &retObj);
}
return success ? retObj.get() : nullptr; return success ? retObj.get() : nullptr;
} }