Bug 1091964 - [e10s] Cache isCallable and isConstructor for CPOWs (r=mrbkap)

This commit is contained in:
Bill McCloskey 2014-11-04 17:39:34 -08:00
parent 131e9e4677
commit 713ddb6b94
7 changed files with 44 additions and 114 deletions

View File

@ -116,14 +116,6 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
return Answer::RecvDOMInstanceOf(ObjectId::deserialize(objId), prototypeID, depth, rs, instanceof);
}
bool RecvIsCallable(const uint64_t &objId, bool *result) {
return Answer::RecvIsCallable(ObjectId::deserialize(objId), result);
}
bool RecvIsConstructor(const uint64_t &objId, bool *result) {
return Answer::RecvIsConstructor(ObjectId::deserialize(objId), result);
}
bool RecvDropObject(const uint64_t &objId) {
return Answer::RecvDropObject(ObjectId::deserialize(objId));
}
@ -215,14 +207,6 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
return Base::SendDOMInstanceOf(objId.serialize(), prototypeID, depth, rs, instanceof);
}
bool SendIsCallable(const ObjectId &objId, bool *result) {
return Base::SendIsCallable(objId.serialize(), result);
}
bool SendIsConstructor(const ObjectId &objId, bool *result) {
return Base::SendIsConstructor(objId.serialize(), result);
}
/* The following code is needed to suppress a bogus MSVC warning (C4250). */
virtual bool toObjectVariant(JSContext *cx, JSObject *obj, ObjectVariant *objVarp) {

View File

@ -35,6 +35,8 @@ struct LocalObject
struct RemoteObject
{
uint64_t serializedId;
bool isCallable;
bool isConstructor;
};
union ObjectVariant

View File

@ -46,9 +46,6 @@ both:
prio(high) sync InstanceOf(uint64_t objId, JSIID iid) returns (ReturnStatus rs, bool instanceof);
prio(high) sync DOMInstanceOf(uint64_t objId, int prototypeID, int depth) returns (ReturnStatus rs, bool instanceof);
prio(high) sync IsCallable(uint64_t objId) returns (bool result);
prio(high) sync IsConstructor(uint64_t objId) returns (bool result);
parent:
async __delete__();
};

View File

