Bug 1499140 - Compile dynamic module import bytecode r=jandem
authorJon Coppeard <jcoppeard@mozilla.com>
Mon, 22 Oct 2018 11:28:17 +0100
changeset 501558 6592655e860e73040175e3a0de9d7a1ade2dea89
parent 501557 430db29f46858faff930e2ec3ed45fbf13a73a20
child 501559 41812db6cabaf796d6672786efa109ab771e3b2f
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1499140
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1499140 - Compile dynamic module import bytecode r=jandem
js/src/jit/BaselineCompiler.cpp
js/src/jit/BaselineCompiler.h
js/src/jit/CodeGenerator.cpp
js/src/jit/IonBuilder.cpp
js/src/jit/IonBuilder.h
js/src/jit/Lowering.cpp
js/src/jit/MIR.h
js/src/jit/shared/LIR-shared.h
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -1196,18 +1196,16 @@ BaselineCompiler::emitBody()
         }
 
         switch (op) {
           // ===== NOT Yet Implemented =====
           case JSOP_FORCEINTERPRETER:
             // Intentionally not implemented.
           case JSOP_SETINTRINSIC:
             // Run-once opcode during self-hosting initialization.
-          case JSOP_DYNAMIC_IMPORT:
-            // Dynamic module import.
           case JSOP_UNUSED126:
           case JSOP_UNUSED206:
           case JSOP_LIMIT:
             // === !! WARNING WARNING WARNING !! ===
             // Do you really want to sacrifice performance by not implementing
             // this operation in the BaselineCompiler?
             JitSpew(JitSpew_BaselineAbort, "Unhandled op: %s", CodeName[op]);
             return Method_CantCompile;
@@ -5441,8 +5439,33 @@ BaselineCompiler::emit_JSOP_IMPORTMETA()
     if (!callVM(GetOrCreateModuleMetaObjectInfo)) {
         return false;
     }
 
     masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
     frame.push(R0);
     return true;
 }
