Bug 1530937 part 10 - Convert more callVMs in CodeGenerator.cpp. r=nbp
authorJan de Mooij <jdemooij@mozilla.com>
Thu, 07 Mar 2019 17:49:04 +0000
changeset 521006 5734a9a9153133cd366f75742cc958ce205a8b5d
parent 521005 546397372dd75a335d91268a5b5b539f17f266d9
child 521007 ef2b461b0a90a509075824a47115a7c94a3eb25b
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1530937
milestone67.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 1530937 part 10 - Convert more callVMs in CodeGenerator.cpp. r=nbp Differential Revision: https://phabricator.services.mozilla.com/D22523
js/src/builtin/String.cpp
js/src/builtin/String.h
js/src/jit/BaselineFrame-inl.h
js/src/jit/CodeGenerator.cpp
js/src/jit/Recover.cpp
js/src/jit/VMFunctionList-inl.h
js/src/jit/VMFunctions.h
js/src/vm/EnvironmentObject.cpp
js/src/vm/EnvironmentObject.h
js/src/vm/Stack.cpp
js/src/vm/TypedArrayObject.cpp
js/src/vm/TypedArrayObject.h
--- a/js/src/builtin/String.cpp
+++ b/js/src/builtin/String.cpp
@@ -2905,17 +2905,17 @@ static bool StrFlatReplaceGlobal(JSConte
     return false;
   }
 
   return true;
 }
 
 // This is identical to "str.split(pattern).join(replacement)" except that we
 // do some deforestation optimization in Ion.
