From 2ee97dbd008d1314c7a51a9475ca7434b4fdefc0 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Wed, 2 Dec 2015 10:10:26 +0000 Subject: [PATCH] Bug 1227567 - Optimise module namespace imports in Ion where we have type information r=shu --- js/public/TrackedOptimizationInfo.h | 3 ++ js/src/builtin/ModuleObject.cpp | 1 + js/src/jit/IonBuilder.cpp | 48 +++++++++++++++++++++++++++++ js/src/jit/IonBuilder.h | 2 ++ 4 files changed, 54 insertions(+) diff --git a/js/public/TrackedOptimizationInfo.h b/js/public/TrackedOptimizationInfo.h index 58253e780181..642f4d773055 100644 --- a/js/public/TrackedOptimizationInfo.h +++ b/js/public/TrackedOptimizationInfo.h @@ -26,6 +26,7 @@ namespace JS { _(GetProp_Innerize) \ _(GetProp_InlineCache) \ _(GetProp_SharedCache) \ + _(GetProp_ModuleNamespace) \ \ _(SetProp_CommonSetter) \ _(SetProp_TypedObject) \ @@ -104,6 +105,8 @@ namespace JS { _(NoSimdJitSupport) \ _(SimdTypeNotOptimized) \ _(UnknownSimdProperty) \ + _(NotModuleNamespace) \ + _(UnknownProperty) \ \ _(ICOptStub_GenericSuccess) \ \ diff --git a/js/src/builtin/ModuleObject.cpp b/js/src/builtin/ModuleObject.cpp index 5b5dfd0e426c..3ba3d8c3c9d9 100644 --- a/js/src/builtin/ModuleObject.cpp +++ b/js/src/builtin/ModuleObject.cpp @@ -285,6 +285,7 @@ ModuleNamespaceObject::create(JSContext* cx, HandleModuleObject module) RootedValue priv(cx, ObjectValue(*module)); ProxyOptions options; options.setLazyProto(true); + options.setSingleton(true); RootedObject object(cx, NewProxyObject(cx, &proxyHandler, priv, nullptr, options)); if (!object) return nullptr; diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index d651415d70e7..52e72acdfe89 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -10941,6 +10941,11 @@ IonBuilder::jsop_getprop(PropertyName* name) trackOptimizationAttempt(TrackedStrategy::GetProp_InlineAccess); if (!getPropTryInlineAccess(&emitted, obj, name, barrier, types) || emitted) return emitted; + + // Try to emit loads from a module namespace. + trackOptimizationAttempt(TrackedStrategy::GetProp_ModuleNamespace); + if (!getPropTryModuleNamespace(&emitted, obj, name, barrier, types) || emitted) + return emitted; } // Try to emit a polymorphic cache. @@ -11406,6 +11411,49 @@ IonBuilder::getPropTryDefiniteSlot(bool* emitted, MDefinition* obj, PropertyName return true; } +bool +IonBuilder::getPropTryModuleNamespace(bool* emitted, MDefinition* obj, PropertyName* name, + BarrierKind barrier, TemporaryTypeSet* types) +{ + MOZ_ASSERT(*emitted == false); + + TemporaryTypeSet* objTypes = obj->resultTypeSet(); + if (!objTypes) { + trackOptimizationOutcome(TrackedOutcome::NoTypeInfo); + return true; + } + + JSObject* singleton = objTypes->maybeSingleton(); + if (!singleton) { + trackOptimizationOutcome(TrackedOutcome::NotSingleton); + return true; + } + + if (!singleton->is()) { + trackOptimizationOutcome(TrackedOutcome::NotModuleNamespace); + return true; + } + + ModuleNamespaceObject* ns = &singleton->as(); + ModuleEnvironmentObject* env; + Shape* shape; + if (!ns->bindings().lookup(NameToId(name), &env, &shape)) { + trackOptimizationOutcome(TrackedOutcome::UnknownProperty); + return true; + } + + obj->setImplicitlyUsedUnchecked(); + MConstant* envConst = constant(ObjectValue(*env)); + uint32_t slot = shape->slot(); + uint32_t nfixed = env->numFixedSlots(); + if (!loadSlot(envConst, slot, nfixed, types->getKnownMIRType(), barrier, types)) + return false; + + trackOptimizationSuccess(); + *emitted = true; + return true; +} + MInstruction* IonBuilder::loadUnboxedProperty(MDefinition* obj, size_t offset, JSValueType unboxedType, BarrierKind barrier, TemporaryTypeSet* types) diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index f80c9ff833d7..54a7589877e6 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -432,6 +432,8 @@ class IonBuilder bool getPropTryConstant(bool* emitted, MDefinition* obj, jsid id, TemporaryTypeSet* types); bool getPropTryDefiniteSlot(bool* emitted, MDefinition* obj, PropertyName* name, BarrierKind barrier, TemporaryTypeSet* types); + bool getPropTryModuleNamespace(bool* emitted, MDefinition* obj, PropertyName* name, + BarrierKind barrier, TemporaryTypeSet* types); bool getPropTryUnboxed(bool* emitted, MDefinition* obj, PropertyName* name, BarrierKind barrier, TemporaryTypeSet* types); bool getPropTryCommonGetter(bool* emitted, MDefinition* obj, PropertyName* name,