Bug 1530937 part 5 - Convert more callVMs in BaselineCompiler. r=nbp
authorJan de Mooij <jdemooij@mozilla.com>
Tue, 05 Mar 2019 11:22:46 +0000
changeset 520250 a70132c4c444ca959970fbc9bd6674d04c9586e4
parent 520249 24a48c47224236b2aeaba54d39d509b34dbd188c
child 520251 4e8b8c1e0d19cf0c5bba05fd3df46254d5d68ab9
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 5 - Convert more callVMs in BaselineCompiler. r=nbp We had multiple overloads for js::Throw so I renamed the one we call here for JSOP_THROW to js::ThrowOperation. Differential Revision: https://phabricator.services.mozilla.com/D22058
js/src/jit/BaselineCompiler.cpp
js/src/jit/CodeGenerator.cpp
js/src/jit/VMFunctionList-inl.h
js/src/vm/Interpreter.cpp
js/src/vm/Interpreter.h
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -4008,39 +4008,35 @@ bool BaselineCodeGen<Handler>::emit_JSOP
   return true;
 }
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_TYPEOFEXPR() {
   return emit_JSOP_TYPEOF();
 }
 
-typedef bool (*ThrowMsgFn)(JSContext*, const unsigned);
-static const VMFunction ThrowMsgInfo =
-    FunctionInfo<ThrowMsgFn>(js::ThrowMsgOperation, "ThrowMsgOperation");
-
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_THROWMSG() {
   prepareVMCall();
   pushUint16BytecodeOperandArg();
-  return callVM(ThrowMsgInfo);
-}
-
-typedef bool (*ThrowFn)(JSContext*, HandleValue);
-static const VMFunction ThrowInfo = FunctionInfo<ThrowFn>(js::Throw, "Throw");
+
+  using Fn = bool (*)(JSContext*, const unsigned);
+  return callVM<Fn, js::ThrowMsgOperation>();
+}
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_THROW() {
   // Keep value to throw in R0.
   frame.popRegsAndSync(1);
 
   prepareVMCall();
   pushArg(R0);
 
-  return callVM(ThrowInfo);
+  using Fn = bool (*)(JSContext*, HandleValue);
+  return callVM<Fn, js::ThrowOperation>();
 }
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_TRY() {
   // Ionmonkey can't inline function with JSOP_TRY.
   if (JSScript* script = handler.maybeScript()) {
     script->setUninlineable();
   }
@@ -4102,17 +4098,19 @@ bool BaselineCodeGen<Handler>::emit_JSOP
   frame.popRegsAndSync(2);
 
   Label isReturn;
   masm.branchTestBooleanTruthy(/* branchIfTrue = */ false, R0, &isReturn);
 
   // R0 is |true|. We need to throw R1.
   prepareVMCall();
   pushArg(R1);
-  if (!callVM(ThrowInfo)) {
+
+  using Fn = bool (*)(JSContext*, HandleValue);
+  if (!callVM<Fn, js::ThrowOperation>()) {
     return false;
   }
 
   masm.bind(&isReturn);
 
   // R0 is |false|. R1 contains the resumeIndex to jump to.
   Register resumeIndexReg = R1.scratchReg();
   masm.unboxInt32(R1, resumeIndexReg);
@@ -4165,273 +4163,221 @@ MOZ_MUST_USE bool BaselineInterpreterCod
   if (ifNotDebuggee && !(*ifNotDebuggee)()) {
     return false;
   }
 
   masm.bind(&done);
   return true;
 }
 
-typedef bool (*PushLexicalEnvFn)(JSContext*, BaselineFrame*,
-                                 Handle<LexicalScope*>);
-static const VMFunction PushLexicalEnvInfo =
-    FunctionInfo<PushLexicalEnvFn>(jit::PushLexicalEnv, "PushLexicalEnv");
-
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_PUSHLEXICALENV() {
   // Call a stub to push the block on the block chain.
   prepareVMCall();
   masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
 
   pushScriptScopeArg();
   pushArg(R0.scratchReg());
 
-  return callVM(PushLexicalEnvInfo);
-}
-
-typedef bool (*PopLexicalEnvFn)(JSContext*, BaselineFrame*);
-static const VMFunction PopLexicalEnvInfo =
-    FunctionInfo<PopLexicalEnvFn>(jit::PopLexicalEnv, "PopLexicalEnv");
-
-typedef bool (*DebugLeaveThenPopLexicalEnvFn)(JSContext*, BaselineFrame*,
-                                              jsbytecode*);
-static const VMFunction DebugLeaveThenPopLexicalEnvInfo =
-    FunctionInfo<DebugLeaveThenPopLexicalEnvFn>(
-        jit::DebugLeaveThenPopLexicalEnv, "DebugLeaveThenPopLexicalEnv");
+  using Fn = bool (*)(JSContext*, BaselineFrame*, Handle<LexicalScope*>);
+  return callVM<Fn, jit::PushLexicalEnv>();
+}
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_POPLEXICALENV() {
   frame.syncStack(0);
 
   masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
 
   auto ifDebuggee = [this]() {
     prepareVMCall();
     pushBytecodePCArg();
     pushArg(R0.scratchReg());
-    return callVM(DebugLeaveThenPopLexicalEnvInfo);
+
+    using Fn = bool (*)(JSContext*, BaselineFrame*, jsbytecode*);
+    return callVM<Fn, jit::DebugLeaveThenPopLexicalEnv>();
   };
   auto ifNotDebuggee = [this]() {
     prepareVMCall();
     pushArg(R0.scratchReg());
-    return callVM(PopLexicalEnvInfo);
+
+    using Fn = bool (*)(JSContext*, BaselineFrame*);
+    return callVM<Fn, jit::PopLexicalEnv>();
   };
   return emitDebugInstrumentation(ifDebuggee, mozilla::Some(ifNotDebuggee));
 }
 
