Bug 1010658 part 1. Stop using the DOMClass stored in DOM_PROTO_INSTANCE_CLASS_SLOT for doing type checks in the jit, and do them directly on the instance classes instead. r=efaust

This commit is contained in:
Boris Zbarsky 2014-05-19 16:37:59 -04:00
parent 22db30d2de
commit 1b444f52b8
8 changed files with 58 additions and 19 deletions

View File

@ -773,15 +773,13 @@ TryPreserveWrapper(JSObject* obj)
return domClass && !domClass->mParticipant;
}
// Can only be called with the immediate prototype of the instance object. Can
// only be called on the prototype of an object known to be a DOM instance.
// Can only be called with a DOM JSClass.
bool
InstanceClassHasProtoAtDepth(JSObject* protoObject, uint32_t protoID,
uint32_t depth)
InstanceClassHasProtoAtDepth(const js::Class* clasp,
uint32_t protoID, uint32_t depth)
{
const DOMClass* domClass = static_cast<const DOMClass*>(
js::GetReservedSlot(protoObject, DOM_PROTO_INSTANCE_CLASS_SLOT).toPrivate());
return (uint32_t)domClass->mInterfaceChain[depth] == protoID;
const DOMClass& domClass = DOMJSClass::FromJSClass(clasp)->mClass;
return static_cast<uint32_t>(domClass.mInterfaceChain[depth]) == protoID;
}
// Only set allowNativeWrapper to false if you really know you need it, if in

View File

@ -1185,11 +1185,10 @@ ClearWrapper(T* p, void*)
bool
TryPreserveWrapper(JSObject* obj);
// Can only be called with the immediate prototype of the instance object. Can
// only be called on the prototype of an object known to be a DOM instance.
// Can only be called with a DOM JSClass.
bool
InstanceClassHasProtoAtDepth(JSObject* protoObject, uint32_t protoID,
uint32_t depth);
InstanceClassHasProtoAtDepth(const js::Class* clasp,
uint32_t protoID, uint32_t depth);
// Only set allowNativeWrapper to false if you really know you need it, if in
// doubt use true. Setting it to false disables security wrappers.

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<script>
/*
user_pref("dom.window_experimental_bindings", true);
*/
function boom()
{
window.__proto__ = null;
for (var i = 0; i < 10000; ++i) {
self.document;
}
}
</script></head>
<body onload="boom();"></body>
</html>

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<script>
/*
user_pref("dom.window_experimental_bindings", true);
*/
function boom()
{
window.__proto__ = function(){};
for (var i = 0; i < 10000; ++i) {
self.document;
}
}
</script></head>
<body onload="boom();"></body>
</html>

View File

@ -8,3 +8,5 @@ load 862610.html
load 862092.html
load 869038.html
load 949940.html
load 1010658-1.html
load 1010658-2.html

View File

@ -5198,7 +5198,7 @@ IonBuilder::testShouldDOMCall(types::TypeSet *inTypes,
// If all the DOM objects flowing through are legal with this
// property, we can bake in a call to the bottom half of the DOM
// accessor
DOMInstanceClassMatchesProto instanceChecker =
DOMInstanceClassHasProtoAtDepth instanceChecker =
compartment->runtime()->DOMcallbacks()->instanceClassMatchesProto;
const JSJitInfo *jinfo = func->jitInfo();
@ -5210,10 +5210,7 @@ IonBuilder::testShouldDOMCall(types::TypeSet *inTypes,
if (!curType)
continue;
if (!curType->hasTenuredProto())
return false;
JSObject *proto = curType->proto().toObjectOrNull();
if (!instanceChecker(proto, jinfo->protoID, jinfo->depth))
if (!instanceChecker(curType->clasp(), jinfo->protoID, jinfo->depth))
return false;
}

View File

@ -925,9 +925,10 @@ extern JS_FRIEND_API(bool)
IsContextRunningJS(JSContext *cx);
typedef bool
(* DOMInstanceClassMatchesProto)(JSObject *protoObject, uint32_t protoID, uint32_t depth);
(* DOMInstanceClassHasProtoAtDepth)(const Class *instanceClass,
uint32_t protoID, uint32_t depth);
struct JSDOMCallbacks {
DOMInstanceClassMatchesProto instanceClassMatchesProto;
DOMInstanceClassHasProtoAtDepth instanceClassMatchesProto;
};
typedef struct JSDOMCallbacks DOMCallbacks;

View File

@ -5399,7 +5399,7 @@ dom_constructor(JSContext* cx, unsigned argc, JS::Value *vp)
}
static bool
InstanceClassHasProtoAtDepth(JSObject *protoObject, uint32_t protoID, uint32_t depth)
InstanceClassHasProtoAtDepth(const Class *clasp, uint32_t protoID, uint32_t depth)
{
/* There's only a single (fake) DOM object in the shell, so just return true. */
return true;