From 5f5137c030aef12d9c138e424237859b3cb1bee0 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Wed, 18 Nov 2015 11:10:10 +0000 Subject: [PATCH] Bug 1219288 - Optimize GETIMPORT instructions in Ion r=shu --- js/src/jit/BaselineCompiler.cpp | 2 ++ js/src/jit/IonBuilder.cpp | 40 +++++++++++++++++++++++++++++++-- js/src/jit/IonBuilder.h | 1 + js/src/vm/TypeInference.cpp | 8 +++---- 4 files changed, 45 insertions(+), 6 deletions(-) diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index 10c055e0b299..5a651cceb241 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -2492,6 +2492,8 @@ BaselineCompiler::emit_JSOP_GETIMPORT() Shape* shape; MOZ_ALWAYS_TRUE(env->lookupImport(NameToId(script->getName(pc)), &targetEnv, &shape)); + EnsureTrackPropertyTypes(cx, targetEnv, shape->propid()); + frame.syncStack(0); uint32_t slot = shape->slot(); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 5ce139aff79f..5b534252d81e 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -1925,6 +1925,12 @@ IonBuilder::inspectOpcode(JSOp op) return jsop_intrinsic(name); } + case JSOP_GETIMPORT: + { + PropertyName* name = info().getAtom(pc)->asPropertyName(); + return jsop_getimport(name); + } + case JSOP_BINDGNAME: if (!script()->hasNonSyntacticScope()) { if (JSObject* scope = testGlobalLexicalBinding(info().getName(pc))) @@ -8033,7 +8039,7 @@ IonBuilder::getStaticName(JSObject* staticObject, PropertyName* name, bool* psuc staticObject->as().isGlobal(); MOZ_ASSERT(isGlobalLexical || staticObject->is() || - staticObject->is()); + staticObject->is()); MOZ_ASSERT(staticObject->isSingleton()); *psucceeded = true; @@ -8314,6 +8320,34 @@ IonBuilder::jsop_intrinsic(PropertyName* name) return true; } +bool +IonBuilder::jsop_getimport(PropertyName* name) +{ + ModuleEnvironmentObject* env = GetModuleEnvironmentForScript(script()); + MOZ_ASSERT(env); + + Shape* shape; + ModuleEnvironmentObject* targetEnv; + MOZ_ALWAYS_TRUE(env->lookupImport(NameToId(name), &targetEnv, &shape)); + + PropertyName* localName = JSID_TO_STRING(shape->propid())->asAtom().asPropertyName(); + bool emitted = false; + if (!getStaticName(targetEnv, localName, &emitted)) + return false; + + MOZ_ASSERT(emitted); + + // In the rare case where this import hasn't been initialized already (we + // have an import cycle where modules reference each other's imports), emit + // a check. + if (targetEnv->getSlot(shape->slot()).isMagic(JS_UNINITIALIZED_LEXICAL)) { + MDefinition* checked = addLexicalCheck(current->pop()); + current->push(checked); + } + + return true; +} + bool IonBuilder::jsop_bindname(PropertyName* name) { @@ -13876,7 +13910,9 @@ IonBuilder::getCallee() MDefinition* IonBuilder::addLexicalCheck(MDefinition* input) { - MOZ_ASSERT(JSOp(*pc) == JSOP_CHECKLEXICAL || JSOp(*pc) == JSOP_CHECKALIASEDLEXICAL); + MOZ_ASSERT(JSOp(*pc) == JSOP_CHECKLEXICAL || + JSOp(*pc) == JSOP_CHECKALIASEDLEXICAL || + JSOp(*pc) == JSOP_GETIMPORT); MInstruction* lexicalCheck; diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 4a695f642981..c97b4ceee83b 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -683,6 +683,7 @@ class IonBuilder bool jsop_getgname(PropertyName* name); bool jsop_getname(PropertyName* name); bool jsop_intrinsic(PropertyName* name); + bool jsop_getimport(PropertyName* name); bool jsop_bindname(PropertyName* name); bool jsop_getelem(); bool jsop_getelem_dense(MDefinition* obj, MDefinition* index, JSValueType unboxedType); diff --git a/js/src/vm/TypeInference.cpp b/js/src/vm/TypeInference.cpp index 258366906cf7..949c2fdfe760 100644 --- a/js/src/vm/TypeInference.cpp +++ b/js/src/vm/TypeInference.cpp @@ -2579,12 +2579,12 @@ UpdatePropertyType(ExclusiveContext* cx, HeapTypeSet* types, NativeObject* obj, * that are not collated into the JSID_VOID property (see propertySet * comment). * - * Also don't add untracked values (initial uninitialized lexical - * magic values and optimized out values) as appearing in CallObjects - * and the global lexical scope. + * Also don't add untracked values (initial uninitialized lexical magic + * values and optimized out values) as appearing in CallObjects, module + * environments or the global lexical scope. */ MOZ_ASSERT_IF(TypeSet::IsUntrackedValue(value), - obj->is() || IsExtensibleLexicalScope(obj)); + obj->is() || IsExtensibleLexicalScope(obj)); if ((indexed || !value.isUndefined() || !CanHaveEmptyPropertyTypesForOwnProperty(obj)) && !TypeSet::IsUntrackedValue(value)) {