-typedef bool (*FreshenLexicalEnvFn)(JSContext*, BaselineFrame*);
-static const VMFunction FreshenLexicalEnvInfo =
-    FunctionInfo<FreshenLexicalEnvFn>(jit::FreshenLexicalEnv,
-                                      "FreshenLexicalEnv");
-
-typedef bool (*DebugLeaveThenFreshenLexicalEnvFn)(JSContext*, BaselineFrame*,
-                                                  jsbytecode*);
-static const VMFunction DebugLeaveThenFreshenLexicalEnvInfo =
-    FunctionInfo<DebugLeaveThenFreshenLexicalEnvFn>(
-        jit::DebugLeaveThenFreshenLexicalEnv,
-        "DebugLeaveThenFreshenLexicalEnv");
-
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_FRESHENLEXICALENV() {
   frame.syncStack(0);
 
   masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
 
   auto ifDebuggee = [this]() {
     prepareVMCall();
     pushBytecodePCArg();
     pushArg(R0.scratchReg());
-    return callVM(DebugLeaveThenFreshenLexicalEnvInfo);
+
+    using Fn = bool (*)(JSContext*, BaselineFrame*, jsbytecode*);
+    return callVM<Fn, jit::DebugLeaveThenFreshenLexicalEnv>();
   };
   auto ifNotDebuggee = [this]() {
     prepareVMCall();
     pushArg(R0.scratchReg());
-    return callVM(FreshenLexicalEnvInfo);
+
+    using Fn = bool (*)(JSContext*, BaselineFrame*);
+    return callVM<Fn, jit::FreshenLexicalEnv>();
   };
   return emitDebugInstrumentation(ifDebuggee, mozilla::Some(ifNotDebuggee));
 }
 
-typedef bool (*RecreateLexicalEnvFn)(JSContext*, BaselineFrame*);
-static const VMFunction RecreateLexicalEnvInfo =
-    FunctionInfo<RecreateLexicalEnvFn>(jit::RecreateLexicalEnv,
-                                       "RecreateLexicalEnv");
-
-typedef bool (*DebugLeaveThenRecreateLexicalEnvFn)(JSContext*, BaselineFrame*,
-                                                   jsbytecode*);
-static const VMFunction DebugLeaveThenRecreateLexicalEnvInfo =
-    FunctionInfo<DebugLeaveThenRecreateLexicalEnvFn>(
-        jit::DebugLeaveThenRecreateLexicalEnv,
-        "DebugLeaveThenRecreateLexicalEnv");
-
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_RECREATELEXICALENV() {
   frame.syncStack(0);
 
   masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
 
   auto ifDebuggee = [this]() {
     prepareVMCall();
     pushBytecodePCArg();
     pushArg(R0.scratchReg());
-    return callVM(DebugLeaveThenRecreateLexicalEnvInfo);
+
+    using Fn = bool (*)(JSContext*, BaselineFrame*, jsbytecode*);
+    return callVM<Fn, jit::DebugLeaveThenRecreateLexicalEnv>();
   };
   auto ifNotDebuggee = [this]() {
     prepareVMCall();
     pushArg(R0.scratchReg());
-    return callVM(RecreateLexicalEnvInfo);
+
+    using Fn = bool (*)(JSContext*, BaselineFrame*);
+    return callVM<Fn, jit::RecreateLexicalEnv>();
   };
   return emitDebugInstrumentation(ifDebuggee, mozilla::Some(ifNotDebuggee));
 }
 
