Bug 1133746. Allow DOMProxyShadows to communicate to the JIT whether the shadowing is done by the expando object or not. r=efaust,peterv

This commit is contained in:
Boris Zbarsky 2015-02-26 12:30:02 -05:00
parent 6038f5819e
commit 0123e1e87e
4 changed files with 40 additions and 18 deletions

View File

@ -33,17 +33,22 @@ const char DOMProxyHandler::family = 0;
js::DOMProxyShadowsResult
DOMProxyShadows(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id)
{
JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
JS::Value v = js::GetProxyExtra(proxy, JSPROXYSLOT_EXPANDO);
if (v.isObject()) {
bool isOverrideBuiltins = !v.isObject() && !v.isUndefined();
if (expando) {
bool hasOwn;
Rooted<JSObject*> object(cx, &v.toObject());
if (!JS_AlreadyHasOwnPropertyById(cx, object, id, &hasOwn))
if (!JS_AlreadyHasOwnPropertyById(cx, expando, id, &hasOwn))
return js::ShadowCheckFailed;
return hasOwn ? js::Shadows : js::DoesntShadow;
if (hasOwn) {
return isOverrideBuiltins ?
js::ShadowsViaIndirectExpando : js::ShadowsViaDirectExpando;
}
}
if (v.isUndefined()) {
if (!isOverrideBuiltins) {
// Our expando, if any, didn't shadow, so we're not shadowing at all.
return js::DoesntShadow;
}

View File

@ -3220,7 +3220,7 @@ EffectlesslyLookupProperty(JSContext *cx, HandleObject obj, HandlePropertyName n
if (*shadowsResult == ShadowCheckFailed)
return false;
if (*shadowsResult == Shadows) {
if (DOMProxyIsShadowing(*shadowsResult)) {
holder.set(obj);
return true;
}
@ -6519,7 +6519,7 @@ TryAttachNativeGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc,
}
// If it's a shadowed listbase proxy property, attach stub to call Proxy::get instead.
if (isDOMProxy && domProxyShadowsResult == Shadows) {
if (isDOMProxy && DOMProxyIsShadowing(domProxyShadowsResult)) {
MOZ_ASSERT(obj == holder);
#if JS_HAS_NO_SUCH_METHOD
if (isCallProp)

View File

@ -1697,9 +1697,10 @@ GetPropertyIC::tryAttachProxy(JSContext *cx, HandleScript outerScript, IonScript
DOMProxyShadowsResult shadows = GetDOMProxyShadowsCheck()(cx, obj, id);
if (shadows == ShadowCheckFailed)
return false;
if (shadows == Shadows)
if (DOMProxyIsShadowing(shadows))
return tryAttachDOMProxyShadowed(cx, outerScript, ion, obj, returnAddr, emitted);
MOZ_ASSERT(shadows == DoesntShadow || shadows == DoesntShadowUnique);
return tryAttachDOMProxyUnshadowed(cx, outerScript, ion, obj, name,
shadows == DoesntShadowUnique, returnAddr, emitted);
}
@ -2969,7 +2970,7 @@ SetPropertyIC::update(JSContext *cx, HandleScript outerScript, size_t cacheIndex
DOMProxyShadowsResult shadows = GetDOMProxyShadowsCheck()(cx, obj, id);
if (shadows == ShadowCheckFailed)
return false;
if (shadows == Shadows) {
if (DOMProxyIsShadowing(shadows)) {
if (!cache.attachDOMProxyShadowed(cx, outerScript, ion, obj, returnAddr))
return false;
addedSetterStub = true;

View File

@ -1176,14 +1176,23 @@ NukeCrossCompartmentWrappers(JSContext* cx,
* The DOMProxyShadowsCheck function will be called to check if the property for
* id should be gotten from the prototype, or if there is an own property that
* shadows it.
* If DoesntShadow is returned then the slot at listBaseExpandoSlot should
* either be undefined or point to an expando object that would contain the own
* property.
* If DoesntShadowUnique is returned then the slot at listBaseExpandoSlot should
* contain a private pointer to a ExpandoAndGeneration, which contains a
* JS::Value that should either be undefined or point to an expando object, and
* a uint32 value. If that value changes then the IC for getting a property will
* be invalidated.
* * If ShadowsViaDirectExpando is returned, then the slot at
* listBaseExpandoSlot contains an expando object which has the property in
* question.
* * If ShadowsViaIndirectExpando is returned, then the slot at
* listBaseExpandoSlot contains a private pointer to an ExpandoAndGeneration
* and the expando object in the ExpandoAndGeneration has the property in
* question.
* * If DoesntShadow is returned then the slot at listBaseExpandoSlot should
* either be undefined or point to an expando object that would contain the
* own property.
* * If DoesntShadowUnique is returned then the slot at listBaseExpandoSlot
* should contain a private pointer to a ExpandoAndGeneration, which contains
* a JS::Value that should either be undefined or point to an expando object,
* and a uint32 value. If that value changes then the IC for getting a
* property will be invalidated.
* * If Shadows is returned, that means the property is an own property of the
* proxy but doesn't live on the expando object.
*/
struct ExpandoAndGeneration {
@ -1216,7 +1225,9 @@ typedef enum DOMProxyShadowsResult {
ShadowCheckFailed,
Shadows,
DoesntShadow,
DoesntShadowUnique
DoesntShadowUnique,
ShadowsViaDirectExpando,
ShadowsViaIndirectExpando
} DOMProxyShadowsResult;
typedef DOMProxyShadowsResult
(* DOMProxyShadowsCheck)(JSContext* cx, JS::HandleObject object, JS::HandleId id);
@ -1227,6 +1238,11 @@ SetDOMProxyInformation(const void *domProxyHandlerFamily, uint32_t domProxyExpan
const void *GetDOMProxyHandlerFamily();
uint32_t GetDOMProxyExpandoSlot();
DOMProxyShadowsCheck GetDOMProxyShadowsCheck();
inline bool DOMProxyIsShadowing(DOMProxyShadowsResult result) {
return result == Shadows ||
result == ShadowsViaDirectExpando ||
result == ShadowsViaIndirectExpando;
}
/* Implemented in jsdate.cpp. */