+
+typedef JSObject* (*StartDynamicModuleImportFn)(JSContext*, HandleValue, HandleValue);
+static const VMFunction StartDynamicModuleImportInfo =
+    FunctionInfo<StartDynamicModuleImportFn>(js::StartDynamicModuleImport,
+                                                "StartDynamicModuleImport");
+
+bool
+BaselineCompiler::emit_JSOP_DYNAMIC_IMPORT()
+{
+    RootedValue referencingPrivate(cx, FindScriptOrModulePrivateForScript(script));
+
+    // Put specifier value in R0.
+    frame.popRegsAndSync(1);
+
+    prepareVMCall();
+    pushArg(R0);
+    pushArg(referencingPrivate);
+    if (!callVM(StartDynamicModuleImportInfo)) {
+        return false;
+    }
+
+    masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
+    frame.push(R0);
+    return true;
+}
--- a/js/src/jit/BaselineCompiler.h
+++ b/js/src/jit/BaselineCompiler.h
@@ -240,17 +240,18 @@ namespace jit {
     _(JSOP_TRY_DESTRUCTURING_ITERCLOSE) \
     _(JSOP_CHECKCLASSHERITAGE) \
     _(JSOP_INITHOMEOBJECT)     \
     _(JSOP_BUILTINPROTO)       \
     _(JSOP_OBJWITHPROTO)       \
     _(JSOP_FUNWITHPROTO)       \
     _(JSOP_CLASSCONSTRUCTOR)   \
     _(JSOP_DERIVEDCONSTRUCTOR) \
-    _(JSOP_IMPORTMETA)
+    _(JSOP_IMPORTMETA)         \
+    _(JSOP_DYNAMIC_IMPORT)
 
 class BaselineCompiler final
 {
     JSContext* cx;
     JSScript* script;
     jsbytecode* pc;
     StackMacroAssembler masm;
     bool ionCompileable_;
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -3020,16 +3020,29 @@ static const VMFunction GetOrCreateModul
 
 void
 CodeGenerator::visitModuleMetadata(LModuleMetadata* lir)
 {
     pushArg(ImmPtr(lir->mir()->module()));
     callVM(GetOrCreateModuleMetaObjectInfo, lir);
 }
 
+typedef JSObject* (*StartDynamicModuleImportFn)(JSContext*, HandleValue, HandleValue);
+static const VMFunction StartDynamicModuleImportInfo =
+    FunctionInfo<StartDynamicModuleImportFn>(js::StartDynamicModuleImport,
+                                                "StartDynamicModuleImport");
+
+void
+CodeGenerator::visitDynamicImport(LDynamicImport* lir)
+{
+    pushArg(ToValue(lir, LDynamicImport::SpecifierIndex));
+    pushArg(ToValue(lir, LDynamicImport::ReferencingPrivateIndex));
+    callVM(StartDynamicModuleImportInfo, lir);
+}
+
 typedef JSObject* (*LambdaFn)(JSContext*, HandleFunction, HandleObject);
 static const VMFunction LambdaInfo = FunctionInfo<LambdaFn>(js::Lambda, "Lambda");
 
 void
 CodeGenerator::visitLambdaForSingleton(LLambdaForSingleton* lir)
 {
     pushArg(ToRegister(lir->environmentChain()));
     pushArg(ImmGCPtr(lir->mir()->info().funUnsafe()));
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -16,16 +16,17 @@
 #include "jit/BaselineInspector.h"
 #include "jit/Ion.h"
 #include "jit/IonControlFlow.h"
 #include "jit/IonOptimizationLevels.h"
 #include "jit/JitSpewer.h"
 #include "jit/Lowering.h"
 #include "jit/MIRGraph.h"
 #include "vm/ArgumentsObject.h"
+#include "vm/EnvironmentObject.h"
 #include "vm/Opcodes.h"
 #include "vm/RegExpStatics.h"
 #include "vm/TraceLogging.h"
 
 #include "gc/Nursery-inl.h"
 #include "jit/CompileInfo-inl.h"
 #include "jit/shared/Lowering-shared-inl.h"
 #include "vm/BytecodeUtil-inl.h"
@@ -2484,16 +2485,19 @@ IonBuilder::inspectOpcode(JSOp op)
         arr->setImplicitlyUsedUnchecked();
         pushConstant(BooleanValue(false));
         return Ok();
       }
 
       case JSOP_IMPORTMETA:
         return jsop_importmeta();
 
+      case JSOP_DYNAMIC_IMPORT:
+        return jsop_dynamic_import();
+
       case JSOP_LOOPENTRY:
         return jsop_loopentry();
 
       // ===== NOT Yet Implemented =====
       // Read below!
 
       // With
       case JSOP_ENTERWITH:
@@ -2552,17 +2556,16 @@ IonBuilder::inspectOpcode(JSOp op)
       // Misc
       case JSOP_DELNAME:
       case JSOP_FINALLY:
       case JSOP_GETRVAL:
       case JSOP_GOSUB:
       case JSOP_RETSUB:
       case JSOP_SETINTRINSIC:
       case JSOP_THROWMSG:
-      case JSOP_DYNAMIC_IMPORT:
         // === !! WARNING WARNING WARNING !! ===
         // Do you really want to sacrifice performance by not implementing this
         // operation in the optimizing compiler?
         break;
 
       case JSOP_FORCEINTERPRETER:
         // Intentionally not implemented.
         break;
@@ -13824,16 +13827,30 @@ IonBuilder::jsop_importmeta()
     MOZ_ASSERT(module);
 
     MModuleMetadata* meta = MModuleMetadata::New(alloc(), module);
     current->add(meta);
     current->push(meta);
     return resumeAfter(meta);
 }
 
+AbortReasonOr<Ok>
+IonBuilder::jsop_dynamic_import()
+{
+    Value referencingPrivate = FindScriptOrModulePrivateForScript(script());
+    MConstant* ref = constant(referencingPrivate);
+
+    MDefinition* specifier = current->pop();
+
+    MDynamicImport* ins = MDynamicImport::New(alloc(), ref, specifier);
+    current->add(ins);
+    current->push(ins);
+    return resumeAfter(ins);
+}
+
 MInstruction*
 IonBuilder::addConvertElementsToDoubles(MDefinition* elements)
 {
     MInstruction* convert = MConvertElementsToDoubles::New(alloc(), elements);
     current->add(convert);
     return convert;
 }
 
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -588,16 +588,17 @@ class IonBuilder
     AbortReasonOr<Ok> jsop_debugger();
     AbortReasonOr<Ok> jsop_newtarget();
     AbortReasonOr<Ok> jsop_checkisobj(uint8_t kind);
     AbortReasonOr<Ok> jsop_checkiscallable(uint8_t kind);
     AbortReasonOr<Ok> jsop_checkobjcoercible();
     AbortReasonOr<Ok> jsop_pushcallobj();
     AbortReasonOr<Ok> jsop_implicitthis(PropertyName* name);
     AbortReasonOr<Ok> jsop_importmeta();
+    AbortReasonOr<Ok> jsop_dynamic_import();
 
     /* Inlining. */
 
     enum InliningStatus
     {
         InliningStatus_NotInlined,
         InliningStatus_WarmUpCountTooLow,
         InliningStatus_Inlined
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -2598,16 +2598,25 @@ void
 LIRGenerator::visitModuleMetadata(MModuleMetadata* ins)
 {
     LModuleMetadata* lir = new(alloc()) LModuleMetadata();
     defineReturn(lir, ins);
     assignSafepoint(lir, ins);
 }
 
 void
+LIRGenerator::visitDynamicImport(MDynamicImport* ins)
+{
+    LDynamicImport* lir = new(alloc()) LDynamicImport(useBoxAtStart(ins->referencingPrivate()),
+                                                      useBoxAtStart(ins->specifier()));
+    defineReturn(lir, ins);
+    assignSafepoint(lir, ins);
+}
+
+void
 LIRGenerator::visitLambda(MLambda* ins)
 {
     if (ins->info().singletonType || ins->info().useSingletonForClone) {
         // If the function has a singleton type, this instruction will only be
         // executed once so we don't bother inlining it.
         //
         // If UseSingletonForClone is true, we will assign a singleton type to
         // the clone and we have to clone the script, we can't do that inline.
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -7814,16 +7814,32 @@ class MModuleMetadata : public MNullaryI
         return AliasSet::None();
     }
 
     bool appendRoots(MRootList& roots) const override {
         return roots.append(module_);
     }
 };
 
+class MDynamicImport : public MBinaryInstruction,
+                       public BoxInputsPolicy::Data
+{
+    explicit MDynamicImport(MDefinition* referencingPrivate, MDefinition* specifier)
+      : MBinaryInstruction(classOpcode, referencingPrivate, specifier)
+    {
+        setResultType(MIRType::Object);
+    }
+
+  public:
+    INSTRUCTION_HEADER(DynamicImport)
+    TRIVIAL_NEW_WRAPPERS
+    NAMED_OPERANDS((0, referencingPrivate))
+    NAMED_OPERANDS((1, specifier))
+};
+
 struct LambdaFunctionInfo
 {
     // The functions used in lambdas are the canonical original function in
     // the script, and are immutable except for delazification. Record this
     // information while still on the main thread to avoid races.
   private:
     CompilerFunction fun_;
 
--- a/js/src/jit/shared/LIR-shared.h
+++ b/js/src/jit/shared/LIR-shared.h
@@ -4898,16 +4898,37 @@ class LModuleMetadata : public LCallInst
         return mir_->toModuleMetadata();
     }
 
     LModuleMetadata()
       : LCallInstructionHelper(classOpcode)
     {}
 };
 
+class LDynamicImport : public LCallInstructionHelper<1, 2 * BOX_PIECES, 0>
+{
+  public:
+    LIR_HEADER(DynamicImport)
+
+    static const size_t ReferencingPrivateIndex = 0;
+    static const size_t SpecifierIndex = BOX_PIECES;
+
+    explicit LDynamicImport(const LBoxAllocation& referencingPrivate,
+                            const LBoxAllocation& specifier)
+      : LCallInstructionHelper(classOpcode)
+    {
+        setBoxOperand(ReferencingPrivateIndex, referencingPrivate);
+        setBoxOperand(SpecifierIndex, specifier);
+    }
+
+    const MDynamicImport* mir() const {
+        return mir_->toDynamicImport();
+    }
+};
+
 class LLambdaForSingleton : public LCallInstructionHelper<1, 1, 0>
 {
   public:
     LIR_HEADER(LambdaForSingleton)
 
     explicit LLambdaForSingleton(const LAllocation& envChain)
       : LCallInstructionHelper(classOpcode)
     {