-typedef bool (*DebugLeaveLexicalEnvFn)(JSContext*, BaselineFrame*, jsbytecode*);
-static const VMFunction DebugLeaveLexicalEnvInfo =
-    FunctionInfo<DebugLeaveLexicalEnvFn>(jit::DebugLeaveLexicalEnv,
-                                         "DebugLeaveLexicalEnv");
-
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_DEBUGLEAVELEXICALENV() {
   auto ifDebuggee = [this]() {
     prepareVMCall();
     masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
     pushBytecodePCArg();
     pushArg(R0.scratchReg());
-    return callVM(DebugLeaveLexicalEnvInfo);
+
+    using Fn = bool (*)(JSContext*, BaselineFrame*, jsbytecode*);
+    return callVM<Fn, jit::DebugLeaveLexicalEnv>();
   };
   return emitDebugInstrumentation(ifDebuggee);
 }
 
-typedef bool (*PushVarEnvFn)(JSContext*, BaselineFrame*, HandleScope);
-static const VMFunction PushVarEnvInfo =
-    FunctionInfo<PushVarEnvFn>(jit::PushVarEnv, "PushVarEnv");
-
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_PUSHVARENV() {
   prepareVMCall();
   masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
   pushScriptScopeArg();
   pushArg(R0.scratchReg());
 
-  return callVM(PushVarEnvInfo);
-}
-
-typedef bool (*PopVarEnvFn)(JSContext*, BaselineFrame*);
-static const VMFunction PopVarEnvInfo =
-    FunctionInfo<PopVarEnvFn>(jit::PopVarEnv, "PopVarEnv");
+  using Fn = bool (*)(JSContext*, BaselineFrame*, HandleScope);
+  return callVM<Fn, jit::PushVarEnv>();
+}
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_POPVARENV() {
   prepareVMCall();
   masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
   pushArg(R0.scratchReg());
 
-  return callVM(PopVarEnvInfo);
-}
-
-typedef bool (*EnterWithFn)(JSContext*, BaselineFrame*, HandleValue,
-                            Handle<WithScope*>);
-static const VMFunction EnterWithInfo =
-    FunctionInfo<EnterWithFn>(jit::EnterWith, "EnterWith");
+  using Fn = bool (*)(JSContext*, BaselineFrame*);
+  return callVM<Fn, jit::PopVarEnv>();
+}
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_ENTERWITH() {
   // Pop "with" object to R0.
   frame.popRegsAndSync(1);
 
   // Call a stub to push the object onto the environment chain.
   prepareVMCall();
   masm.loadBaselineFramePtr(BaselineFrameReg, R1.scratchReg());
 
   pushScriptScopeArg();
   pushArg(R0);
   pushArg(R1.scratchReg());
 
-  return callVM(EnterWithInfo);
-}
-
-typedef bool (*LeaveWithFn)(JSContext*, BaselineFrame*);
-static const VMFunction LeaveWithInfo =
-    FunctionInfo<LeaveWithFn>(jit::LeaveWith, "LeaveWith");
+  using Fn =
+      bool (*)(JSContext*, BaselineFrame*, HandleValue, Handle<WithScope*>);
+  return callVM<Fn, jit::EnterWith>();
+}
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_LEAVEWITH() {
   // Call a stub to pop the with object from the environment chain.
   prepareVMCall();
 
   masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
   pushArg(R0.scratchReg());
 
-  return callVM(LeaveWithInfo);
-}
-
-typedef bool (*GetAndClearExceptionFn)(JSContext*, MutableHandleValue);
-static const VMFunction GetAndClearExceptionInfo =
-    FunctionInfo<GetAndClearExceptionFn>(GetAndClearException,
-                                         "GetAndClearException");
+  using Fn = bool (*)(JSContext*, BaselineFrame*);
+  return callVM<Fn, jit::LeaveWith>();
+}
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_EXCEPTION() {
   prepareVMCall();
 
-  if (!callVM(GetAndClearExceptionInfo)) {
+  using Fn = bool (*)(JSContext*, MutableHandleValue);
+  if (!callVM<Fn, GetAndClearException>()) {
     return false;
   }
 
   frame.push(R0);
   return true;
 }
 
-typedef bool (*OnDebuggerStatementFn)(JSContext*, BaselineFrame*,
-                                      jsbytecode* pc, bool*);
-static const VMFunction OnDebuggerStatementInfo =
-    FunctionInfo<OnDebuggerStatementFn>(jit::OnDebuggerStatement,
-                                        "OnDebuggerStatement");
-
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_DEBUGGER() {
   prepareVMCall();
   pushBytecodePCArg();
 
   frame.assertSyncedStack();
   masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
   pushArg(R0.scratchReg());
 
-  if (!callVM(OnDebuggerStatementInfo)) {
+  using Fn = bool (*)(JSContext*, BaselineFrame*, jsbytecode*, bool*);
+  if (!callVM<Fn, jit::OnDebuggerStatement>()) {
     return false;
   }
 
   // If the stub returns |true|, return the frame's return value.
   Label done;
   masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, &done);
   {
     masm.loadValue(frame.addressOfReturnValue(), JSReturnOperand);
     masm.jump(&return_);
   }
   masm.bind(&done);
   return true;
 }
 
-typedef bool (*DebugEpilogueFn)(JSContext*, BaselineFrame*, jsbytecode*);
-static const VMFunction DebugEpilogueInfo = FunctionInfo<DebugEpilogueFn>(
-    jit::DebugEpilogueOnBaselineReturn, "DebugEpilogueOnBaselineReturn");
-
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emitReturn() {
   auto ifDebuggee = [this]() {
     // Move return value into the frame's rval slot.
     masm.storeValue(JSReturnOperand, frame.addressOfReturnValue());
     masm.or32(Imm32(BaselineFrame::HAS_RVAL), frame.addressOfFlags());
 
     // Load BaselineFrame pointer in R0.
     frame.syncStack(0);
     masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
 
     prepareVMCall();
     pushBytecodePCArg();
     pushArg(R0.scratchReg());
-    if (!callVM(DebugEpilogueInfo)) {
+
+    using Fn = bool (*)(JSContext*, BaselineFrame*, jsbytecode*);
+    if (!callVM<Fn, jit::DebugEpilogueOnBaselineReturn>()) {
       return false;
     }
 
     // Fix up the RetAddrEntry appended by callVM for on-stack recompilation.
     handler.markLastRetAddrEntryKind(RetAddrEntry::Kind::DebugEpilogue);
 
     masm.loadValue(frame.addressOfReturnValue(), JSReturnOperand);
     return true;
@@ -4486,83 +4432,74 @@ bool BaselineCodeGen<Handler>::emit_JSOP
                       &done);
     masm.loadValue(frame.addressOfReturnValue(), JSReturnOperand);
     masm.bind(&done);
   }
 
   return emitReturn();
 }
 
-typedef bool (*ToIdFn)(JSContext*, HandleValue, MutableHandleValue);
-static const VMFunction ToIdInfo =
-    FunctionInfo<ToIdFn>(js::ToIdOperation, "ToIdOperation");
-
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_TOID() {
   // Load index in R0, but keep values on the stack for the decompiler.
   frame.syncStack(0);
   masm.loadValue(frame.addressOfStackValue(-1), R0);
 
   // No-op if the index is trivally convertable to an id.
   Label done;
   masm.branchTestInt32(Assembler::Equal, R0, &done);
   masm.branchTestString(Assembler::Equal, R0, &done);
   masm.branchTestSymbol(Assembler::Equal, R0, &done);
 
   prepareVMCall();
 
   pushArg(R0);
 
-  if (!callVM(ToIdInfo)) {
+  using Fn = bool (*)(JSContext*, HandleValue, MutableHandleValue);
+  if (!callVM<Fn, js::ToIdOperation>()) {
     return false;
   }
 
   masm.bind(&done);
   frame.pop();  // Pop index.
   frame.push(R0);
   return true;
 }
 
-typedef JSObject* (*ToAsyncIterFn)(JSContext*, HandleObject, HandleValue);
-static const VMFunction ToAsyncIterInfo =
-    FunctionInfo<ToAsyncIterFn>(js::CreateAsyncFromSyncIterator, "ToAsyncIter");
-
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_TOASYNCITER() {
   frame.syncStack(0);
   masm.unboxObject(frame.addressOfStackValue(-2), R0.scratchReg());
   masm.loadValue(frame.addressOfStackValue(-1), R1);
 
   prepareVMCall();
   pushArg(R1);
   pushArg(R0.scratchReg());
 
-  if (!callVM(ToAsyncIterInfo)) {
+  using Fn = JSObject* (*)(JSContext*, HandleObject, HandleValue);
+  if (!callVM<Fn, js::CreateAsyncFromSyncIterator>()) {
     return false;
   }
 
   masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
   frame.popn(2);
   frame.push(R0);
   return true;
 }
 
-typedef bool (*TrySkipAwaitFn)(JSContext*, HandleValue, MutableHandleValue);
-static const VMFunction TrySkipAwaitInfo =
-    FunctionInfo<TrySkipAwaitFn>(jit::TrySkipAwait, "TrySkipAwait");
-
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_TRYSKIPAWAIT() {
   frame.syncStack(0);
   masm.loadValue(frame.addressOfStackValue(-1), R0);
 
   prepareVMCall();
   pushArg(R0);
 
-  if (!callVM(TrySkipAwaitInfo)) {
+  using Fn = bool (*)(JSContext*, HandleValue, MutableHandleValue);
+  if (!callVM<Fn, jit::TrySkipAwait>()) {
     return false;
   }
 
   Label cannotSkip, done;
   masm.branchTestMagicValue(Assembler::Equal, R0, JS_CANNOT_SKIP_AWAIT,
                             &cannotSkip);
   masm.moveValue(BooleanValue(true), R1);
   masm.jump(&done);
@@ -4574,118 +4511,101 @@ bool BaselineCodeGen<Handler>::emit_JSOP
   masm.bind(&done);
 
   frame.pop();
   frame.push(R0);
   frame.push(R1);
   return true;
 }
 
-typedef JSObject* (*AsyncFunctionAwaitFn)(JSContext*,
-                                          Handle<AsyncFunctionGeneratorObject*>,
-                                          HandleValue);
-static const VMFunction AsyncFunctionAwaitInfo =
-    FunctionInfo<AsyncFunctionAwaitFn>(js::AsyncFunctionAwait,
-                                       "AsyncFunctionAwait");
-
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_ASYNCAWAIT() {
   frame.syncStack(0);
   masm.loadValue(frame.addressOfStackValue(-2), R1);
   masm.unboxObject(frame.addressOfStackValue(-1), R0.scratchReg());
 
   prepareVMCall();
   pushArg(R1);
   pushArg(R0.scratchReg());
 
-  if (!callVM(AsyncFunctionAwaitInfo)) {
+  using Fn = JSObject* (*)(JSContext*, Handle<AsyncFunctionGeneratorObject*>,
+                           HandleValue);
+  if (!callVM<Fn, js::AsyncFunctionAwait>()) {
     return false;
   }
 
   masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
   frame.popn(2);
   frame.push(R0);
   return true;
 }
 
-typedef JSObject* (*AsyncFunctionResolveFn)(
-    JSContext*, Handle<AsyncFunctionGeneratorObject*>, HandleValue,
-    AsyncFunctionResolveKind);
-static const VMFunction AsyncFunctionResolveInfo =
-    FunctionInfo<AsyncFunctionResolveFn>(js::AsyncFunctionResolve,
-                                         "AsyncFunctionResolve");
-
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_ASYNCRESOLVE() {
   frame.syncStack(0);
   masm.loadValue(frame.addressOfStackValue(-2), R1);
   masm.unboxObject(frame.addressOfStackValue(-1), R0.scratchReg());
 
   prepareVMCall();
   pushUint8BytecodeOperandArg();
   pushArg(R1);
   pushArg(R0.scratchReg());
 
-  if (!callVM(AsyncFunctionResolveInfo)) {
+  using Fn = JSObject* (*)(JSContext*, Handle<AsyncFunctionGeneratorObject*>,
+                           HandleValue, AsyncFunctionResolveKind);
+  if (!callVM<Fn, js::AsyncFunctionResolve>()) {
     return false;
   }
 
   masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
   frame.popn(2);
   frame.push(R0);
   return true;
 }
 
-typedef bool (*ThrowObjectCoercibleFn)(JSContext*, HandleValue);
-static const VMFunction ThrowObjectCoercibleInfo =
-    FunctionInfo<ThrowObjectCoercibleFn>(ThrowObjectCoercible,
-                                         "ThrowObjectCoercible");
-
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_CHECKOBJCOERCIBLE() {
   frame.syncStack(0);
   masm.loadValue(frame.addressOfStackValue(-1), R0);
 
   Label fail, done;
 
   masm.branchTestUndefined(Assembler::Equal, R0, &fail);
   masm.branchTestNull(Assembler::NotEqual, R0, &done);
 
   masm.bind(&fail);
   prepareVMCall();
 
   pushArg(R0);
 
-  if (!callVM(ThrowObjectCoercibleInfo)) {
+  using Fn = bool (*)(JSContext*, HandleValue);
+  if (!callVM<Fn, ThrowObjectCoercible>()) {
     return false;
   }
 
   masm.bind(&done);
   return true;
 }
 
-typedef JSString* (*ToStringFn)(JSContext*, HandleValue);
-static const VMFunction ToStringInfo =
-    FunctionInfo<ToStringFn>(ToStringSlow, "ToStringSlow");
-
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_TOSTRING() {
   // Keep top stack value in R0.
   frame.popRegsAndSync(1);
 
   // Inline path for string.
   Label done;
   masm.branchTestString(Assembler::Equal, R0, &done);
 
   prepareVMCall();
 
   pushArg(R0);
 
   // Call ToStringSlow which doesn't handle string inputs.
-  if (!callVM(ToStringInfo)) {
+  using Fn = JSString* (*)(JSContext*, HandleValue);
+  if (!callVM<Fn, ToStringSlow<CanGC>>()) {
     return false;
   }
 
   masm.tagValue(JSVAL_TYPE_STRING, ReturnReg, R0);
 
   masm.bind(&done);
   frame.push(R0);
   return true;
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -11110,17 +11110,17 @@ void CodeGenerator::visitSetPropertyCach
   addSetPropertyCache(ins, liveRegs, objReg, temp, tempDouble, tempF32, id,
                       value, ins->mir()->strict(),
                       ins->mir()->needsPostBarrier(),
                       ins->mir()->needsTypeBarrier(), ins->mir()->guardHoles());
 }
 
 typedef bool (*ThrowFn)(JSContext*, HandleValue);
 static const VMFunction ThrowInfoCodeGen =
-    FunctionInfo<ThrowFn>(js::Throw, "Throw");
+    FunctionInfo<ThrowFn>(js::ThrowOperation, "ThrowOperation");
 
 void CodeGenerator::visitThrow(LThrow* lir) {
   pushArg(ToValue(lir, LThrow::Value));
   callVM(ThrowInfoCodeGen, lir);
 }
 
 typedef bool (*BitNotFn)(JSContext*, MutableHandleValue, MutableHandleValue);
 static const VMFunction BitNotInfo = FunctionInfo<BitNotFn>(BitNot, "BitNot");
--- a/js/src/jit/VMFunctionList-inl.h
+++ b/js/src/jit/VMFunctionList-inl.h
@@ -2,64 +2,91 @@
  * 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 "jit/BaselineIC.h"
 #include "jit/JitRealm.h"
 #include "jit/VMFunctions.h"
+#include "vm/AsyncFunction.h"
+#include "vm/AsyncIteration.h"
 #include "vm/Interpreter.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(_)                                                   \
-  _(BaselineDebugPrologue, js::jit::DebugPrologue)                           \
-  _(BaselineGetFunctionThis, js::jit::BaselineGetFunctionThis)               \
-  _(BaselineThrowInitializedThis, js::jit::BaselineThrowInitializedThis)     \
-  _(BaselineThrowUninitializedThis, js::jit::BaselineThrowUninitializedThis) \
-  _(BindVarOperation, js::BindVarOperation)                                  \
-  _(CheckIsCallable, js::jit::CheckIsCallable)                               \
-  _(CheckOverRecursedBaseline, js::jit::CheckOverRecursedBaseline)           \
-  _(CloneRegExpObject, js::CloneRegExpObject)                                \
-  _(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>)                       \
-  _(GetImportOperation, js::GetImportOperation)                              \
-  _(GetNonSyntacticGlobalThis, js::GetNonSyntacticGlobalThis)                \
-  _(InitElemGetterSetterOperation, js::InitElemGetterSetterOperation)        \
-  _(InitPropGetterSetterOperation, js::InitPropGetterSetterOperation)        \
-  _(InterruptCheck, js::jit::InterruptCheck)                                 \
-  _(IonCompileScriptForBaseline, js::jit::IonCompileScriptForBaseline)       \
-  _(Lambda, js::Lambda)                                                      \
-  _(LambdaArrow, js::LambdaArrow)                                            \
-  _(MutatePrototype, js::jit::MutatePrototype)                               \
-  _(NewArrayCopyOnWriteOperation, js::NewArrayCopyOnWriteOperation)          \
-  _(NewDenseCopyOnWriteArray, js::NewDenseCopyOnWriteArray)                  \
-  _(OptimizeSpreadCall, js::OptimizeSpreadCall)                              \
-  _(ProcessCallSiteObjOperation, js::ProcessCallSiteObjOperation)            \
-  _(SetFunctionName, js::SetFunctionName)                                    \
-  _(SetIntrinsicOperation, js::SetIntrinsicOperation)                        \
-  _(SetPropertySuper, js::SetPropertySuper)                                  \
-  _(SingletonObjectLiteralOperation, js::SingletonObjectLiteralOperation)    \
-  _(ThrowBadDerivedReturn, js::jit::ThrowBadDerivedReturn)                   \
-  _(ThrowCheckIsObject, js::ThrowCheckIsObject)                              \
-  _(ThrowRuntimeLexicalError, js::jit::ThrowRuntimeLexicalError)
+#define VMFUNCTION_LIST(_)                                                     \
+  _(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)                                    \
+  _(CheckIsCallable, js::jit::CheckIsCallable)                                 \
+  _(CheckOverRecursedBaseline, js::jit::CheckOverRecursedBaseline)             \
+  _(CloneRegExpObject, js::CloneRegExpObject)                                  \
+  _(CreateAsyncFromSyncIterator, js::CreateAsyncFromSyncIterator)              \
+  _(DebugEpilogueOnBaselineReturn, js::jit::DebugEpilogueOnBaselineReturn)     \
+  _(DebugLeaveLexicalEnv, js::jit::DebugLeaveLexicalEnv)                       \
+  _(DebugLeaveThenFreshenLexicalEnv, js::jit::DebugLeaveThenFreshenLexicalEnv) \
+  _(DebugLeaveThenPopLexicalEnv, js::jit::DebugLeaveThenPopLexicalEnv)         \
+  _(DebugLeaveThenRecreateLexicalEnv,                                          \
+    js::jit::DebugLeaveThenRecreateLexicalEnv)                                 \
+  _(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>)                         \
+  _(EnterWith, js::jit::EnterWith)                                             \
+  _(FreshenLexicalEnv, js::jit::FreshenLexicalEnv)                             \
+  _(GetAndClearException, js::GetAndClearException)                            \
+  _(GetImportOperation, js::GetImportOperation)                                \
+  _(GetNonSyntacticGlobalThis, js::GetNonSyntacticGlobalThis)                  \
+  _(InitElemGetterSetterOperation, js::InitElemGetterSetterOperation)          \
+  _(InitPropGetterSetterOperation, js::InitPropGetterSetterOperation)          \
+  _(InterruptCheck, js::jit::InterruptCheck)                                   \
+  _(IonCompileScriptForBaseline, js::jit::IonCompileScriptForBaseline)         \
+  _(Lambda, js::Lambda)                                                        \
+  _(LambdaArrow, js::LambdaArrow)                                              \
+  _(LeaveWith, js::jit::LeaveWith)                                             \
+  _(MutatePrototype, js::jit::MutatePrototype)                                 \
+  _(NewArrayCopyOnWriteOperation, js::NewArrayCopyOnWriteOperation)            \
+  _(NewDenseCopyOnWriteArray, js::NewDenseCopyOnWriteArray)                    \
+  _(OnDebuggerStatement, js::jit::OnDebuggerStatement)                         \
+  _(OptimizeSpreadCall, js::OptimizeSpreadCall)                                \
+  _(PopLexicalEnv, js::jit::PopLexicalEnv)                                     \
+  _(PopVarEnv, js::jit::PopVarEnv)                                             \
+  _(ProcessCallSiteObjOperation, js::ProcessCallSiteObjOperation)              \
+  _(PushLexicalEnv, js::jit::PushLexicalEnv)                                   \
+  _(PushVarEnv, js::jit::PushVarEnv)                                           \
+  _(RecreateLexicalEnv, js::jit::RecreateLexicalEnv)                           \
+  _(SetFunctionName, js::SetFunctionName)                                      \
+  _(SetIntrinsicOperation, js::SetIntrinsicOperation)                          \
+  _(SetPropertySuper, js::SetPropertySuper)                                    \
+  _(SingletonObjectLiteralOperation, js::SingletonObjectLiteralOperation)      \
+  _(ThrowBadDerivedReturn, js::jit::ThrowBadDerivedReturn)                     \
+  _(ThrowCheckIsObject, js::ThrowCheckIsObject)                                \
+  _(ThrowMsgOperation, js::ThrowMsgOperation)                                  \
+  _(ThrowObjectCoercible, js::jit::ThrowObjectCoercible)                       \
+  _(ThrowOperation, js::ThrowOperation)                                        \
+  _(ThrowRuntimeLexicalError, js::jit::ThrowRuntimeLexicalError)               \
+  _(ToIdOperation, js::ToIdOperation)                                          \
+  _(ToStringSlow, js::ToStringSlow<CanGC>)                                     \
+  _(TrySkipAwait, js::jit::TrySkipAwait)
 
 enum class VMFunctionId {
 #define DEF_ID(name, fp) name,
   VMFUNCTION_LIST(DEF_ID)
 #undef DEF_ID
       Count
 };
 
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -3876,17 +3876,17 @@ static MOZ_NEVER_INLINE JS_HAZ_JSNATIVE_
 
     CASE(JSOP_FINALLY) { CHECK_BRANCH(); }
     END_CASE(JSOP_FINALLY)
 
     CASE(JSOP_THROW) {
       CHECK_BRANCH();
       ReservedRooted<Value> v(&rootValue0);
       POP_COPY_TO(v);
-      MOZ_ALWAYS_FALSE(Throw(cx, v));
+      MOZ_ALWAYS_FALSE(ThrowOperation(cx, v));
       /* let the code at error try to catch the exception. */
       goto error;
     }
 
     CASE(JSOP_INSTANCEOF) {
       ReservedRooted<Value> rref(&rootValue0, REGS.sp[-1]);
       if (HandleValue(rref).isPrimitive()) {
         ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS, -1, rref, nullptr);
@@ -4398,17 +4398,17 @@ leave_on_safe_point:
   return interpReturnOK;
 
 prologue_error:
   interpReturnOK = false;
   frameHalfInitialized = true;
   goto prologue_return_continuation;
 }
 
-bool js::Throw(JSContext* cx, HandleValue v) {
+bool js::ThrowOperation(JSContext* cx, HandleValue v) {
   MOZ_ASSERT(!cx->isExceptionPending());
   cx->setPendingException(v);
   return false;
 }
 
 bool js::GetProperty(JSContext* cx, HandleValue v, HandlePropertyName name,
                      MutableHandleValue vp) {
   if (name == cx->names().length) {
--- a/js/src/vm/Interpreter.h
+++ b/js/src/vm/Interpreter.h
@@ -420,17 +420,17 @@ class MOZ_STACK_CLASS TryNoteIter {
   const JSTryNote* operator*() const { return tn_; }
 };
 
 bool HandleClosingGeneratorReturn(JSContext* cx, AbstractFramePtr frame,
                                   bool ok);
 
 /************************************************************************/
 
-bool Throw(JSContext* cx, HandleValue v);
+bool ThrowOperation(JSContext* cx, HandleValue v);
 
 bool GetProperty(JSContext* cx, HandleValue value, HandlePropertyName name,
                  MutableHandleValue vp);
 
 JSObject* Lambda(JSContext* cx, HandleFunction fun, HandleObject parent);
 
 JSObject* LambdaArrow(JSContext* cx, HandleFunction fun, HandleObject parent,
                       HandleValue newTargetv);