From 3d3f20ee49835722a6b8e88f95478edef53a75a3 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Tue, 19 Nov 2013 19:21:11 +0100 Subject: [PATCH] Bug 894881 - Fix JIT fast paths to work with typed array properties. r=bhackett --- js/src/jit/BaselineIC.cpp | 14 +++++++++----- js/src/jit/IonBuilder.cpp | 17 ++++++++++++----- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 26dd349d1fd..50223fd56fc 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -3269,10 +3269,14 @@ EffectlesslyLookupProperty(JSContext *cx, HandleObject obj, HandlePropertyName n *domProxyHasGeneration = (*shadowsResult == DoesntShadowUnique); checkObj = GetDOMProxyProto(obj); - } - - if (!isDOMProxy && !obj->isNative()) + } else if (obj->is() && obj->getProto()) { + // Typed array objects are non-native, but don't have any named + // properties. Just forward the lookup to the prototype, to allow + // inlining common getters like byteOffset. + checkObj = obj->getProto(); + } else if (!obj->isNative()) { return true; + } if (checkObj->hasIdempotentProtoChain()) { if (!JSObject::lookupProperty(cx, checkObj, name, holder, shape)) @@ -3289,7 +3293,7 @@ static bool IsCacheableProtoChain(JSObject *obj, JSObject *holder, bool isDOMProxy=false) { JS_ASSERT_IF(isDOMProxy, IsCacheableDOMProxy(obj)); - JS_ASSERT_IF(!isDOMProxy, obj->isNative()); + JS_ASSERT_IF(!isDOMProxy, obj->isNative() || obj->is()); // Don't handle objects which require a prototype guard. This should // be uncommon so handling it is likely not worth the complexity. @@ -5974,7 +5978,7 @@ TryAttachNativeGetPropStub(JSContext *cx, HandleScript script, jsbytecode *pc, return false; } - if (!isDOMProxy && !obj->isNative()) + if (!isDOMProxy && !obj->isNative() && !obj->is()) return true; bool isCallProp = (JSOp(*pc) == JSOP_CALLPROP); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index b09571f0b15..3f59b68a839 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -5934,8 +5934,14 @@ IonBuilder::maybeInsertResume() } static bool -ClassHasEffectlessLookup(const Class *clasp) +ClassHasEffectlessLookup(const Class *clasp, PropertyName *name) { + if (IsTypedArrayClass(clasp)) { + // Typed arrays have a lookupGeneric hook, but it only handles + // integers, not names. + JS_ASSERT(name); + return true; + } return clasp->isNative() && !clasp->ops.lookupGeneric; } @@ -5974,7 +5980,7 @@ IonBuilder::testSingletonProperty(JSObject *obj, PropertyName *name) // property will change and trigger invalidation. while (obj) { - if (!ClassHasEffectlessLookup(obj->getClass())) + if (!ClassHasEffectlessLookup(obj->getClass(), name)) return nullptr; types::TypeObjectKey *objType = types::TypeObjectKey::get(obj); @@ -7785,12 +7791,13 @@ IonBuilder::objectsHaveCommonPrototype(types::TemporaryTypeSet *types, PropertyN return false; const Class *clasp = type->clasp(); - if (!ClassHasEffectlessLookup(clasp) || ClassHasResolveHook(compartment, clasp, name)) + if (!ClassHasEffectlessLookup(clasp, name) || ClassHasResolveHook(compartment, clasp, name)) return false; // Look for a getter/setter on the class itself which may need - // to be called. - if (isGetter && clasp->ops.getGeneric) + // to be called. Ignore the getGeneric hook for typed arrays, it + // only handles integers and forwards names to the prototype. + if (isGetter && clasp->ops.getGeneric && !IsTypedArrayClass(clasp)) return false; if (!isGetter && clasp->ops.setGeneric) return false;