-JSString* js::str_flat_replace_string(JSContext* cx, HandleString string,
+JSString* js::StringFlatReplaceString(JSContext* cx, HandleString string,
                                       HandleString pattern,
                                       HandleString replacement) {
   MOZ_ASSERT(string);
   MOZ_ASSERT(pattern);
   MOZ_ASSERT(replacement);
 
   if (!string->length()) {
     return string;
--- a/js/src/builtin/String.h
+++ b/js/src/builtin/String.h
@@ -136,17 +136,17 @@ extern bool str_localeCompare(JSContext*
 #endif  // EXPOSE_INTL_API
 
 extern bool str_concat(JSContext* cx, unsigned argc, Value* vp);
 
 ArrayObject* str_split_string(JSContext* cx, HandleObjectGroup group,
                               HandleString str, HandleString sep,
                               uint32_t limit);
 
-JSString* str_flat_replace_string(JSContext* cx, HandleString string,
+JSString* StringFlatReplaceString(JSContext* cx, HandleString string,
                                   HandleString pattern,
                                   HandleString replacement);
 
 JSString* str_replace_string_raw(JSContext* cx, HandleString string,
                                  HandleString pattern,
                                  HandleString replacement);
 
 extern JSString* StringToLowerCase(JSContext* cx, HandleString string);
--- a/js/src/jit/BaselineFrame-inl.h
+++ b/js/src/jit/BaselineFrame-inl.h
@@ -38,17 +38,17 @@ inline void BaselineFrame::replaceInnerm
   MOZ_ASSERT(env.enclosingEnvironment() ==
              envChain_->as<EnvironmentObject>().enclosingEnvironment());
   envChain_ = &env;
 }
 
 inline bool BaselineFrame::pushLexicalEnvironment(JSContext* cx,
                                                   Handle<LexicalScope*> scope) {
   LexicalEnvironmentObject* env =
-      LexicalEnvironmentObject::create(cx, scope, this);
+      LexicalEnvironmentObject::createForFrame(cx, scope, this);
   if (!env) {
     return false;
   }
   pushOnEnvironmentChain(*env);
 
   return true;
 }
 
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -2744,23 +2744,16 @@ class OutOfLineRegExpMatcher : public Ou
 
   void accept(CodeGenerator* codegen) override {
     codegen->visitOutOfLineRegExpMatcher(this);
   }
 
   LRegExpMatcher* lir() const { return lir_; }
 };
 
-typedef bool (*RegExpMatcherRawFn)(JSContext* cx, HandleObject regexp,
-                                   HandleString input, int32_t lastIndex,
-                                   MatchPairs* pairs,
-                                   MutableHandleValue output);
-static const VMFunction RegExpMatcherRawInfo =
-    FunctionInfo<RegExpMatcherRawFn>(RegExpMatcherRaw, "RegExpMatcherRaw");
-
 void CodeGenerator::visitOutOfLineRegExpMatcher(OutOfLineRegExpMatcher* ool) {
   LRegExpMatcher* lir = ool->lir();
   Register lastIndex = ToRegister(lir->lastIndex());
   Register input = ToRegister(lir->string());
   Register regexp = ToRegister(lir->regexp());
 
   AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
   regs.take(lastIndex);
@@ -2773,17 +2766,20 @@ void CodeGenerator::visitOutOfLineRegExp
 
   pushArg(temp);
   pushArg(lastIndex);
   pushArg(input);
   pushArg(regexp);
 
   // We are not using oolCallVM because we are in a Call, and that live
   // registers are already saved by the the register allocator.
-  callVM(RegExpMatcherRawInfo, lir);
+  using Fn = bool (*)(JSContext * cx, HandleObject regexp, HandleString input,
+                      int32_t lastIndex, MatchPairs * pairs,
+                      MutableHandleValue output);
+  callVM<Fn, RegExpMatcherRaw>(lir);
 
   masm.jump(ool->rejoin());
 }
 
 void CodeGenerator::visitRegExpMatcher(LRegExpMatcher* lir) {
   MOZ_ASSERT(ToRegister(lir->regexp()) == RegExpMatcherRegExpReg);
   MOZ_ASSERT(ToRegister(lir->string()) == RegExpMatcherStringReg);
   MOZ_ASSERT(ToRegister(lir->lastIndex()) == RegExpMatcherLastIndexReg);
@@ -2929,22 +2925,16 @@ class OutOfLineRegExpSearcher : public O
 
   void accept(CodeGenerator* codegen) override {
     codegen->visitOutOfLineRegExpSearcher(this);
   }
 
   LRegExpSearcher* lir() const { return lir_; }
 };
 
-typedef bool (*RegExpSearcherRawFn)(JSContext* cx, HandleObject regexp,
-                                    HandleString input, int32_t lastIndex,
-                                    MatchPairs* pairs, int32_t* result);
-static const VMFunction RegExpSearcherRawInfo =
-    FunctionInfo<RegExpSearcherRawFn>(RegExpSearcherRaw, "RegExpSearcherRaw");
-
 void CodeGenerator::visitOutOfLineRegExpSearcher(OutOfLineRegExpSearcher* ool) {
   LRegExpSearcher* lir = ool->lir();
   Register lastIndex = ToRegister(lir->lastIndex());
   Register input = ToRegister(lir->string());
   Register regexp = ToRegister(lir->regexp());
 
   AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
   regs.take(lastIndex);
@@ -2957,17 +2947,19 @@ void CodeGenerator::visitOutOfLineRegExp
 
   pushArg(temp);
   pushArg(lastIndex);
   pushArg(input);
   pushArg(regexp);
 
   // We are not using oolCallVM because we are in a Call, and that live
   // registers are already saved by the the register allocator.
-  callVM(RegExpSearcherRawInfo, lir);
+  using Fn = bool (*)(JSContext * cx, HandleObject regexp, HandleString input,
+                      int32_t lastIndex, MatchPairs * pairs, int32_t * result);
+  callVM<Fn, RegExpSearcherRaw>(lir);
 
   masm.jump(ool->rejoin());
 }
 
 void CodeGenerator::visitRegExpSearcher(LRegExpSearcher* lir) {
   MOZ_ASSERT(ToRegister(lir->regexp()) == RegExpTesterRegExpReg);
   MOZ_ASSERT(ToRegister(lir->string()) == RegExpTesterStringReg);
   MOZ_ASSERT(ToRegister(lir->lastIndex()) == RegExpTesterLastIndexReg);
@@ -3071,35 +3063,31 @@ class OutOfLineRegExpTester : public Out
 
   void accept(CodeGenerator* codegen) override {
     codegen->visitOutOfLineRegExpTester(this);
   }
 
   LRegExpTester* lir() const { return lir_; }
 };
 
-typedef bool (*RegExpTesterRawFn)(JSContext* cx, HandleObject regexp,
-                                  HandleString input, int32_t lastIndex,
-                                  int32_t* result);
-static const VMFunction RegExpTesterRawInfo =
-    FunctionInfo<RegExpTesterRawFn>(RegExpTesterRaw, "RegExpTesterRaw");
-
 void CodeGenerator::visitOutOfLineRegExpTester(OutOfLineRegExpTester* ool) {
   LRegExpTester* lir = ool->lir();
   Register lastIndex = ToRegister(lir->lastIndex());
   Register input = ToRegister(lir->string());
   Register regexp = ToRegister(lir->regexp());
 
   pushArg(lastIndex);
   pushArg(input);
   pushArg(regexp);
 
   // We are not using oolCallVM because we are in a Call, and that live
   // registers are already saved by the the register allocator.
-  callVM(RegExpTesterRawInfo, lir);
+  using Fn = bool (*)(JSContext * cx, HandleObject regexp, HandleString input,
+                      int32_t lastIndex, int32_t * result);
+  callVM<Fn, RegExpTesterRaw>(lir);
 
   masm.jump(ool->rejoin());
 }
 
 void CodeGenerator::visitRegExpTester(LRegExpTester* lir) {
   MOZ_ASSERT(ToRegister(lir->regexp()) == RegExpTesterRegExpReg);
   MOZ_ASSERT(ToRegister(lir->string()) == RegExpTesterStringReg);
   MOZ_ASSERT(ToRegister(lir->lastIndex()) == RegExpTesterLastIndexReg);
@@ -3297,23 +3285,16 @@ void CodeGenerator::visitGetFirstDollarI
   {
     FindFirstDollarIndex(masm, str, len, temp0, temp1, output,
                          CharEncoding::Latin1);
   }
   masm.bind(&done);
   masm.bind(ool->rejoin());
 }
 
-typedef JSString* (*StringReplaceFn)(JSContext*, HandleString, HandleString,
-                                     HandleString);
-static const VMFunction StringFlatReplaceInfo = FunctionInfo<StringReplaceFn>(
-    js::str_flat_replace_string, "str_flat_replace_string");
-static const VMFunction StringReplaceInfo =
-    FunctionInfo<StringReplaceFn>(StringReplace, "StringReplace");
-
 void CodeGenerator::visitStringReplace(LStringReplace* lir) {
   if (lir->replacement()->isConstant()) {
     pushArg(ImmGCPtr(lir->replacement()->toConstant()->toString()));
   } else {
     pushArg(ToRegister(lir->replacement()));
   }
 
   if (lir->pattern()->isConstant()) {
@@ -3323,20 +3304,22 @@ void CodeGenerator::visitStringReplace(L
   }
 
   if (lir->string()->isConstant()) {
     pushArg(ImmGCPtr(lir->string()->toConstant()->toString()));
   } else {
     pushArg(ToRegister(lir->string()));
   }
 
+  using Fn =
+      JSString* (*)(JSContext*, HandleString, HandleString, HandleString);
   if (lir->mir()->isFlatReplacement()) {
-    callVM(StringFlatReplaceInfo, lir);
-  } else {
-    callVM(StringReplaceInfo, lir);
+    callVM<Fn, StringFlatReplaceString>(lir);
+  } else {
+    callVM<Fn, StringReplace>(lir);
   }
 }
 
 void CodeGenerator::visitBinaryValueCache(LBinaryValueCache* lir) {
   LiveRegisterSet liveRegs = lir->safepoint()->liveRegs();
   TypedOrValueRegister lhs =
       TypedOrValueRegister(ToValue(lir, LBinaryValueCache::LhsInput));
   TypedOrValueRegister rhs =
@@ -3475,21 +3458,16 @@ class OutOfLineLambdaArrow : public OutO
 
   void accept(CodeGenerator* codegen) override {
     codegen->visitOutOfLineLambdaArrow(this);
   }
 
   Label* entryNoPop() { return &entryNoPop_; }
 };
 
-typedef JSObject* (*LambdaArrowFn)(JSContext*, HandleFunction, HandleObject,
-                                   HandleValue);
-static const VMFunction LambdaArrowInfo =
-    FunctionInfo<LambdaArrowFn>(js::LambdaArrow, "LambdaArrow");
-
 void CodeGenerator::visitOutOfLineLambdaArrow(OutOfLineLambdaArrow* ool) {
   Register envChain = ToRegister(ool->lir->environmentChain());
   ValueOperand newTarget = ToValue(ool->lir, LLambdaArrow::NewTargetValue);
   Register output = ToRegister(ool->lir->output());
   const LambdaFunctionInfo& info = ool->lir->mir()->info();
 
   // When we get here, we may need to restore part of the newTarget,
   // which has been conscripted into service as a temp register.
@@ -3498,17 +3476,19 @@ void CodeGenerator::visitOutOfLineLambda
   masm.bind(ool->entryNoPop());
 
   saveLive(ool->lir);
 
   pushArg(newTarget);
   pushArg(envChain);
   pushArg(ImmGCPtr(info.funUnsafe()));
 
-  callVM(LambdaArrowInfo, ool->lir);
+  using Fn =
+      JSObject* (*)(JSContext*, HandleFunction, HandleObject, HandleValue);
+  callVM<Fn, js::LambdaArrow>(ool->lir);
   StoreRegisterTo(output).generate(this);
 
   restoreLiveIgnore(ool->lir, StoreRegisterTo(output).clobbered());
 
   masm.jump(ool->rejoin());
 }
 
 void CodeGenerator::visitLambdaArrow(LLambdaArrow* lir) {
@@ -3679,26 +3659,22 @@ void CodeGenerator::visitTableSwitchV(LT
   masm.bind(&unboxInt);
   masm.unboxInt32(value, index);
 
   masm.bind(&isInt);
 
   emitTableSwitchDispatch(mir, index, ToRegisterOrInvalid(ins->tempPointer()));
 }
 
-typedef JSObject* (*DeepCloneObjectLiteralFn)(JSContext*, HandleObject,
-                                              NewObjectKind);
-static const VMFunction DeepCloneObjectLiteralInfo =
-    FunctionInfo<DeepCloneObjectLiteralFn>(DeepCloneObjectLiteral,
-                                           "DeepCloneObjectLiteral");
-
 void CodeGenerator::visitCloneLiteral(LCloneLiteral* lir) {
   pushArg(ImmWord(TenuredObject));
   pushArg(ToRegister(lir->getObjectLiteral()));
-  callVM(DeepCloneObjectLiteralInfo, lir);
+
+  using Fn = JSObject* (*)(JSContext*, HandleObject, NewObjectKind);
+  callVM<Fn, DeepCloneObjectLiteral>(lir);
 }
 
 void CodeGenerator::visitParameter(LParameter* lir) {}
 
 void CodeGenerator::visitCallee(LCallee* lir) {
   Register callee = ToRegister(lir->output());
   Address ptr(masm.getStackPointer(),
               frameSize() + JitFrameLayout::offsetOfCalleeToken());
@@ -4296,42 +4272,34 @@ void CodeGenerator::visitHomeObjectSuper
   OutOfLineCode* ool = oolCallVM(HomeObjectSuperBaseInfo, lir,
                                  ArgList(homeObject), StoreRegisterTo(output));
 
   masm.loadObjProto(homeObject, output);
   masm.branchPtr(Assembler::BelowOrEqual, output, ImmWord(1), ool->entry());
   masm.bind(ool->rejoin());
 }
 
-typedef LexicalEnvironmentObject* (*NewLexicalEnvironmentObjectFn)(
-    JSContext*, Handle<LexicalScope*>, HandleObject, gc::InitialHeap);
-static const VMFunction NewLexicalEnvironmentObjectInfo =
-    FunctionInfo<NewLexicalEnvironmentObjectFn>(
-        LexicalEnvironmentObject::create, "LexicalEnvironmentObject::create");
-
 void CodeGenerator::visitNewLexicalEnvironmentObject(
     LNewLexicalEnvironmentObject* lir) {
   pushArg(Imm32(gc::DefaultHeap));
   pushArg(ToRegister(lir->enclosing()));
   pushArg(ImmGCPtr(lir->mir()->scope()));
-  callVM(NewLexicalEnvironmentObjectInfo, lir);
-}
-
-typedef JSObject* (*CopyLexicalEnvironmentObjectFn)(JSContext*, HandleObject,
-                                                    bool);
-static const VMFunction CopyLexicalEnvironmentObjectInfo =
-    FunctionInfo<CopyLexicalEnvironmentObjectFn>(
-        js::jit::CopyLexicalEnvironmentObject,
-        "js::jit::CopyLexicalEnvironmentObject");
+
+  using Fn = LexicalEnvironmentObject* (*)(JSContext*, Handle<LexicalScope*>,
+                                           HandleObject, gc::InitialHeap);
+  callVM<Fn, LexicalEnvironmentObject::create>(lir);
+}
 
 void CodeGenerator::visitCopyLexicalEnvironmentObject(
     LCopyLexicalEnvironmentObject* lir) {
   pushArg(Imm32(lir->mir()->copySlots()));
   pushArg(ToRegister(lir->env()));
-  callVM(CopyLexicalEnvironmentObjectInfo, lir);
+
+  using Fn = JSObject* (*)(JSContext*, HandleObject, bool);
+  callVM<Fn, jit::CopyLexicalEnvironmentObject>(lir);
 }
 
 void CodeGenerator::visitGuardShape(LGuardShape* guard) {
   Register obj = ToRegister(guard->input());
   Register temp = ToTempRegisterOrInvalid(guard->temp());
   Label bail;
   masm.branchTestObjShape(Assembler::NotEqual, obj, guard->mir()->shape(), temp,
                           obj, &bail);
@@ -5049,45 +5017,39 @@ void CodeGenerator::visitCallDOMNative(L
   // is no need for leaveFakeExitFrame.
 
   // Move the StackPointer back to its original location, unwinding the native
   // exit frame.
   masm.adjustStack(IonDOMMethodExitFrameLayout::Size() - unusedStack);
   MOZ_ASSERT(masm.framePushed() == initialStack);
 }
 
-typedef bool (*GetIntrinsicValueFn)(JSContext* cx, HandlePropertyName,
-                                    MutableHandleValue);
-static const VMFunction GetIntrinsicValueInfo =
-    FunctionInfo<GetIntrinsicValueFn>(GetIntrinsicValue, "GetIntrinsicValue");
-
 void CodeGenerator::visitCallGetIntrinsicValue(LCallGetIntrinsicValue* lir) {
   pushArg(ImmGCPtr(lir->mir()->name()));
-  callVM(GetIntrinsicValueInfo, lir);
-}
-
-typedef bool (*InvokeFunctionFn)(JSContext*, HandleObject, bool, bool, uint32_t,
-                                 Value*, MutableHandleValue);
-static const VMFunction InvokeFunctionInfo =
-    FunctionInfo<InvokeFunctionFn>(InvokeFunction, "InvokeFunction");
+
+  using Fn = bool (*)(JSContext * cx, HandlePropertyName, MutableHandleValue);
+  callVM<Fn, GetIntrinsicValue>(lir);
+}
 
 void CodeGenerator::emitCallInvokeFunction(
     LInstruction* call, Register calleereg, bool constructing,
     bool ignoresReturnValue, uint32_t argc, uint32_t unusedStack) {
   // Nestle %esp up to the argument vector.
   // Each path must account for framePushed_ separately, for callVM to be valid.
   masm.freeStack(unusedStack);
 
   pushArg(masm.getStackPointer());  // argv.
   pushArg(Imm32(argc));             // argc.
   pushArg(Imm32(ignoresReturnValue));
   pushArg(Imm32(constructing));  // constructing.
   pushArg(calleereg);            // JSFunction*.
 
-  callVM(InvokeFunctionInfo, call);
+  using Fn = bool (*)(JSContext*, HandleObject, bool, bool, uint32_t, Value*,
+                      MutableHandleValue);
+  callVM<Fn, jit::InvokeFunction>(call);
 
   // Un-nestle %esp from the argument vector. No prefix was pushed.
   masm.reserveStack(unusedStack);
 }
 
 void CodeGenerator::visitCallGeneric(LCallGeneric* call) {
   Register calleereg = ToRegister(call->getFunction());
   Register objreg = ToRegister(call->getTempObject());
@@ -5191,32 +5153,29 @@ void CodeGenerator::visitCallGeneric(LCa
     masm.branchTestPrimitive(Assembler::NotEqual, JSReturnOperand,
                              &notPrimitive);
     masm.loadValue(Address(masm.getStackPointer(), unusedStack),
                    JSReturnOperand);
     masm.bind(&notPrimitive);
   }
 }
 
-typedef bool (*InvokeFunctionShuffleFn)(JSContext*, HandleObject, uint32_t,
-                                        uint32_t, Value*, MutableHandleValue);
-static const VMFunction InvokeFunctionShuffleInfo =
-    FunctionInfo<InvokeFunctionShuffleFn>(InvokeFunctionShuffleNewTarget,
-                                          "InvokeFunctionShuffleNewTarget");
 void CodeGenerator::emitCallInvokeFunctionShuffleNewTarget(
     LCallKnown* call, Register calleeReg, uint32_t numFormals,
     uint32_t unusedStack) {
   masm.freeStack(unusedStack);
 
   pushArg(masm.getStackPointer());
   pushArg(Imm32(numFormals));
   pushArg(Imm32(call->numActualArgs()));
   pushArg(calleeReg);
 
-  callVM(InvokeFunctionShuffleInfo, call);
+  using Fn = bool (*)(JSContext*, HandleObject, uint32_t, uint32_t, Value*,
+                      MutableHandleValue);
+  callVM<Fn, InvokeFunctionShuffleNewTarget>(call);
 
   masm.reserveStack(unusedStack);
 }
 
 void CodeGenerator::visitCallKnown(LCallKnown* call) {
   Register calleereg = ToRegister(call->getFunction());
   Register objreg = ToRegister(call->getTempObject());
   uint32_t unusedStack = StackOffsetOfPassedArg(call->argslot());
@@ -5326,17 +5285,19 @@ void CodeGenerator::emitCallInvokeFuncti
 
   pushArg(objreg);                            // argv.
   pushArg(ToRegister(apply->getArgc()));      // argc.
   pushArg(Imm32(false));                      // ignoresReturnValue.
   pushArg(Imm32(false));                      // isConstrucing.
   pushArg(ToRegister(apply->getFunction()));  // JSFunction*.
 
   // This specialization og callVM restore the extraStackSize after the call.
-  callVM(InvokeFunctionInfo, apply, &extraStackSize);
+  using Fn = bool (*)(JSContext*, HandleObject, bool, bool, uint32_t, Value*,
+                      MutableHandleValue);
+  callVM<Fn, jit::InvokeFunction>(apply, &extraStackSize);
 
   masm.Pop(extraStackSize);
 }
 
 // Do not bailout after the execution of this function since the stack no longer
 // correspond to what is expected by the snapshots.
 void CodeGenerator::emitAllocateSpaceForApply(Register argcreg,
                                               Register extraStackSpace,
@@ -5728,33 +5689,29 @@ void CodeGenerator::visitGetDynamicName(
   const ValueOperand out = ToOutValue(lir);
 
   masm.loadValue(Address(masm.getStackPointer(), 0), out);
   masm.adjustStack(sizeof(Value));
 
   bailoutIfFalseBool(ReturnReg, lir->snapshot());
 }
 
-typedef bool (*DirectEvalSFn)(JSContext*, HandleObject, HandleScript,
-                              HandleValue, HandleString, jsbytecode*,
-                              MutableHandleValue);
-static const VMFunction DirectEvalStringInfo = FunctionInfo<DirectEvalSFn>(
-    DirectEvalStringFromIon, "DirectEvalStringFromIon");
-
 void CodeGenerator::visitCallDirectEval(LCallDirectEval* lir) {
   Register envChain = ToRegister(lir->getEnvironmentChain());
   Register string = ToRegister(lir->getString());
 
   pushArg(ImmPtr(lir->mir()->pc()));
   pushArg(string);
   pushArg(ToValue(lir, LCallDirectEval::NewTarget));
   pushArg(ImmGCPtr(current->mir()->info().script()));
   pushArg(envChain);
 
-  callVM(DirectEvalStringInfo, lir);
+  using Fn = bool (*)(JSContext*, HandleObject, HandleScript, HandleValue,
+                      HandleString, jsbytecode*, MutableHandleValue);
+  callVM<Fn, DirectEvalStringFromIon>(lir);
 }
 
 void CodeGenerator::generateArgumentsChecks(bool assert) {
   // This function can be used the normal way to check the argument types,
   // before entering the function and bailout when arguments don't match.
   // For debug purpose, this is can also be used to force/check that the
   // arguments are correct. Upon fail it will hit a breakpoint.
 
@@ -5908,31 +5865,28 @@ void CodeGenerator::visitDefFun(LDefFun*
   pushArg(fun);
   pushArg(envChain);
   pushArg(ImmGCPtr(current->mir()->info().script()));
 
   using Fn = bool (*)(JSContext*, HandleScript, HandleObject, HandleFunction);
   callVM<Fn, DefFunOperation>(lir);
 }
 
-typedef bool (*CheckOverRecursedFn)(JSContext*);
-static const VMFunction CheckOverRecursedInfo =
-    FunctionInfo<CheckOverRecursedFn>(CheckOverRecursed, "CheckOverRecursed");
-
 void CodeGenerator::visitCheckOverRecursedFailure(
     CheckOverRecursedFailure* ool) {
   // The OOL path is hit if the recursion depth has been exceeded.
   // Throw an InternalError for over-recursion.
 
   // LFunctionEnvironment can appear before LCheckOverRecursed, so we have
   // to save all live registers to avoid crashes if CheckOverRecursed triggers
   // a GC.
   saveLive(ool->lir());
 
-  callVM(CheckOverRecursedInfo, ool->lir());
+  using Fn = bool (*)(JSContext*);
+  callVM<Fn, CheckOverRecursed>(ool->lir());
 
   restoreLive(ool->lir());
   masm.jump(ool->rejoin());
 }
 
 IonScriptCounts* CodeGenerator::maybeCreateScriptCounts() {
   // If scripts are being profiled, create a new IonScriptCounts for the
   // profiling data, which will be attached to the associated JSScript or
@@ -6468,21 +6422,16 @@ class OutOfLineNewArray : public OutOfLi
 
   void accept(CodeGenerator* codegen) override {
     codegen->visitOutOfLineNewArray(this);
   }
 
   LNewArray* lir() const { return lir_; }
 };
 
-typedef JSObject* (*NewArrayOperationFn)(JSContext*, HandleScript, jsbytecode*,
-                                         uint32_t, NewObjectKind);
-static const VMFunction NewArrayOperationInfo =
-    FunctionInfo<NewArrayOperationFn>(NewArrayOperation, "NewArrayOperation");
-
 static JSObject* NewArrayWithGroup(JSContext* cx, uint32_t length,
                                    HandleObjectGroup group,
                                    bool convertDoubleElements) {
   ArrayObject* res = NewFullyAllocatedArrayTryUseGroup(cx, group, length);
   if (!res) {
     return nullptr;
   }
   if (convertDoubleElements) {
@@ -6511,38 +6460,36 @@ void CodeGenerator::visitNewArrayCallVM(
 
     callVM(NewArrayWithGroupInfo, lir);
   } else {
     pushArg(Imm32(GenericObject));
     pushArg(Imm32(lir->mir()->length()));
     pushArg(ImmPtr(lir->mir()->pc()));
     pushArg(ImmGCPtr(lir->mir()->block()->info().script()));
 
-    callVM(NewArrayOperationInfo, lir);
+    using Fn = JSObject* (*)(JSContext*, HandleScript, jsbytecode*, uint32_t,
+                             NewObjectKind);
+    callVM<Fn, NewArrayOperation>(lir);
   }
 
   if (ReturnReg != objReg) {
     masm.movePtr(ReturnReg, objReg);
   }
 
   restoreLive(lir);
 }
 
-typedef JSObject* (*NewDerivedTypedObjectFn)(JSContext*, HandleObject type,
-                                             HandleObject owner,
-                                             int32_t offset);
-static const VMFunction CreateDerivedTypedObjInfo =
-    FunctionInfo<NewDerivedTypedObjectFn>(CreateDerivedTypedObj,
-                                          "CreateDerivedTypedObj");
-
 void CodeGenerator::visitNewDerivedTypedObject(LNewDerivedTypedObject* lir) {
   pushArg(ToRegister(lir->offset()));
   pushArg(ToRegister(lir->owner()));
   pushArg(ToRegister(lir->type()));
-  callVM(CreateDerivedTypedObjInfo, lir);
+
+  using Fn = JSObject* (*)(JSContext*, HandleObject type, HandleObject owner,
+                           int32_t offset);
+  callVM<Fn, CreateDerivedTypedObj>(lir);
 }
 
 void CodeGenerator::visitAtan2D(LAtan2D* lir) {
   Register temp = ToRegister(lir->temp());
   FloatRegister y = ToFloatRegister(lir->y());
   FloatRegister x = ToFloatRegister(lir->x());
 
   masm.setupUnalignedABICall(temp);
@@ -6731,18 +6678,19 @@ void CodeGenerator::visitNewIterator(LNe
 
   masm.bind(ool->rejoin());
 }
 
 typedef TypedArrayObject* (*TypedArrayConstructorOneArgFn)(JSContext*,
                                                            HandleObject,
                                                            int32_t length);
 static const VMFunction TypedArrayConstructorOneArgInfo =
-    FunctionInfo<TypedArrayConstructorOneArgFn>(TypedArrayCreateWithTemplate,
-                                                "TypedArrayCreateWithTemplate");
+    FunctionInfo<TypedArrayConstructorOneArgFn>(
+        NewTypedArrayWithTemplateAndLength,
+        "NewTypedArrayWithTemplateAndLength");
 
 void CodeGenerator::visitNewTypedArray(LNewTypedArray* lir) {
   Register objReg = ToRegister(lir->output());
   Register tempReg = ToRegister(lir->temp1());
   Register lengthReg = ToRegister(lir->temp2());
   LiveRegisterSet liveRegs = lir->safepoint()->liveRegs();
 
   JSObject* templateObject = lir->mir()->templateObject();
@@ -6785,101 +6733,84 @@ void CodeGenerator::visitNewTypedArrayDy
 
   masm.initTypedArraySlots(objReg, tempReg, lengthReg, liveRegs, ool->entry(),
                            ttemplate,
                            MacroAssembler::TypedArrayLength::Dynamic);
 
   masm.bind(ool->rejoin());
 }
 
-typedef TypedArrayObject* (*TypedArrayCreateWithTemplateFn)(JSContext*,
-                                                            HandleObject,
-                                                            HandleObject);
-static const VMFunction TypedArrayCreateWithTemplateInfo =
-    FunctionInfo<TypedArrayCreateWithTemplateFn>(
-        js::TypedArrayCreateWithTemplate, "TypedArrayCreateWithTemplate");
-
 void CodeGenerator::visitNewTypedArrayFromArray(LNewTypedArrayFromArray* lir) {
   pushArg(ToRegister(lir->array()));
   pushArg(ImmGCPtr(lir->mir()->templateObject()));
-  callVM(TypedArrayCreateWithTemplateInfo, lir);
-}
-
-typedef TypedArrayObject* (*TypedArrayCreateFromArrayBufferWithTemplateFn)(
-    JSContext*, HandleObject, HandleObject, HandleValue, HandleValue);
-static const VMFunction TypedArrayCreateFromArrayBufferWithTemplateInfo =
-    FunctionInfo<TypedArrayCreateFromArrayBufferWithTemplateFn>(
-        js::TypedArrayCreateWithTemplate, "TypedArrayCreateWithTemplate");
+
+  using Fn = TypedArrayObject* (*)(JSContext*, HandleObject, HandleObject);
+  callVM<Fn, js::NewTypedArrayWithTemplateAndArray>(lir);
+}
 
 void CodeGenerator::visitNewTypedArrayFromArrayBuffer(
     LNewTypedArrayFromArrayBuffer* lir) {
   pushArg(ToValue(lir, LNewTypedArrayFromArrayBuffer::LengthIndex));
   pushArg(ToValue(lir, LNewTypedArrayFromArrayBuffer::ByteOffsetIndex));
   pushArg(ToRegister(lir->arrayBuffer()));
   pushArg(ImmGCPtr(lir->mir()->templateObject()));
-  callVM(TypedArrayCreateFromArrayBufferWithTemplateInfo, lir);
+
+  using Fn = TypedArrayObject* (*)(JSContext*, HandleObject, HandleObject,
+                                   HandleValue, HandleValue);
+  callVM<Fn, js::NewTypedArrayWithTemplateAndBuffer>(lir);
 }
 
 // Out-of-line object allocation for JSOP_NEWOBJECT.
 class OutOfLineNewObject : public OutOfLineCodeBase<CodeGenerator> {
   LNewObject* lir_;
 
  public:
   explicit OutOfLineNewObject(LNewObject* lir) : lir_(lir) {}
 
   void accept(CodeGenerator* codegen) override {
     codegen->visitOutOfLineNewObject(this);
   }
 
   LNewObject* lir() const { return lir_; }
 };
 
-typedef JSObject* (*NewInitObjectWithTemplateFn)(JSContext*, HandleObject);
-static const VMFunction NewInitObjectWithTemplateInfo =
-    FunctionInfo<NewInitObjectWithTemplateFn>(NewObjectOperationWithTemplate,
-                                              "NewObjectOperationWithTemplate");
-
-typedef JSObject* (*NewInitObjectFn)(JSContext*, HandleScript, jsbytecode* pc,
-                                     NewObjectKind);
-static const VMFunction NewInitObjectInfo =
-    FunctionInfo<NewInitObjectFn>(NewObjectOperation, "NewObjectOperation");
-
-typedef PlainObject* (*ObjectCreateWithTemplateFn)(JSContext*,
-                                                   HandlePlainObject);
-static const VMFunction ObjectCreateWithTemplateInfo =
-    FunctionInfo<ObjectCreateWithTemplateFn>(ObjectCreateWithTemplate,
-                                             "ObjectCreateWithTemplate");
-
 void CodeGenerator::visitNewObjectVMCall(LNewObject* lir) {
   Register objReg = ToRegister(lir->output());
 
   MOZ_ASSERT(!lir->isCall());
   saveLive(lir);
 
   JSObject* templateObject = lir->mir()->templateObject();
 
   // If we're making a new object with a class prototype (that is, an object
   // that derives its class from its prototype instead of being
   // PlainObject::class_'d) from self-hosted code, we need a different init
   // function.
   switch (lir->mir()->mode()) {
     case MNewObject::ObjectLiteral:
       if (templateObject) {
         pushArg(ImmGCPtr(templateObject));
-        callVM(NewInitObjectWithTemplateInfo, lir);
+
+        using Fn = JSObject* (*)(JSContext*, HandleObject);
+        callVM<Fn, NewObjectOperationWithTemplate>(lir);
       } else {
         pushArg(Imm32(GenericObject));
         pushArg(ImmPtr(lir->mir()->resumePoint()->pc()));
         pushArg(ImmGCPtr(lir->mir()->block()->info().script()));
-        callVM(NewInitObjectInfo, lir);
+
+        using Fn = JSObject* (*)(JSContext*, HandleScript, jsbytecode * pc,
+                                 NewObjectKind);
+        callVM<Fn, NewObjectOperation>(lir);
       }
       break;
     case MNewObject::ObjectCreate:
       pushArg(ImmGCPtr(templateObject));
-      callVM(ObjectCreateWithTemplateInfo, lir);
+
+      using Fn = PlainObject* (*)(JSContext*, HandlePlainObject);
+      callVM<Fn, ObjectCreateWithTemplate>(lir);
       break;
   }
 
   if (ReturnReg != objReg) {
     masm.movePtr(ReturnReg, objReg);
   }
 
   restoreLive(lir);
@@ -7102,30 +7033,27 @@ void CodeGenerator::visitNewStringObject
   masm.storeValue(JSVAL_TYPE_STRING, input,
                   Address(output, StringObject::offsetOfPrimitiveValue()));
   masm.storeValue(JSVAL_TYPE_INT32, temp,
                   Address(output, StringObject::offsetOfLength()));
 
   masm.bind(ool->rejoin());
 }
 
-typedef bool (*InitElemFn)(JSContext* cx, jsbytecode* pc, HandleObject obj,
-                           HandleValue id, HandleValue value);
-static const VMFunction InitElemInfo =
-    FunctionInfo<InitElemFn>(InitElemOperation, "InitElemOperation");
-
 void CodeGenerator::visitInitElem(LInitElem* lir) {
   Register objReg = ToRegister(lir->getObject());
 
   pushArg(ToValue(lir, LInitElem::ValueIndex));
   pushArg(ToValue(lir, LInitElem::IdIndex));
   pushArg(objReg);
   pushArg(ImmPtr(lir->mir()->resumePoint()->pc()));
 
-  callVM(InitElemInfo, lir);
+  using Fn = bool (*)(JSContext * cx, jsbytecode * pc, HandleObject obj,
+                      HandleValue id, HandleValue value);
+  callVM<Fn, InitElemOperation>(lir);
 }
 
 void CodeGenerator::visitInitElemGetterSetter(LInitElemGetterSetter* lir) {
   Register obj = ToRegister(lir->object());
   Register value = ToRegister(lir->value());
 
   pushArg(value);
   pushArg(ToValue(lir, LInitElemGetterSetter::IdIndex));
@@ -7156,47 +7084,36 @@ void CodeGenerator::visitInitPropGetterS
   pushArg(obj);
   pushArg(ImmPtr(lir->mir()->resumePoint()->pc()));
 
   using Fn = bool (*)(JSContext*, jsbytecode*, HandleObject, HandlePropertyName,
                       HandleObject);
   callVM<Fn, InitPropGetterSetterOperation>(lir);
 }
 
-typedef bool (*CreateThisFn)(JSContext* cx, HandleObject callee,
-                             HandleObject newTarget, MutableHandleValue rval);
-static const VMFunction CreateThisInfoCodeGen =
-    FunctionInfo<CreateThisFn>(CreateThis, "CreateThis");
-
 void CodeGenerator::visitCreateThis(LCreateThis* lir) {
   const LAllocation* callee = lir->getCallee();
   const LAllocation* newTarget = lir->getNewTarget();
 
   if (newTarget->isConstant()) {
     pushArg(ImmGCPtr(&newTarget->toConstant()->toObject()));
   } else {
     pushArg(ToRegister(newTarget));
   }
 
   if (callee->isConstant()) {
     pushArg(ImmGCPtr(&callee->toConstant()->toObject()));
   } else {
     pushArg(ToRegister(callee));
   }
 
-  callVM(CreateThisInfoCodeGen, lir);
-}
-
-typedef JSObject* (*CreateThisWithProtoFn)(JSContext* cx, HandleFunction callee,
-                                           HandleObject newTarget,
-                                           HandleObject proto,
-                                           NewObjectKind newKind);
-static const VMFunction CreateThisWithProtoInfo =
-    FunctionInfo<CreateThisWithProtoFn>(CreateThisForFunctionWithProto,
-                                        "CreateThisForFunctionWithProto");
+  using Fn = bool (*)(JSContext * cx, HandleObject callee,
+                      HandleObject newTarget, MutableHandleValue rval);
+  callVM<Fn, jit::CreateThis>(lir);
+}
 
 void CodeGenerator::visitCreateThisWithProto(LCreateThisWithProto* lir) {
   const LAllocation* callee = lir->getCallee();
   const LAllocation* newTarget = lir->getNewTarget();
   const LAllocation* proto = lir->getPrototype();
 
   pushArg(Imm32(GenericObject));
 
@@ -7213,17 +7130,20 @@ void CodeGenerator::visitCreateThisWithP
   }
 
   if (callee->isConstant()) {
     pushArg(ImmGCPtr(&callee->toConstant()->toObject()));
   } else {
     pushArg(ToRegister(callee));
   }
 
-  callVM(CreateThisWithProtoInfo, lir);
+  using Fn = JSObject* (*)(JSContext * cx, HandleFunction callee,
+                           HandleObject newTarget, HandleObject proto,
+                           NewObjectKind newKind);
+  callVM<Fn, CreateThisForFunctionWithProto>(lir);
 }
 
 typedef JSObject* (*CreateThisWithTemplateFn)(JSContext*, HandleObject);
 static const VMFunction CreateThisWithTemplateInfo =
     FunctionInfo<CreateThisWithTemplateFn>(CreateThisWithTemplate,
                                            "CreateThisWithTemplate");
 
 void CodeGenerator::visitCreateThisWithTemplate(LCreateThisWithTemplate* lir) {
@@ -7240,24 +7160,16 @@ void CodeGenerator::visitCreateThisWithT
   bool initContents =
       !templateObj.isPlainObject() || ShouldInitFixedSlots(lir, templateObj);
   masm.createGCObject(objReg, tempReg, templateObj, lir->mir()->initialHeap(),
                       ool->entry(), initContents);
 
   masm.bind(ool->rejoin());
 }
 
-typedef JSObject* (*NewIonArgumentsObjectFn)(JSContext* cx,
-                                             JitFrameLayout* frame,
-                                             HandleObject);
-static const VMFunction NewIonArgumentsObjectInfo =
-    FunctionInfo<NewIonArgumentsObjectFn>(
-        (NewIonArgumentsObjectFn)ArgumentsObject::createForIon,
-        "ArgumentsObject::createForIon");
-
 void CodeGenerator::visitCreateArgumentsObject(LCreateArgumentsObject* lir) {
   // This should be getting constructed in the first block only, and not any OSR
   // entry blocks.
   MOZ_ASSERT(lir->mir()->block()->id() == 0);
 
   Register callObj = ToRegister(lir->getCallObject());
   Register temp = ToRegister(lir->temp0());
   Label done;
@@ -7299,17 +7211,19 @@ void CodeGenerator::visitCreateArguments
     masm.Pop(callObj);
   }
 
   masm.moveStackPtrTo(temp);
   masm.addPtr(Imm32(frameSize()), temp);
 
   pushArg(callObj);
   pushArg(temp);
-  callVM(NewIonArgumentsObjectInfo, lir);
+
+  using Fn = ArgumentsObject* (*)(JSContext*, JitFrameLayout*, HandleObject);
+  callVM<Fn, ArgumentsObject::createForIon>(lir);
 
   masm.bind(&done);
 }
 
 void CodeGenerator::visitGetArgumentsObjectArg(LGetArgumentsObjectArg* lir) {
   Register temp = ToRegister(lir->getTemp(0));
   Register argsObj = ToRegister(lir->getArgsObject());
   ValueOperand out = ToOutValue(lir);
@@ -8047,25 +7961,23 @@ void CodeGenerator::visitPowD(LPowD* ins
   masm.setupUnalignedABICall(temp);
   masm.passABIArg(value, MoveOp::DOUBLE);
   masm.passABIArg(power, MoveOp::DOUBLE);
   masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, ecmaPow), MoveOp::DOUBLE);
 
   MOZ_ASSERT(ToFloatRegister(ins->output()) == ReturnDoubleReg);
 }
 
-using PowFn = bool (*)(JSContext*, MutableHandleValue, MutableHandleValue,
-                       MutableHandleValue);
-static const VMFunction PowInfo =
-    FunctionInfo<PowFn>(js::PowValues, "PowValues");
-
 void CodeGenerator::visitPowV(LPowV* ins) {
   pushArg(ToValue(ins, LPowV::PowerInput));
   pushArg(ToValue(ins, LPowV::ValueInput));
-  callVM(PowInfo, ins);
+
+  using Fn = bool (*)(JSContext*, MutableHandleValue, MutableHandleValue,
+                      MutableHandleValue);
+  callVM<Fn, js::PowValues>(ins);
 }
 
 void CodeGenerator::visitSignI(LSignI* ins) {
   Register input = ToRegister(ins->input());
   Register output = ToRegister(ins->output());
 
   Label done;
   masm.move32(input, output);
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -1209,17 +1209,17 @@ bool MNewTypedArray::writeRecoverData(Co
 RNewTypedArray::RNewTypedArray(CompactBufferReader& reader) {}
 
 bool RNewTypedArray::recover(JSContext* cx, SnapshotIterator& iter) const {
   RootedObject templateObject(cx, &iter.read().toObject());
   RootedValue result(cx);
 
   uint32_t length = templateObject.as<TypedArrayObject>()->length();
   JSObject* resultObject =
-      TypedArrayCreateWithTemplate(cx, templateObject, length);
+      NewTypedArrayWithTemplateAndLength(cx, templateObject, length);
   if (!resultObject) {
     return false;
   }
 
   result.setObject(*resultObject);
   iter.storeInstructionResult(result);
   return true;
 }
@@ -1605,17 +1605,17 @@ RStringReplace::RStringReplace(CompactBu
 
 bool RStringReplace::recover(JSContext* cx, SnapshotIterator& iter) const {
   RootedString string(cx, iter.read().toString());
   RootedString pattern(cx, iter.read().toString());
   RootedString replace(cx, iter.read().toString());
 
   JSString* result =
       isFlatReplacement_
-          ? js::str_flat_replace_string(cx, string, pattern, replace)
+          ? js::StringFlatReplaceString(cx, string, pattern, replace)
           : js::str_replace_string_raw(cx, string, pattern, replace);
 
   if (!result) {
     return false;
   }
 
   iter.storeInstructionResult(StringValue(result));
   return true;
--- a/js/src/jit/VMFunctionList-inl.h
+++ b/js/src/jit/VMFunctionList-inl.h
@@ -1,119 +1,148 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * vim: set ts=8 sts=2 et sw=2 tw=80:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "builtin/Eval.h"
+#include "builtin/RegExp.h"
 #include "jit/BaselineIC.h"
 #include "jit/IonIC.h"
 #include "jit/JitRealm.h"
 #include "jit/VMFunctions.h"
 #include "vm/AsyncFunction.h"
 #include "vm/AsyncIteration.h"
 #include "vm/Interpreter.h"
+#include "vm/TypedArrayObject.h"
 
 #include "jit/BaselineFrame-inl.h"
 #include "vm/Interpreter-inl.h"
 
 namespace js {
 namespace jit {
 
 // List of all VM functions to be used with callVM. Each entry stores the name
 // (must be unique, used for the VMFunctionId enum and profiling) and the C++
 // function to be called. This list must be sorted on the name field.
 #define VMFUNCTION_LIST(_)                                                     \
+  _(ArgumentsObjectCreateForIon, js::ArgumentsObject::createForIon)            \
   _(AsyncFunctionAwait, js::AsyncFunctionAwait)                                \
   _(AsyncFunctionResolve, js::AsyncFunctionResolve)                            \
   _(BaselineDebugPrologue, js::jit::DebugPrologue)                             \
   _(BaselineGetFunctionThis, js::jit::BaselineGetFunctionThis)                 \
   _(BaselineThrowInitializedThis, js::jit::BaselineThrowInitializedThis)       \
   _(BaselineThrowUninitializedThis, js::jit::BaselineThrowUninitializedThis)   \
   _(BindVarOperation, js::BindVarOperation)                                    \
   _(BuiltinProtoOperation, js::BuiltinProtoOperation)                          \
   _(CheckClassHeritageOperation, js::CheckClassHeritageOperation)              \
   _(CheckGlobalOrEvalDeclarationConflicts,                                     \
     js::CheckGlobalOrEvalDeclarationConflicts)                                 \
   _(CheckIsCallable, js::jit::CheckIsCallable)                                 \
+  _(CheckOverRecursed, js::jit::CheckOverRecursed)                             \
   _(CheckOverRecursedBaseline, js::jit::CheckOverRecursedBaseline)             \
   _(CloneRegExpObject, js::CloneRegExpObject)                                  \
+  _(CopyLexicalEnvironmentObject, js::jit::CopyLexicalEnvironmentObject)       \
   _(CreateAsyncFromSyncIterator, js::CreateAsyncFromSyncIterator)              \
+  _(CreateDerivedTypedObj, js::jit::CreateDerivedTypedObj)                     \
   _(CreateGenerator, js::jit::CreateGenerator)                                 \
+  _(CreateThis, js::jit::CreateThis)                                           \
+  _(CreateThisForFunctionWithProto, js::CreateThisForFunctionWithProto)        \
   _(DebugAfterYield, js::jit::DebugAfterYield)                                 \
   _(DebugEpilogueOnBaselineReturn, js::jit::DebugEpilogueOnBaselineReturn)     \
   _(DebugLeaveLexicalEnv, js::jit::DebugLeaveLexicalEnv)                       \
   _(DebugLeaveThenFreshenLexicalEnv, js::jit::DebugLeaveThenFreshenLexicalEnv) \
   _(DebugLeaveThenPopLexicalEnv, js::jit::DebugLeaveThenPopLexicalEnv)         \
   _(DebugLeaveThenRecreateLexicalEnv,                                          \
     js::jit::DebugLeaveThenRecreateLexicalEnv)                                 \
   _(Debug_CheckSelfHosted, js::Debug_CheckSelfHosted)                          \
+  _(DeepCloneObjectLiteral, js::DeepCloneObjectLiteral)                        \
   _(DefFunOperation, js::DefFunOperation)                                      \
   _(DefLexicalOperation, js::DefLexicalOperation)                              \
   _(DefVarOperation, js::DefVarOperation)                                      \
   _(DeleteElementNonStrict, js::DeleteElementJit<false>)                       \
   _(DeleteElementStrict, js::DeleteElementJit<true>)                           \
   _(DeleteNameOperation, js::DeleteNameOperation)                              \
   _(DeletePropertyNonStrict, js::DeletePropertyJit<false>)                     \
   _(DeletePropertyStrict, js::DeletePropertyJit<true>)                         \
+  _(DirectEvalStringFromIon, js::DirectEvalStringFromIon)                      \
   _(DoToNumber, js::jit::DoToNumber)                                           \
   _(DoToNumeric, js::jit::DoToNumeric)                                         \
   _(EnterWith, js::jit::EnterWith)                                             \
   _(FinalSuspend, js::jit::FinalSuspend)                                       \
   _(FreshenLexicalEnv, js::jit::FreshenLexicalEnv)                             \
   _(FunWithProtoOperation, js::FunWithProtoOperation)                          \
   _(GetAndClearException, js::GetAndClearException)                            \
   _(GetImportOperation, js::GetImportOperation)                                \
+  _(GetIntrinsicValue, js::jit::GetIntrinsicValue)                             \
   _(GetNonSyntacticGlobalThis, js::GetNonSyntacticGlobalThis)                  \
   _(GetOrCreateModuleMetaObject, js::GetOrCreateModuleMetaObject)              \
   _(HomeObjectSuperBase, js::HomeObjectSuperBase)                              \
   _(ImplicitThisOperation, js::ImplicitThisOperation)                          \
   _(ImportMetaOperation, js::ImportMetaOperation)                              \
   _(InitElemGetterSetterOperation, js::InitElemGetterSetterOperation)          \
+  _(InitElemOperation, js::InitElemOperation)                                  \
   _(InitFunctionEnvironmentObjects, js::jit::InitFunctionEnvironmentObjects)   \
   _(InitPropGetterSetterOperation, js::InitPropGetterSetterOperation)          \
   _(InterpretResume, js::jit::InterpretResume)                                 \
   _(InterruptCheck, js::jit::InterruptCheck)                                   \
+  _(InvokeFunction, js::jit::InvokeFunction)                                   \
+  _(InvokeFunctionShuffleNewTarget, js::jit::InvokeFunctionShuffleNewTarget)   \
   _(IonBinaryArithICUpdate, js::jit::IonBinaryArithIC::update)                 \
   _(IonBindNameICUpdate, js::jit::IonBindNameIC::update)                       \
   _(IonCompareICUpdate, js::jit::IonCompareIC::update)                         \
   _(IonCompileScriptForBaseline, js::jit::IonCompileScriptForBaseline)         \
   _(IonGetIteratorICUpdate, js::jit::IonGetIteratorIC::update)                 \
   _(IonGetNameICUpdate, js::jit::IonGetNameIC::update)                         \
   _(IonGetPropSuperICUpdate, js::jit::IonGetPropSuperIC::update)               \
   _(IonGetPropertyICUpdate, js::jit::IonGetPropertyIC::update)                 \
   _(IonHasOwnICUpdate, js::jit::IonHasOwnIC::update)                           \
   _(IonInICUpdate, js::jit::IonInIC::update)                                   \
   _(IonInstanceOfICUpdate, js::jit::IonInstanceOfIC::update)                   \
   _(IonSetPropertyICUpdate, js::jit::IonSetPropertyIC::update)                 \
   _(IonUnaryArithICUpdate, js::jit::IonUnaryArithIC::update)                   \
   _(Lambda, js::Lambda)                                                        \
   _(LambdaArrow, js::LambdaArrow)                                              \
   _(LeaveWith, js::jit::LeaveWith)                                             \
+  _(LexicalEnvironmentObjectCreate, js::LexicalEnvironmentObject::create)      \
   _(MakeDefaultConstructor, js::MakeDefaultConstructor)                        \
   _(MutatePrototype, js::jit::MutatePrototype)                                 \
   _(NewArgumentsObject, js::jit::NewArgumentsObject)                           \
   _(NewArrayCopyOnWriteOperation, js::NewArrayCopyOnWriteOperation)            \
+  _(NewArrayOperation, js::NewArrayOperation)                                  \
   _(NewDenseCopyOnWriteArray, js::NewDenseCopyOnWriteArray)                    \
+  _(NewObjectOperation, js::NewObjectOperation)                                \
+  _(NewObjectOperationWithTemplate, js::NewObjectOperationWithTemplate)        \
+  _(NewTypedArrayWithTemplateAndArray, js::NewTypedArrayWithTemplateAndArray)  \
+  _(NewTypedArrayWithTemplateAndBuffer,                                        \
+    js::NewTypedArrayWithTemplateAndBuffer)                                    \
   _(NormalSuspend, js::jit::NormalSuspend)                                     \
+  _(ObjectCreateWithTemplate, js::ObjectCreateWithTemplate)                    \
   _(ObjectWithProtoOperation, js::ObjectWithProtoOperation)                    \
   _(OnDebuggerStatement, js::jit::OnDebuggerStatement)                         \
   _(OptimizeSpreadCall, js::OptimizeSpreadCall)                                \
   _(PopLexicalEnv, js::jit::PopLexicalEnv)                                     \
   _(PopVarEnv, js::jit::PopVarEnv)                                             \
+  _(PowValues, js::PowValues)                                                  \
   _(ProcessCallSiteObjOperation, js::ProcessCallSiteObjOperation)              \
   _(PushLexicalEnv, js::jit::PushLexicalEnv)                                   \
   _(PushVarEnv, js::jit::PushVarEnv)                                           \
   _(RecreateLexicalEnv, js::jit::RecreateLexicalEnv)                           \
+  _(RegExpMatcherRaw, js::RegExpMatcherRaw)                                    \
+  _(RegExpSearcherRaw, js::RegExpSearcherRaw)                                  \
+  _(RegExpTesterRaw, js::RegExpTesterRaw)                                      \
   _(SetFunctionName, js::SetFunctionName)                                      \
   _(SetIntrinsicOperation, js::SetIntrinsicOperation)                          \
   _(SetObjectElementWithReceiver, js::SetObjectElementWithReceiver)            \
   _(SetPropertySuper, js::SetPropertySuper)                                    \
   _(SingletonObjectLiteralOperation, js::SingletonObjectLiteralOperation)      \
   _(StartDynamicModuleImport, js::StartDynamicModuleImport)                    \
+  _(StringFlatReplaceString, js::StringFlatReplaceString)                      \
+  _(StringReplace, js::jit::StringReplace)                                     \
   _(SuperFunOperation, js::SuperFunOperation)                                  \
   _(ThrowBadDerivedReturn, js::jit::ThrowBadDerivedReturn)                     \
   _(ThrowCheckIsObject, js::ThrowCheckIsObject)                                \
   _(ThrowMsgOperation, js::ThrowMsgOperation)                                  \
   _(ThrowObjectCoercible, js::jit::ThrowObjectCoercible)                       \
   _(ThrowOperation, js::ThrowOperation)                                        \
   _(ThrowRuntimeLexicalError, js::jit::ThrowRuntimeLexicalError)               \
   _(ToIdOperation, js::ToIdOperation)                                          \
--- a/js/src/jit/VMFunctions.h
+++ b/js/src/jit/VMFunctions.h
@@ -13,16 +13,17 @@
 #include "jspubtd.h"
 
 #include "jit/CompileInfo.h"
 #include "jit/JitFrames.h"
 #include "vm/Interpreter.h"
 
 namespace js {
 
+class ArgumentsObject;
 class NamedLambdaObject;
 class WithScope;
 class InlineTypedObject;
 class AbstractGeneratorObject;
 class AsyncFunctionGeneratorObject;
 class RegExpObject;
 class TypedArrayObject;
 
@@ -434,16 +435,20 @@ template <>
 struct TypeToDataType<NamedLambdaObject*> {
   static const DataType result = Type_Object;
 };
 template <>
 struct TypeToDataType<LexicalEnvironmentObject*> {
   static const DataType result = Type_Object;
 };
 template <>
+struct TypeToDataType<ArgumentsObject*> {
+  static const DataType result = Type_Object;
+};
+template <>
 struct TypeToDataType<ArrayObject*> {
   static const DataType result = Type_Object;
 };
 template <>
 struct TypeToDataType<TypedArrayObject*> {
   static const DataType result = Type_Object;
 };
 template <>
--- a/js/src/vm/EnvironmentObject.cpp
+++ b/js/src/vm/EnvironmentObject.cpp
@@ -938,17 +938,17 @@ LexicalEnvironmentObject* LexicalEnviron
     env->initSlot(slot, MagicValue(JS_UNINITIALIZED_LEXICAL));
   }
 
   env->initScopeUnchecked(scope);
   return env;
 }
 
 /* static */
-LexicalEnvironmentObject* LexicalEnvironmentObject::create(
+LexicalEnvironmentObject* LexicalEnvironmentObject::createForFrame(
     JSContext* cx, Handle<LexicalScope*> scope, AbstractFramePtr frame) {
   RootedObject enclosing(cx, frame.environmentChain());
   return create(cx, scope, enclosing, gc::DefaultHeap);
 }
 
 /* static */
 LexicalEnvironmentObject* LexicalEnvironmentObject::createGlobal(
     JSContext* cx, Handle<GlobalObject*> global) {
--- a/js/src/vm/EnvironmentObject.h
+++ b/js/src/vm/EnvironmentObject.h
@@ -522,19 +522,19 @@ class LexicalEnvironmentObject : public 
     initScopeUnchecked(scope);
   }
 
  public:
   static LexicalEnvironmentObject* create(JSContext* cx,
                                           Handle<LexicalScope*> scope,
                                           HandleObject enclosing,
                                           gc::InitialHeap heap);
-  static LexicalEnvironmentObject* create(JSContext* cx,
-                                          Handle<LexicalScope*> scope,
-                                          AbstractFramePtr frame);
+  static LexicalEnvironmentObject* createForFrame(JSContext* cx,
+                                                  Handle<LexicalScope*> scope,
+                                                  AbstractFramePtr frame);
   static LexicalEnvironmentObject* createGlobal(JSContext* cx,
                                                 Handle<GlobalObject*> global);
   static LexicalEnvironmentObject* createNonSyntactic(JSContext* cx,
                                                       HandleObject enclosing,
                                                       HandleObject thisv);
   static LexicalEnvironmentObject* createHollowForDebug(
       JSContext* cx, Handle<LexicalScope*> scope);
 
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -284,17 +284,17 @@ bool InterpreterFrame::checkReturn(JSCon
 
 bool InterpreterFrame::pushVarEnvironment(JSContext* cx, HandleScope scope) {
   return js::PushVarEnvironmentObject(cx, scope, this);
 }
 
 bool InterpreterFrame::pushLexicalEnvironment(JSContext* cx,
                                               Handle<LexicalScope*> scope) {
   LexicalEnvironmentObject* env =
-      LexicalEnvironmentObject::create(cx, scope, this);
+      LexicalEnvironmentObject::createForFrame(cx, scope, this);
   if (!env) {
     return false;
   }
 
   pushOnEnvironmentChain(*env);
   return true;
 }
 
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -975,57 +975,53 @@ class TypedArrayObjectTemplate : public 
 
 #define CREATE_TYPE_FOR_TYPED_ARRAY(T, N) \
   typedef TypedArrayObjectTemplate<T> N##Array;
 JS_FOR_EACH_TYPED_ARRAY(CREATE_TYPE_FOR_TYPED_ARRAY)
 #undef CREATE_TYPE_FOR_TYPED_ARRAY
 
 } /* anonymous namespace */
 
-TypedArrayObject* js::TypedArrayCreateWithTemplate(JSContext* cx,
-                                                   HandleObject templateObj,
-                                                   int32_t len) {
+TypedArrayObject* js::NewTypedArrayWithTemplateAndLength(
+    JSContext* cx, HandleObject templateObj, int32_t len) {
   MOZ_ASSERT(templateObj->is<TypedArrayObject>());
   TypedArrayObject* tobj = &templateObj->as<TypedArrayObject>();
 
   switch (tobj->type()) {
 #define CREATE_TYPED_ARRAY(T, N)                                             \
   case Scalar::N:                                                            \
     return TypedArrayObjectTemplate<T>::makeTypedArrayWithTemplate(cx, tobj, \
                                                                    len);
     JS_FOR_EACH_TYPED_ARRAY(CREATE_TYPED_ARRAY)
 #undef CREATE_TYPED_ARRAY
     default:
       MOZ_CRASH("Unsupported TypedArray type");
   }
 }
 
-TypedArrayObject* js::TypedArrayCreateWithTemplate(JSContext* cx,
-                                                   HandleObject templateObj,
-                                                   HandleObject array) {
+TypedArrayObject* js::NewTypedArrayWithTemplateAndArray(
+    JSContext* cx, HandleObject templateObj, HandleObject array) {
   MOZ_ASSERT(templateObj->is<TypedArrayObject>());
   TypedArrayObject* tobj = &templateObj->as<TypedArrayObject>();
 
   switch (tobj->type()) {
 #define CREATE_TYPED_ARRAY(T, N)                                             \
   case Scalar::N:                                                            \
     return TypedArrayObjectTemplate<T>::makeTypedArrayWithTemplate(cx, tobj, \
                                                                    array);
     JS_FOR_EACH_TYPED_ARRAY(CREATE_TYPED_ARRAY)
 #undef CREATE_TYPED_ARRAY
     default:
       MOZ_CRASH("Unsupported TypedArray type");
   }
 }
 
-TypedArrayObject* js::TypedArrayCreateWithTemplate(JSContext* cx,
-                                                   HandleObject templateObj,
-                                                   HandleObject arrayBuffer,
-                                                   HandleValue byteOffset,
-                                                   HandleValue length) {
+TypedArrayObject* js::NewTypedArrayWithTemplateAndBuffer(
+    JSContext* cx, HandleObject templateObj, HandleObject arrayBuffer,
+    HandleValue byteOffset, HandleValue length) {
   MOZ_ASSERT(templateObj->is<TypedArrayObject>());
   TypedArrayObject* tobj = &templateObj->as<TypedArrayObject>();
 
   switch (tobj->type()) {
 #define CREATE_TYPED_ARRAY(T, N)                                    \
   case Scalar::N:                                                   \
     return TypedArrayObjectTemplate<T>::makeTypedArrayWithTemplate( \
         cx, tobj, arrayBuffer, byteOffset, length);
--- a/js/src/vm/TypedArrayObject.h
+++ b/js/src/vm/TypedArrayObject.h
@@ -188,29 +188,25 @@ class TypedArrayObject : public ArrayBuf
 
  private:
   static bool set_impl(JSContext* cx, const CallArgs& args);
 };
 
 MOZ_MUST_USE bool TypedArray_bufferGetter(JSContext* cx, unsigned argc,
                                           Value* vp);
 
-extern TypedArrayObject* TypedArrayCreateWithTemplate(JSContext* cx,
-                                                      HandleObject templateObj,
-                                                      int32_t len);
+extern TypedArrayObject* NewTypedArrayWithTemplateAndLength(
+    JSContext* cx, HandleObject templateObj, int32_t len);
 
-extern TypedArrayObject* TypedArrayCreateWithTemplate(JSContext* cx,
-                                                      HandleObject templateObj,
-                                                      HandleObject array);
+extern TypedArrayObject* NewTypedArrayWithTemplateAndArray(
+    JSContext* cx, HandleObject templateObj, HandleObject array);
 
-extern TypedArrayObject* TypedArrayCreateWithTemplate(JSContext* cx,
-                                                      HandleObject templateObj,
-                                                      HandleObject arrayBuffer,
-                                                      HandleValue byteOffset,
-                                                      HandleValue length);
+extern TypedArrayObject* NewTypedArrayWithTemplateAndBuffer(
+    JSContext* cx, HandleObject templateObj, HandleObject arrayBuffer,
+    HandleValue byteOffset, HandleValue length);
 
 inline bool IsTypedArrayClass(const Class* clasp) {
   return &TypedArrayObject::classes[0] <= clasp &&
          clasp < &TypedArrayObject::classes[Scalar::MaxTypedArrayViewType];
 }
 
 inline Scalar::Type GetTypedArrayClassType(const Class* clasp) {
   MOZ_ASSERT(IsTypedArrayClass(clasp));