Bug 1519779 - Add some helper methods for pushing script/pc or script name/object/scope for VM calls in BaselineCodeGen. r=djvj
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 16 Jan 2019 21:05:31 +0000
changeset 514229 00614ec6e765206c325364b51b8810fddf29234d
parent 514228 eff7fd1e573cc0682e3080ee2370eac840e57b9d
child 514230 824fafc39762398f102ee7f17cac42c3fd04ed89
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdjvj
bugs1519779
milestone66.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 1519779 - Add some helper methods for pushing script/pc or script name/object/scope for VM calls in BaselineCodeGen. r=djvj Interpreter and compiler will implement these differently, but this allows sharing codegen for a large number of JSOps. Differential Revision: https://phabricator.services.mozilla.com/D16438
js/src/jit/BaselineCompiler.cpp
js/src/jit/BaselineCompiler.h
js/src/vm/JSScript-inl.h
js/src/vm/JSScript.h
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -774,27 +774,111 @@ void BaselineCompiler::emitIsDebuggeeChe
     masm.setupUnalignedABICall(R0.scratchReg());
     masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
     masm.passABIArg(R0.scratchReg());
     masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, jit::FrameIsDebuggeeCheck));
     masm.Pop(BaselineFrameReg);
   }
 }
 
+template <>
+void BaselineCompilerCodeGen::pushScriptArg() {
+  pushArg(ImmGCPtr(script));
+}
+
+template <>
+void BaselineInterpreterCodeGen::pushScriptArg() {
+  MOZ_CRASH("NYI: interpreter pushScriptArg");
+}
+
+template <>
+void BaselineCompilerCodeGen::pushBytecodePCArg() {
+  pushArg(ImmPtr(pc));
+}
+
+template <>
+void BaselineInterpreterCodeGen::pushBytecodePCArg() {
+  // This will be something like pushArg(Address(...));
+  MOZ_CRASH("NYI: interpreter pushBytecodePCArg");
+}
+
+template <>
+void BaselineCompilerCodeGen::pushScriptNameArg() {
+  pushArg(ImmGCPtr(script->getName(pc)));
+}
+
+template <>
+void BaselineInterpreterCodeGen::pushScriptNameArg() {
+  MOZ_CRASH("NYI: interpreter pushScriptNameArg");
+}
+
+template <>
+void BaselineCompilerCodeGen::pushScriptObjectArg(ScriptObjectType type) {
+  switch (type) {
+    case ScriptObjectType::RegExp:
+      pushArg(ImmGCPtr(script->getRegExp(pc)));
+      return;
+    case ScriptObjectType::Function:
+      pushArg(ImmGCPtr(script->getFunction(pc)));
+      return;
+    case ScriptObjectType::ObjectLiteral:
+      pushArg(ImmGCPtr(script->getObject(pc)));
+      return;
+  }
+  MOZ_CRASH("Unexpected object type");
+}
+
+template <>
+void BaselineInterpreterCodeGen::pushScriptObjectArg(ScriptObjectType type) {
+  MOZ_CRASH("NYI: interpreter pushScriptObjectArg");
+}
+
+template <>
+void BaselineCompilerCodeGen::pushScriptScopeArg() {
+  pushArg(ImmGCPtr(script->getScope(pc)));
+}
+
+template <>
+void BaselineInterpreterCodeGen::pushScriptScopeArg() {
+  MOZ_CRASH("NYI: interpreter pushScriptScopeArg");
+}
+
+template <>
+void BaselineCompilerCodeGen::pushUint8BytecodeOperandArg() {
+  MOZ_ASSERT(JOF_OPTYPE(JSOp(*pc)) == JOF_UINT8);
+  pushArg(Imm32(GET_UINT8(pc)));
+}
+
+template <>
+void BaselineInterpreterCodeGen::pushUint8BytecodeOperandArg() {
+  MOZ_CRASH("NYI: interpreter pushUint8BytecodeOperandArg");
+}
+
+template <>
+void BaselineCompilerCodeGen::pushUint16BytecodeOperandArg() {
+  MOZ_ASSERT(JOF_OPTYPE(JSOp(*pc)) == JOF_UINT16);
+  pushArg(Imm32(GET_UINT16(pc)));
+}
+
+template <>
+void BaselineInterpreterCodeGen::pushUint16BytecodeOperandArg() {
+  MOZ_CRASH("NYI: interpreter pushUint16BytecodeOperandArg");
+}
+
 typedef bool (*DebugPrologueFn)(JSContext*, BaselineFrame*, jsbytecode*, bool*);
 static const VMFunction DebugPrologueInfo =
     FunctionInfo<DebugPrologueFn>(jit::DebugPrologue, "DebugPrologue");
 
 bool BaselineCompiler::emitDebugPrologue() {
   if (compileDebugInstrumentation()) {
     // Load pointer to BaselineFrame in R0.
     masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
 
     prepareVMCall();
-    pushArg(ImmPtr(pc));
+    pushBytecodePCArg();
     pushArg(R0.scratchReg());
     if (!callVM(DebugPrologueInfo)) {
       return false;
     }
 
     // Fix up the RetAddrEntry appended by callVM for on-stack recompilation.
     retAddrEntries_.back().setKind(RetAddrEntry::Kind::DebugPrologue);
 
@@ -861,17 +945,17 @@ bool BaselineCompiler::initEnvironmentCh
     masm.movePtr(ImmGCPtr(&module()->initialEnvironment()), scope);
     masm.storePtr(scope, frame.addressOfEnvironmentChain());
   } else {
     // EnvironmentChain pointer in BaselineFrame has already been initialized
     // in prologue, but we need to check for redeclaration errors.
 
     prepareVMCall();
 
-    pushArg(ImmGCPtr(script));
+    pushScriptArg();
     masm.loadPtr(frame.addressOfEnvironmentChain(), R0.scratchReg());
     pushArg(R0.scratchReg());
 
     if (!callVMNonOp(CheckGlobalOrEvalDeclarationConflictsInfo, phase)) {
       return false;
     }
   }
 
@@ -1602,17 +1686,17 @@ bool BaselineCodeGen<Handler>::emit_JSOP
   frame.syncStack(0);
   masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R0);
 
   Label ok;
   masm.branchTestObject(Assembler::Equal, R0, &ok);
 
   prepareVMCall();
 