@ -662,47 +662,6 @@ WrapperAnswer::RecvDOMInstanceOf(const ObjectId &objId, const int &prototypeID,
return ok(rs);
}
bool
WrapperAnswer::RecvIsCallable(const ObjectId &objId, bool *result)
{
AutoSafeJSContext cx;
JSAutoRequest request(cx);
RootedObject obj(cx, findObjectById(cx, objId));
if (!obj) {
// This is very unfortunate, but we have no choice.
*result = false;
return true;
}
JSAutoCompartment ac(cx, obj); // Not really necessary here, but be safe.
LOG("%s.isCallable()", ReceiverObj(objId));
*result = JS::IsCallable(obj);
return true;
}
bool
WrapperAnswer::RecvIsConstructor(const ObjectId &objId, bool *result)
{
AutoSafeJSContext cx;
JSAutoRequest request(cx);
RootedObject obj(cx, findObjectById(cx, objId));
if (!obj) {
// This is very unfortunate, but we have no choice.
*result = false;
return true;
}
JSAutoCompartment ac(cx, obj); // Not really necessary here, but be safe.
LOG("%s.isConstructor()", ReceiverObj(objId));
*result = JS::IsConstructor(obj);
return true;
}
bool
WrapperAnswer::RecvDropObject(const ObjectId &objId)
{

View File

@ -62,9 +62,6 @@ class WrapperAnswer : public virtual JavaScriptShared
bool RecvDOMInstanceOf(const ObjectId &objId, const int &prototypeID, const int &depth,
ReturnStatus *rs, bool *instanceof);
bool RecvIsCallable(const ObjectId &objId, bool *result);
bool RecvIsConstructor(const ObjectId &objId, bool *result);
bool RecvDropObject(const ObjectId &objId);
private:

View File

@ -18,12 +18,32 @@ using namespace JS;
using namespace mozilla;
using namespace mozilla::jsipc;
struct AuxCPOWData
{
ObjectId id;
bool isCallable;
bool isConstructor;
AuxCPOWData(ObjectId id, bool isCallable, bool isConstructor)
: id(id),
isCallable(isCallable),
isConstructor(isConstructor)
{}
};
WrapperOwner::WrapperOwner(JSRuntime *rt)
: JavaScriptShared(rt),
inactive_(false)
{
}
static inline AuxCPOWData *
AuxCPOWDataOf(JSObject *obj)
{
MOZ_ASSERT(IsCPOW(obj));
return static_cast<AuxCPOWData *>(GetProxyExtra(obj, 1).toPrivate());
}
static inline WrapperOwner *
OwnerOf(JSObject *obj)
{
@ -36,13 +56,9 @@ WrapperOwner::idOfUnchecked(JSObject *obj)
{
MOZ_ASSERT(IsCPOW(obj));
Value v = GetProxyExtra(obj, 1);
MOZ_ASSERT(v.isDouble());
ObjectId objId = ObjectId::deserialize(BitwiseCast<uint64_t>(v.toDouble()));
MOZ_ASSERT(!objId.isNull());
return objId;
AuxCPOWData *aux = AuxCPOWDataOf(obj);
MOZ_ASSERT(!aux->id.isNull());
return aux->id;
}
ObjectId
@ -689,6 +705,10 @@ void
CPOWProxyHandler::finalize(JSFreeOp *fop, JSObject *proxy) const
{
OwnerOf(proxy)->drop(proxy);
AuxCPOWData *aux = AuxCPOWDataOf(proxy);
if (aux)
delete aux;
}
void
@ -700,47 +720,15 @@ CPOWProxyHandler::objectMoved(JSObject *proxy, const JSObject *old) const
bool
CPOWProxyHandler::isCallable(JSObject *proxy) const
{
WrapperOwner *parent = OwnerOf(proxy);
if (!parent->active())
return false;
return parent->isCallable(proxy);
}
bool
WrapperOwner::isCallable(JSObject *obj)
{
ObjectId objId = idOf(obj);
bool callable = false;
if (!SendIsCallable(objId, &callable)) {
NS_WARNING("IPC isCallable() failed");
return false;
}
return callable;
AuxCPOWData *aux = AuxCPOWDataOf(proxy);
return aux->isCallable;
}
bool
CPOWProxyHandler::isConstructor(JSObject *proxy) const
{
WrapperOwner *parent = OwnerOf(proxy);
if (!parent->active())
return false;
return parent->isConstructor(proxy);
}
bool
WrapperOwner::isConstructor(JSObject *obj)
{
ObjectId objId = idOf(obj);
bool constructor = false;
if (!SendIsConstructor(objId, &constructor)) {
NS_WARNING("IPC isConstructor() failed");
return false;
}
return constructor;
AuxCPOWData *aux = AuxCPOWDataOf(proxy);
return aux->isConstructor;
}
void
@ -895,6 +883,12 @@ WrapperOwner::ok(JSContext *cx, const ReturnStatus &status)
return false;
}
static RemoteObject
MakeRemoteObject(ObjectId id, JSObject *obj)
{
return RemoteObject(id.serialize(), JS::IsCallable(obj), JS::IsConstructor(obj));
}
bool
WrapperOwner::toObjectVariant(JSContext *cx, JSObject *objArg, ObjectVariant *objVarp)
{
@ -916,7 +910,7 @@ WrapperOwner::toObjectVariant(JSContext *cx, JSObject *objArg, ObjectVariant *ob
ObjectId id = objectIdMap(waiveXray).find(obj);
if (!id.isNull()) {
MOZ_ASSERT(id.hasXrayWaiver() == waiveXray);
*objVarp = RemoteObject(id.serialize());
*objVarp = MakeRemoteObject(id, obj);
return true;
}
@ -931,7 +925,7 @@ WrapperOwner::toObjectVariant(JSContext *cx, JSObject *objArg, ObjectVariant *ob
if (!objectIdMap(waiveXray).add(cx, obj, id))
return false;
*objVarp = RemoteObject(id.serialize());
*objVarp = MakeRemoteObject(id, obj);
return true;
}
@ -970,8 +964,10 @@ WrapperOwner::fromRemoteObjectVariant(JSContext *cx, RemoteObject objVar)
// Incref once we know the decref will be called.
incref();
AuxCPOWData *aux = new AuxCPOWData(objId, objVar.isCallable(), objVar.isConstructor());
SetProxyExtra(obj, 0, PrivateValue(this));
SetProxyExtra(obj, 1, DoubleValue(BitwiseCast<double>(objId.serialize())));
SetProxyExtra(obj, 1, PrivateValue(aux));
}
if (!JS_WrapObject(cx, &obj))

View File

@ -61,8 +61,6 @@ class WrapperOwner : public virtual JavaScriptShared
bool objectClassIs(JSContext *cx, JS::HandleObject obj, js::ESClassValue classValue);
const char* className(JSContext *cx, JS::HandleObject proxy);
bool regexp_toShared(JSContext *cx, JS::HandleObject proxy, js::RegExpGuard *g);
bool isCallable(JSObject *obj);
bool isConstructor(JSObject *obj);
nsresult instanceOf(JSObject *obj, const nsID *id, bool *bp);
@ -151,9 +149,6 @@ class WrapperOwner : public virtual JavaScriptShared
ReturnStatus *rs, bool *instanceof) = 0;
virtual bool SendDOMInstanceOf(const ObjectId &objId, const int &prototypeID, const int &depth,
ReturnStatus *rs, bool *instanceof) = 0;
virtual bool SendIsCallable(const ObjectId &objId, bool *result) = 0;
virtual bool SendIsConstructor(const ObjectId &objId, bool *result) = 0;
};
bool