-  pushArg(Imm32(GET_UINT8(pc)));
+  pushUint8BytecodeOperandArg();
   if (!callVM(ThrowCheckIsObjectInfo)) {
     return false;
   }
 
   masm.bind(&ok);
   return true;
 }
 
@@ -1622,17 +1706,17 @@ static const VMFunction CheckIsCallableI
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_CHECKISCALLABLE() {
   frame.syncStack(0);
   masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R0);
 
   prepareVMCall();
 
-  pushArg(Imm32(GET_UINT8(pc)));
+  pushUint8BytecodeOperandArg();
   pushArg(R0);
   if (!callVM(CheckIsCallableInfo)) {
     return false;
   }
 
   return true;
 }
 
@@ -1880,25 +1964,20 @@ typedef JSObject* (*DeepCloneObjectLiter
                                               NewObjectKind);
 static const VMFunction DeepCloneObjectLiteralInfo =
     FunctionInfo<DeepCloneObjectLiteralFn>(DeepCloneObjectLiteral,
                                            "DeepCloneObjectLiteral");
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_OBJECT() {
   if (cx->realm()->creationOptions().cloneSingletons()) {
-    RootedObject obj(cx, script->getObject(GET_UINT32_INDEX(pc)));
-    if (!obj) {
-      return false;
-    }
-
     prepareVMCall();
 
     pushArg(ImmWord(TenuredObject));
-    pushArg(ImmGCPtr(obj));
+    pushScriptObjectArg(ScriptObjectType::ObjectLiteral);
 
     if (!callVM(DeepCloneObjectLiteralInfo)) {
       return false;
     }
 
     // Box and push return value.
     masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
     frame.push(R0);
@@ -1927,43 +2006,39 @@ bool BaselineCodeGen<Handler>::emit_JSOP
 }
 
 typedef JSObject* (*CloneRegExpObjectFn)(JSContext*, Handle<RegExpObject*>);
 static const VMFunction CloneRegExpObjectInfo =
     FunctionInfo<CloneRegExpObjectFn>(CloneRegExpObject, "CloneRegExpObject");
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_REGEXP() {
-  RootedObject reObj(cx, script->getRegExp(pc));
-
   prepareVMCall();
-  pushArg(ImmGCPtr(reObj));
+  pushScriptObjectArg(ScriptObjectType::RegExp);
   if (!callVM(CloneRegExpObjectInfo)) {
     return false;
   }
 
   // Box and push return value.
   masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
   frame.push(R0);
   return true;
 }
 
 typedef JSObject* (*LambdaFn)(JSContext*, HandleFunction, HandleObject);
 static const VMFunction LambdaInfo =
     FunctionInfo<LambdaFn>(js::Lambda, "Lambda");
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_LAMBDA() {
-  RootedFunction fun(cx, script->getFunction(GET_UINT32_INDEX(pc)));
-
   prepareVMCall();
   masm.loadPtr(frame.addressOfEnvironmentChain(), R0.scratchReg());
 
   pushArg(R0.scratchReg());
-  pushArg(ImmGCPtr(fun));
+  pushScriptObjectArg(ScriptObjectType::Function);
 
   if (!callVM(LambdaInfo)) {
     return false;
   }
 
   // Box and push return value.
   masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
   frame.push(R0);
@@ -1975,24 +2050,22 @@ typedef JSObject* (*LambdaArrowFn)(JSCon
 static const VMFunction LambdaArrowInfo =
     FunctionInfo<LambdaArrowFn>(js::LambdaArrow, "LambdaArrow");
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_LAMBDA_ARROW() {
   // Keep pushed newTarget in R0.
   frame.popRegsAndSync(1);
 
-  RootedFunction fun(cx, script->getFunction(GET_UINT32_INDEX(pc)));
-
   prepareVMCall();
   masm.loadPtr(frame.addressOfEnvironmentChain(), R2.scratchReg());
 
   pushArg(R0);
   pushArg(R2.scratchReg());
-  pushArg(ImmGCPtr(fun));
+  pushScriptObjectArg(ScriptObjectType::Function);
 
   if (!callVM(LambdaArrowInfo)) {
     return false;
   }
 
   // Box and push return value.
   masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
   frame.push(R0);
@@ -2006,22 +2079,21 @@ static const VMFunction SetFunNameInfo =
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_SETFUNNAME() {
   frame.popRegsAndSync(2);
 
   frame.push(R0);
   frame.syncStack(0);
 
-  FunctionPrefixKind prefixKind = FunctionPrefixKind(GET_UINT8(pc));
   masm.unboxObject(R0, R0.scratchReg());
 
   prepareVMCall();
 
-  pushArg(Imm32(int32_t(prefixKind)));
+  pushUint8BytecodeOperandArg();
   pushArg(R1);
   pushArg(R0.scratchReg());
   return callVM(SetFunNameInfo);
 }
 
 template <typename Handler>
 void BaselineCodeGen<Handler>::storeValue(const StackValue* source,
                                           const Address& dest,
@@ -2739,17 +2811,17 @@ bool BaselineCodeGen<Handler>::emitSetPr
   frame.popRegsAndSync(1);
   masm.loadValue(frame.addressOfStackValue(frame.peek(-2)), R1);
   masm.storeValue(R0, frame.addressOfStackValue(frame.peek(-2)));
 
   prepareVMCall();
 
   pushArg(Imm32(strict));
   pushArg(R0);  // rval
-  pushArg(ImmGCPtr(script->getName(pc)));
+  pushScriptNameArg();
   pushArg(R1);  // receiver
   masm.unboxObject(frame.addressOfStackValue(frame.peek(-1)), R0.scratchReg());
   pushArg(R0.scratchReg());  // obj
 
   if (!callVM(SetPropertySuperInfo)) {
     return false;
   }
 
@@ -2824,17 +2896,17 @@ static const VMFunction DeletePropertyNo
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emitDelProp(bool strict) {
   // Keep value on the stack for the decompiler.
   frame.syncStack(0);
   masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R0);
 
   prepareVMCall();
 
-  pushArg(ImmGCPtr(script->getName(pc)));
+  pushScriptNameArg();
   pushArg(R0);
 
   if (!callVM(strict ? DeletePropertyStrictInfo
                      : DeletePropertyNonStrictInfo)) {
     return false;
   }
 
   masm.boxNonDouble(JSVAL_TYPE_BOOLEAN, ReturnReg, R1);
@@ -3003,17 +3075,17 @@ static const VMFunction DeleteNameInfo =
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_DELNAME() {
   frame.syncStack(0);
   masm.loadPtr(frame.addressOfEnvironmentChain(), R0.scratchReg());
 
   prepareVMCall();
 
   pushArg(R0.scratchReg());
-  pushArg(ImmGCPtr(script->getName(pc)));
+  pushScriptNameArg();
 
   if (!callVM(DeleteNameInfo)) {
     return false;
   }
 
   frame.push(R0);
   return true;
 }
@@ -3083,18 +3155,18 @@ static const VMFunction DefVarInfo =
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_DEFVAR() {
   frame.syncStack(0);
 
   masm.loadPtr(frame.addressOfEnvironmentChain(), R0.scratchReg());
 
   prepareVMCall();
 
-  pushArg(ImmPtr(pc));
-  pushArg(ImmGCPtr(script));
+  pushBytecodePCArg();
+  pushScriptArg();
   pushArg(R0.scratchReg());
 
   return callVM(DefVarInfo);
 }
 
 typedef bool (*DefLexicalFn)(JSContext*, HandleObject, HandleScript,
                              jsbytecode*);
 static const VMFunction DefLexicalInfo =
@@ -3105,18 +3177,18 @@ bool BaselineCodeGen<Handler>::emitDefLe
   MOZ_ASSERT(op == JSOP_DEFCONST || op == JSOP_DEFLET);
 
   frame.syncStack(0);
 
   masm.loadPtr(frame.addressOfEnvironmentChain(), R0.scratchReg());
 
   prepareVMCall();
 
-  pushArg(ImmPtr(pc));
-  pushArg(ImmGCPtr(script));
+  pushBytecodePCArg();
+  pushScriptArg();
   pushArg(R0.scratchReg());
 
   return callVM(DefLexicalInfo);
 }
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_DEFCONST() {
   return emitDefLexical(JSOP_DEFCONST);
@@ -3137,17 +3209,17 @@ bool BaselineCodeGen<Handler>::emit_JSOP
   frame.popRegsAndSync(1);
   masm.unboxObject(R0, R0.scratchReg());
   masm.loadPtr(frame.addressOfEnvironmentChain(), R1.scratchReg());
 
   prepareVMCall();
 
   pushArg(R0.scratchReg());
   pushArg(R1.scratchReg());
-  pushArg(ImmGCPtr(script));
+  pushScriptArg();
 
   return callVM(DefFunOperationInfo);
 }
 
 typedef bool (*InitPropGetterSetterFn)(JSContext*, jsbytecode*, HandleObject,
                                        HandlePropertyName, HandleObject);
 static const VMFunction InitPropGetterSetterInfo =
     FunctionInfo<InitPropGetterSetterFn>(InitGetterSetterOperation,
@@ -3159,19 +3231,19 @@ bool BaselineCodeGen<Handler>::emitInitP
   frame.syncStack(0);
 
   prepareVMCall();
 
   masm.unboxObject(frame.addressOfStackValue(frame.peek(-1)), R0.scratchReg());
   masm.unboxObject(frame.addressOfStackValue(frame.peek(-2)), R1.scratchReg());
 
   pushArg(R0.scratchReg());
-  pushArg(ImmGCPtr(script->getName(pc)));
+  pushScriptNameArg();
   pushArg(R1.scratchReg());
-  pushArg(ImmPtr(pc));
+  pushBytecodePCArg();
 
   if (!callVM(InitPropGetterSetterInfo)) {
     return false;
   }
 
   frame.pop();
   return true;
 }
@@ -3211,17 +3283,17 @@ bool BaselineCodeGen<Handler>::emitInitE
   masm.unboxObject(frame.addressOfStackValue(frame.peek(-1)), R1.scratchReg());
 
   prepareVMCall();
 
   pushArg(R1.scratchReg());
   pushArg(R0);
   masm.unboxObject(frame.addressOfStackValue(frame.peek(-3)), R0.scratchReg());
   pushArg(R0.scratchReg());
-  pushArg(ImmPtr(pc));
+  pushBytecodePCArg();
 
   if (!callVM(InitElemGetterSetterInfo)) {
     return false;
   }
 
   frame.popn(2);
   return true;
 }
@@ -3671,17 +3743,17 @@ const VMFunction ImplicitThisInfo = Func
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_IMPLICITTHIS() {
   frame.syncStack(0);
   masm.loadPtr(frame.addressOfEnvironmentChain(), R0.scratchReg());
 
   prepareVMCall();
 
-  pushArg(ImmGCPtr(script->getName(pc)));
+  pushScriptNameArg();
   pushArg(R0.scratchReg());
 
   if (!callVM(ImplicitThisInfo)) {
     return false;
   }
 
   frame.push(R0);
   return true;
@@ -3728,17 +3800,17 @@ bool BaselineCodeGen<Handler>::emit_JSOP
 
 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();
-  pushArg(Imm32(GET_UINT16(pc)));
+  pushUint16BytecodeOperandArg();
   return callVM(ThrowMsgInfo);
 }
 
 typedef bool (*ThrowFn)(JSContext*, HandleValue);
 static const VMFunction ThrowInfo = FunctionInfo<ThrowFn>(js::Throw, "Throw");
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_THROW() {
@@ -3870,23 +3942,21 @@ MOZ_MUST_USE bool BaselineInterpreterCod
 
 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() {
-  LexicalScope& scope = script->getScope(pc)->template as<LexicalScope>();
-
   // Call a stub to push the block on the block chain.
   prepareVMCall();
   masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
 
-  pushArg(ImmGCPtr(&scope));
+  pushScriptScopeArg();
   pushArg(R0.scratchReg());
 
   return callVM(PushLexicalEnvInfo);
 }
 
 typedef bool (*PopLexicalEnvFn)(JSContext*, BaselineFrame*);
 static const VMFunction PopLexicalEnvInfo =
     FunctionInfo<PopLexicalEnvFn>(jit::PopLexicalEnv, "PopLexicalEnv");
@@ -3899,17 +3969,17 @@ static const VMFunction DebugLeaveThenPo
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_POPLEXICALENV() {
   prepareVMCall();
 
   masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
 
   auto ifDebuggee = [this]() {
-    pushArg(ImmPtr(pc));
+    pushBytecodePCArg();
     pushArg(R0.scratchReg());
     return callVM(DebugLeaveThenPopLexicalEnvInfo);
   };
   auto ifNotDebuggee = [this]() {
     pushArg(R0.scratchReg());
     return callVM(PopLexicalEnvInfo);
   };
   return emitDebugInstrumentation(ifDebuggee, mozilla::Some(ifNotDebuggee));
@@ -3929,17 +3999,17 @@ static const VMFunction DebugLeaveThenFr
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_FRESHENLEXICALENV() {
   prepareVMCall();
 
   masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
 
   auto ifDebuggee = [this]() {
-    pushArg(ImmPtr(pc));
+    pushBytecodePCArg();
     pushArg(R0.scratchReg());
     return callVM(DebugLeaveThenFreshenLexicalEnvInfo);
   };
   auto ifNotDebuggee = [this]() {
     pushArg(R0.scratchReg());
     return callVM(FreshenLexicalEnvInfo);
   };
   return emitDebugInstrumentation(ifDebuggee, mozilla::Some(ifNotDebuggee));
@@ -3959,17 +4029,17 @@ static const VMFunction DebugLeaveThenRe
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_RECREATELEXICALENV() {
   prepareVMCall();
 
   masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
 
   auto ifDebuggee = [this]() {
-    pushArg(ImmPtr(pc));
+    pushBytecodePCArg();
     pushArg(R0.scratchReg());
     return callVM(DebugLeaveThenRecreateLexicalEnvInfo);
   };
   auto ifNotDebuggee = [this]() {
     pushArg(R0.scratchReg());
     return callVM(RecreateLexicalEnvInfo);
   };
   return emitDebugInstrumentation(ifDebuggee, mozilla::Some(ifNotDebuggee));
@@ -3980,32 +4050,32 @@ static const VMFunction DebugLeaveLexica
     FunctionInfo<DebugLeaveLexicalEnvFn>(jit::DebugLeaveLexicalEnv,
                                          "DebugLeaveLexicalEnv");
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_DEBUGLEAVELEXICALENV() {
   auto ifDebuggee = [this]() {
     prepareVMCall();
     masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
-    pushArg(ImmPtr(pc));
+    pushBytecodePCArg();
     pushArg(R0.scratchReg());
     return callVM(DebugLeaveLexicalEnvInfo);
   };
   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());
-  pushArg(ImmGCPtr(script->getScope(pc)));
+  pushScriptScopeArg();
   pushArg(R0.scratchReg());
 
   return callVM(PushVarEnvInfo);
 }
 
 typedef bool (*PopVarEnvFn)(JSContext*, BaselineFrame*);
 static const VMFunction PopVarEnvInfo =
     FunctionInfo<PopVarEnvFn>(jit::PopVarEnv, "PopVarEnv");
@@ -4021,26 +4091,24 @@ bool BaselineCodeGen<Handler>::emit_JSOP
 
 typedef bool (*EnterWithFn)(JSContext*, BaselineFrame*, HandleValue,
                             Handle<WithScope*>);
 static const VMFunction EnterWithInfo =
     FunctionInfo<EnterWithFn>(jit::EnterWith, "EnterWith");
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_ENTERWITH() {
-  WithScope& withScope = script->getScope(pc)->template as<WithScope>();
-
   // 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());
 
-  pushArg(ImmGCPtr(&withScope));
+  pushScriptScopeArg();
   pushArg(R0);
   pushArg(R1.scratchReg());
 
   return callVM(EnterWithInfo);
 }
 
 typedef bool (*LeaveWithFn)(JSContext*, BaselineFrame*);
 static const VMFunction LeaveWithInfo =
@@ -4078,17 +4146,17 @@ typedef bool (*OnDebuggerStatementFn)(JS
                                       jsbytecode* pc, bool*);
 static const VMFunction OnDebuggerStatementInfo =
     FunctionInfo<OnDebuggerStatementFn>(jit::OnDebuggerStatement,
                                         "OnDebuggerStatement");
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_DEBUGGER() {
   prepareVMCall();
-  pushArg(ImmPtr(pc));
+  pushBytecodePCArg();
 
   frame.assertSyncedStack();
   masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
   pushArg(R0.scratchReg());
 
   if (!callVM(OnDebuggerStatementInfo)) {
     return false;
   }
@@ -4115,17 +4183,17 @@ bool BaselineCodeGen<Handler>::emitRetur
     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();
-    pushArg(ImmPtr(pc));
+    pushBytecodePCArg();
     pushArg(R0.scratchReg());
     if (!callVM(DebugEpilogueInfo)) {
       return false;
     }
 
     // Fix up the RetAddrEntry appended by callVM for on-stack recompilation.
     retAddrEntries_.back().setKind(RetAddrEntry::Kind::DebugEpilogue);
 
@@ -4812,17 +4880,17 @@ bool BaselineCodeGen<Handler>::emit_JSOP
     MOZ_ASSERT(genObj == R2.scratchReg());
     masm.call(&postBarrierSlot_);
     masm.bind(&skipBarrier);
   } else {
     masm.loadBaselineFramePtr(BaselineFrameReg, R1.scratchReg());
 
     prepareVMCall();
     pushArg(Imm32(frame.stackDepth()));
-    pushArg(ImmPtr(pc));
+    pushBytecodePCArg();
     pushArg(R1.scratchReg());
     pushArg(genObj);
 
     if (!callVM(NormalSuspendInfo)) {
       return false;
     }
   }
 
@@ -4841,17 +4909,17 @@ static const VMFunction DebugAfterYieldI
     FunctionInfo<DebugAfterYieldFn>(jit::DebugAfterYield, "DebugAfterYield");
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_DEBUGAFTERYIELD() {
   auto ifDebuggee = [this]() {
     frame.assertSyncedStack();
     masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
     prepareVMCall();
-    pushArg(ImmPtr(pc));
+    pushBytecodePCArg();
     pushArg(R0.scratchReg());
     if (!callVM(DebugAfterYieldInfo)) {
       return false;
     }
 
     retAddrEntries_.back().setKind(RetAddrEntry::Kind::DebugAfterYield);
 
     Label done;
@@ -4872,17 +4940,17 @@ static const VMFunction FinalSuspendInfo
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_FINALYIELDRVAL() {
   // Store generator in R0.
   frame.popRegsAndSync(1);
   masm.unboxObject(R0, R0.scratchReg());
 
   prepareVMCall();
-  pushArg(ImmPtr(pc));
+  pushBytecodePCArg();
   pushArg(R0.scratchReg());
 
   if (!callVM(FinalSuspendInfo)) {
     return false;
   }
 
   masm.loadValue(frame.addressOfReturnValue(), JSReturnOperand);
   return emitReturn();
@@ -5286,17 +5354,17 @@ bool BaselineCodeGen<Handler>::emit_JSOP
   frame.popRegsAndSync(1);
 
   masm.unboxObject(R0, R0.scratchReg());
   masm.loadPtr(frame.addressOfEnvironmentChain(), R1.scratchReg());
 
   prepareVMCall();
   pushArg(R0.scratchReg());
   pushArg(R1.scratchReg());
-  pushArg(ImmGCPtr(script->getFunction(GET_UINT32_INDEX(pc))));
+  pushScriptObjectArg(ScriptObjectType::Function);
   if (!callVM(FunWithProtoInfo)) {
     return false;
   }
 
   masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
   frame.push(R0);
   return true;
 }
@@ -5309,18 +5377,18 @@ static const VMFunction MakeDefaultConst
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_CLASSCONSTRUCTOR() {
   frame.syncStack(0);
 
   // Pass nullptr as prototype to MakeDefaultConstructor
   prepareVMCall();
   pushArg(ImmPtr(nullptr));
-  pushArg(ImmPtr(pc));
-  pushArg(ImmGCPtr(script));
+  pushBytecodePCArg();
+  pushScriptArg();
   if (!callVM(MakeDefaultConstructorInfo)) {
     return false;
   }
 
   masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
   frame.push(R0);
   return true;
 }
@@ -5328,18 +5396,18 @@ bool BaselineCodeGen<Handler>::emit_JSOP
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_DERIVEDCONSTRUCTOR() {
   frame.popRegsAndSync(1);
 
   masm.unboxObject(R0, R0.scratchReg());
 
   prepareVMCall();
   pushArg(R0.scratchReg());
-  pushArg(ImmPtr(pc));
-  pushArg(ImmGCPtr(script));
+  pushBytecodePCArg();
+  pushScriptArg();
   if (!callVM(MakeDefaultConstructorInfo)) {
     return false;
   }
 
   masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
   frame.push(R0);
   return true;
 }
--- a/js/src/jit/BaselineCompiler.h
+++ b/js/src/jit/BaselineCompiler.h
@@ -307,16 +307,34 @@ class BaselineCodeGen {
   }
 
   ModuleObject* module() const { return script->module(); }
 
   template <typename T>
   void pushArg(const T& t) {
     masm.Push(t);
   }
+
+  // Pushes the current script as argument for a VM function.
+  void pushScriptArg();
+
+  // Pushes the bytecode pc as argument for a VM function.
+  void pushBytecodePCArg();
+
+  // Pushes a name/object/scope associated with the current bytecode op (and
+  // stored in the script) as argument for a VM function.
+  enum class ScriptObjectType { RegExp, Function, ObjectLiteral };
+  void pushScriptObjectArg(ScriptObjectType type);
+  void pushScriptNameArg();
+  void pushScriptScopeArg();
+
+  // Pushes a bytecode operand as argument for a VM function.
+  void pushUint8BytecodeOperandArg();
+  void pushUint16BytecodeOperandArg();
+
   void prepareVMCall();
 
   enum CallVMPhase { POST_INITIALIZE, CHECK_OVER_RECURSED };
   bool callVM(const VMFunction& fun, CallVMPhase phase = POST_INITIALIZE);
 
   bool callVMNonOp(const VMFunction& fun, CallVMPhase phase = POST_INITIALIZE) {
     if (!callVM(fun, phase)) {
       return false;
--- a/js/src/vm/JSScript-inl.h
+++ b/js/src/vm/JSScript-inl.h
@@ -92,16 +92,20 @@ inline void JSScript::ensureNonLazyCanon
 inline JSFunction* JSScript::getFunction(size_t index) {
   JSObject* obj = getObject(index);
   MOZ_RELEASE_ASSERT(obj->is<JSFunction>(), "Script object is not JSFunction");
   JSFunction* fun = &obj->as<JSFunction>();
   MOZ_ASSERT_IF(fun->isNative(), IsAsmJSModuleNative(fun->native()));
   return fun;
 }
 
+inline JSFunction* JSScript::getFunction(jsbytecode* pc) {
+  return getFunction(GET_UINT32_INDEX(pc));
+}
+
 inline js::RegExpObject* JSScript::getRegExp(size_t index) {
   JSObject* obj = getObject(index);
   MOZ_RELEASE_ASSERT(obj->is<js::RegExpObject>(),
                      "Script object is not RegExpObject");
   return &obj->as<js::RegExpObject>();
 }
 
 inline js::RegExpObject* JSScript::getRegExp(jsbytecode* pc) {
--- a/js/src/vm/JSScript.h
+++ b/js/src/vm/JSScript.h
@@ -2604,16 +2604,18 @@ class JSScript : public js::gc::TenuredC
     // use lookupScope.
     MOZ_ASSERT(containsPC(pc) && containsPC(pc + sizeof(uint32_t)));
     MOZ_ASSERT(js::JOF_OPTYPE(JSOp(*pc)) == JOF_SCOPE,
                "Did you mean to use lookupScope(pc)?");
     return getScope(GET_UINT32_INDEX(pc));
   }
 
   inline JSFunction* getFunction(size_t index);
+  inline JSFunction* getFunction(jsbytecode* pc);
+
   JSFunction* function() const {
     if (functionNonDelazifying()) {
       return functionNonDelazifying();
     }
     return nullptr;
   }
 
   inline js::RegExpObject* getRegExp(size_t index);