Bug 1508962 part 3 - Eliminate some *pc uses where we know the JSOp statically. r=djvj
authorJan de Mooij <jdemooij@mozilla.com>
Thu, 29 Nov 2018 22:44:48 +0000
changeset 508087 c315f5473734de31c574cb650c67a98916f9f64b
parent 508086 e0b75c94bc06140a53af4e9bc1a6c738b62d5793
child 508088 863959eb64d1f39ad7c07e44f98263ee10d6ef5a
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdjvj
bugs1508962
milestone65.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 1508962 part 3 - Eliminate some *pc uses where we know the JSOp statically. r=djvj Differential Revision: https://phabricator.services.mozilla.com/D12922
js/src/jit/BaselineCompiler.cpp
js/src/jit/BaselineCompiler.h
js/src/vm/BytecodeUtil.h
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -2660,20 +2660,18 @@ template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_STRICTSETELEM()
 {
     return emit_JSOP_SETELEM();
 }
 
 template <typename Handler>
 bool
-BaselineCodeGen<Handler>::emit_JSOP_SETELEM_SUPER()
-{
-    bool strict = IsCheckStrictOp(JSOp(*pc));
-
+BaselineCodeGen<Handler>::emitSetElemSuper(bool strict)
+{
     // Incoming stack is |receiver, propval, obj, rval|. We need to shuffle
     // stack to leave rval when operation is complete.
 
     // Pop rval into R0, then load receiver into R1 and replace with rval.
     frame.popRegsAndSync(1);
     masm.loadValue(frame.addressOfStackValue(frame.peek(-3)), R1);
     masm.storeValue(R0, frame.addressOfStackValue(frame.peek(-3)));
 
@@ -2692,57 +2690,69 @@ BaselineCodeGen<Handler>::emit_JSOP_SETE
     }
 
     frame.popn(2);
     return true;
 }
 
 template <typename Handler>
 bool
+BaselineCodeGen<Handler>::emit_JSOP_SETELEM_SUPER()
+{
+    return emitSetElemSuper(/* strict = */ false);
+}
+
+template <typename Handler>
+bool
 BaselineCodeGen<Handler>::emit_JSOP_STRICTSETELEM_SUPER()
 {
-    return emit_JSOP_SETELEM_SUPER();
+    return emitSetElemSuper(/* strict = */ true);
 }
 
 typedef bool (*DeleteElementFn)(JSContext*, HandleValue, HandleValue, bool*);
 static const VMFunction DeleteElementStrictInfo
     = FunctionInfo<DeleteElementFn>(DeleteElementJit<true>, "DeleteElementStrict");
 static const VMFunction DeleteElementNonStrictInfo
     = FunctionInfo<DeleteElementFn>(DeleteElementJit<false>, "DeleteElementNonStrict");
 
 template <typename Handler>
 bool
-BaselineCodeGen<Handler>::emit_JSOP_DELELEM()
+BaselineCodeGen<Handler>::emitDelElem(bool strict)
 {
     // Keep values on the stack for the decompiler.
     frame.syncStack(0);
     masm.loadValue(frame.addressOfStackValue(frame.peek(-2)), R0);
     masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R1);
 
     prepareVMCall();
 
     pushArg(R1);
     pushArg(R0);
-
-    bool strict = JSOp(*pc) == JSOP_STRICTDELELEM;
     if (!callVM(strict ? DeleteElementStrictInfo : DeleteElementNonStrictInfo)) {
         return false;
     }
 
     masm.boxNonDouble(JSVAL_TYPE_BOOLEAN, ReturnReg, R1);
     frame.popn(2);
     frame.push(R1);
     return true;
 }
 
 template <typename Handler>
 bool
+BaselineCodeGen<Handler>::emit_JSOP_DELELEM()
+{
+    return emitDelElem(/* strict = */ false);
+}
+
+template <typename Handler>
+bool
 BaselineCodeGen<Handler>::emit_JSOP_STRICTDELELEM()
 {
-    return emit_JSOP_DELELEM();
+    return emitDelElem(/* strict = */ true);
 }
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_IN()
 {
     frame.popRegsAndSync(2);
 
@@ -2832,17 +2842,17 @@ BaselineCodeGen<Handler>::emit_JSOP_BIND
                 frame.push(ObjectValue(script->global()));
                 return true;
             }
         }
 
         // Otherwise we have to use the environment chain.
     }
 
-    return emit_JSOP_BINDNAME();
+    return emitBindName(JSOP_BINDGNAME);
 }
 
 typedef JSObject* (*BindVarFn)(JSContext*, HandleObject);
 static const VMFunction BindVarInfo = FunctionInfo<BindVarFn>(jit::BindVar, "BindVar");
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_BINDVAR()
@@ -2918,20 +2928,18 @@ BaselineCodeGen<Handler>::emit_JSOP_STRI
 
 typedef bool (*SetPropertySuperFn)(JSContext*, HandleObject, HandleValue,
                                    HandlePropertyName, HandleValue, bool);
 static const VMFunction SetPropertySuperInfo =
     FunctionInfo<SetPropertySuperFn>(js::SetPropertySuper, "SetPropertySuper");
 
 template <typename Handler>
 bool
-BaselineCodeGen<Handler>::emit_JSOP_SETPROP_SUPER()
-{
-    bool strict = IsCheckStrictOp(JSOp(*pc));
-
+BaselineCodeGen<Handler>::emitSetPropSuper(bool strict)
+{
     // Incoming stack is |receiver, obj, rval|. We need to shuffle stack to
     // leave rval when operation is complete.
 
     // Pop rval into R0, then load receiver into R1 and replace with rval.
     frame.popRegsAndSync(1);
     masm.loadValue(frame.addressOfStackValue(frame.peek(-2)), R1);
     masm.storeValue(R0, frame.addressOfStackValue(frame.peek(-2)));
 
@@ -2949,19 +2957,26 @@ BaselineCodeGen<Handler>::emit_JSOP_SETP
     }
 
     frame.pop();
     return true;
 }
 
 template <typename Handler>
 bool
+BaselineCodeGen<Handler>::emit_JSOP_SETPROP_SUPER()
+{
+    return emitSetPropSuper(/* strict = */ false);
+}
+
+template <typename Handler>
+bool
 BaselineCodeGen<Handler>::emit_JSOP_STRICTSETPROP_SUPER()
 {
-    return emit_JSOP_SETPROP_SUPER();
+    return emitSetPropSuper(/* strict = */ true);
 }
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_GETPROP()
 {
     // Keep object in R0.
     frame.popRegsAndSync(1);
@@ -3018,43 +3033,49 @@ BaselineCodeGen<Handler>::emit_JSOP_GETP
 typedef bool (*DeletePropertyFn)(JSContext*, HandleValue, HandlePropertyName, bool*);
 static const VMFunction DeletePropertyStrictInfo =
     FunctionInfo<DeletePropertyFn>(DeletePropertyJit<true>, "DeletePropertyStrict");
 static const VMFunction DeletePropertyNonStrictInfo =
     FunctionInfo<DeletePropertyFn>(DeletePropertyJit<false>, "DeletePropertyNonStrict");
 
 template <typename Handler>
 bool
-BaselineCodeGen<Handler>::emit_JSOP_DELPROP()
+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)));
     pushArg(R0);
 
-    bool strict = JSOp(*pc) == JSOP_STRICTDELPROP;
     if (!callVM(strict ? DeletePropertyStrictInfo : DeletePropertyNonStrictInfo)) {
         return false;
     }
 
     masm.boxNonDouble(JSVAL_TYPE_BOOLEAN, ReturnReg, R1);
     frame.pop();
     frame.push(R1);
     return true;
 }
 
 template <typename Handler>
 bool
+BaselineCodeGen<Handler>::emit_JSOP_DELPROP()
+{
+    return emitDelProp(/* strict = */ false);
+}
+
+template <typename Handler>
+bool
 BaselineCodeGen<Handler>::emit_JSOP_STRICTDELPROP()
 {
-    return emit_JSOP_DELPROP();
+    return emitDelProp(/* strict = */ true);
 }
 
 template <typename Handler>
 void
 BaselineCodeGen<Handler>::getEnvironmentCoordinateObject(Register reg)
 {
     EnvironmentCoordinate ec(pc);
 
@@ -3171,36 +3192,45 @@ BaselineCodeGen<Handler>::emit_JSOP_GETN
 
     // Mark R0 as pushed stack value.
     frame.push(R0);
     return true;
 }
 
 template <typename Handler>
 bool
-BaselineCodeGen<Handler>::emit_JSOP_BINDNAME()
-{
+BaselineCodeGen<Handler>::emitBindName(JSOp op)
+{
+    MOZ_ASSERT(op == JSOP_BINDNAME || op == JSOP_BINDGNAME);
+
     frame.syncStack(0);
 
-    if (*pc == JSOP_BINDGNAME && !script->hasNonSyntacticScope()) {
+    if (op == JSOP_BINDGNAME && !script->hasNonSyntacticScope()) {
         masm.movePtr(ImmGCPtr(&script->global().lexicalEnvironment()), R0.scratchReg());
     } else {
         masm.loadPtr(frame.addressOfEnvironmentChain(), R0.scratchReg());
     }
 
     // Call IC.
     if (!emitNextIC()) {
         return false;
     }
 
     // Mark R0 as pushed stack value.
     frame.push(R0);
     return true;
 }
 
+template <typename Handler>
+bool
+BaselineCodeGen<Handler>::emit_JSOP_BINDNAME()
+{
+    return emitBindName(JSOP_BINDNAME);
+}
+
 typedef bool (*DeleteNameFn)(JSContext*, HandlePropertyName, HandleObject,
                              MutableHandleValue);
 static const VMFunction DeleteNameInfo =
     FunctionInfo<DeleteNameFn>(DeleteNameOperation, "DeleteNameOperation");
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_DELNAME()
@@ -3305,44 +3335,53 @@ BaselineCodeGen<Handler>::emit_JSOP_DEFV
     return callVM(DefVarInfo);
 }
 
 typedef bool (*DefLexicalFn)(JSContext*, HandlePropertyName, unsigned, HandleObject);
 static const VMFunction DefLexicalInfo = FunctionInfo<DefLexicalFn>(DefLexical, "DefLexical");
 
 template <typename Handler>
 bool
-BaselineCodeGen<Handler>::emit_JSOP_DEFCONST()
-{
-    return emit_JSOP_DEFLET();
-}
-
-template <typename Handler>
-bool
-BaselineCodeGen<Handler>::emit_JSOP_DEFLET()
-{
+BaselineCodeGen<Handler>::emitDefLexical(JSOp op)
+{
+    MOZ_ASSERT(op == JSOP_DEFCONST || op == JSOP_DEFLET);
+
     frame.syncStack(0);
 
     unsigned attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT;
-    if (*pc == JSOP_DEFCONST) {
+    if (op == JSOP_DEFCONST) {
         attrs |= JSPROP_READONLY;
     }
     MOZ_ASSERT(attrs <= UINT32_MAX);
 
     masm.loadPtr(frame.addressOfEnvironmentChain(), R0.scratchReg());
 
     prepareVMCall();
 
     pushArg(R0.scratchReg());
     pushArg(Imm32(attrs));
     pushArg(ImmGCPtr(script->getName(pc)));
 
     return callVM(DefLexicalInfo);
 }
 
+template <typename Handler>
+bool
+BaselineCodeGen<Handler>::emit_JSOP_DEFCONST()
+{
+    return emitDefLexical(JSOP_DEFCONST);
+}
+
+template <typename Handler>
+bool
+BaselineCodeGen<Handler>::emit_JSOP_DEFLET()
+{
+    return emitDefLexical(JSOP_DEFLET);
+}
+
 typedef bool (*DefFunOperationFn)(JSContext*, HandleScript, HandleObject, HandleFunction);
 static const VMFunction DefFunOperationInfo =
     FunctionInfo<DefFunOperationFn>(DefFunOperation, "DefFunOperation");
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_DEFFUN()
 {
@@ -3364,21 +3403,16 @@ typedef bool (*InitPropGetterSetterFn)(J
 static const VMFunction InitPropGetterSetterInfo =
     FunctionInfo<InitPropGetterSetterFn>(InitGetterSetterOperation,
                                          "InitPropGetterSetterOperation");
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emitInitPropGetterSetter()
 {
-    MOZ_ASSERT(JSOp(*pc) == JSOP_INITPROP_GETTER ||
-               JSOp(*pc) == JSOP_INITHIDDENPROP_GETTER ||
-               JSOp(*pc) == JSOP_INITPROP_SETTER ||
-               JSOp(*pc) == JSOP_INITHIDDENPROP_SETTER);
-
     // Keep values on the stack for the decompiler.
     frame.syncStack(0);
 
     prepareVMCall();
 
     masm.unboxObject(frame.addressOfStackValue(frame.peek(-1)), R0.scratchReg());
     masm.unboxObject(frame.addressOfStackValue(frame.peek(-2)), R1.scratchReg());
 
@@ -3428,21 +3462,16 @@ typedef bool (*InitElemGetterSetterFn)(J
 static const VMFunction InitElemGetterSetterInfo =
     FunctionInfo<InitElemGetterSetterFn>(InitGetterSetterOperation,
                                          "InitElemGetterSetterOperation");
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emitInitElemGetterSetter()
 {
-    MOZ_ASSERT(JSOp(*pc) == JSOP_INITELEM_GETTER ||
-               JSOp(*pc) == JSOP_INITHIDDENELEM_GETTER ||
-               JSOp(*pc) == JSOP_INITELEM_SETTER ||
-               JSOp(*pc) == JSOP_INITHIDDENELEM_SETTER);
-
     // Load index and value in R0 and R1, but keep values on the stack for the
     // decompiler.
     frame.syncStack(0);
     masm.loadValue(frame.addressOfStackValue(frame.peek(-2)), R0);
     masm.unboxObject(frame.addressOfStackValue(frame.peek(-1)), R1.scratchReg());
 
     prepareVMCall();
 
@@ -3799,154 +3828,154 @@ bool
 BaselineCodeGen<Handler>::emit_JSOP_UNINITIALIZED()
 {
     frame.push(MagicValue(JS_UNINITIALIZED_LEXICAL));
     return true;
 }
 
 template <typename Handler>
 bool
-BaselineCodeGen<Handler>::emitCall()
-{
-    MOZ_ASSERT(IsCallPC(pc));
-
-    bool construct = JSOp(*pc) == JSOP_NEW || JSOp(*pc) == JSOP_SUPERCALL;
-    uint32_t argc = GET_ARGC(pc);
+BaselineCodeGen<Handler>::emitCall(JSOp op)
+{
+    MOZ_ASSERT(IsCallOp(op));
 
     frame.syncStack(0);
+
+    uint32_t argc = GET_ARGC(pc);
     masm.move32(Imm32(argc), R0.scratchReg());
 
     // Call IC
     if (!emitNextIC()) {
         return false;
     }
 
     // Update FrameInfo.
+    bool construct = op == JSOP_NEW || op == JSOP_SUPERCALL;
     frame.popn(2 + argc + construct);
     frame.push(R0);
     return true;
 }
 
 template <typename Handler>
 bool
-BaselineCodeGen<Handler>::emitSpreadCall()
-{
-    MOZ_ASSERT(IsCallPC(pc));
+BaselineCodeGen<Handler>::emitSpreadCall(JSOp op)
+{
+    MOZ_ASSERT(IsCallOp(op));
 
     frame.syncStack(0);
     masm.move32(Imm32(1), R0.scratchReg());
 
     // Call IC
-    bool construct = JSOp(*pc) == JSOP_SPREADNEW || JSOp(*pc) == JSOP_SPREADSUPERCALL;
     if (!emitNextIC()) {
         return false;
     }
 
     // Update FrameInfo.
+    bool construct = op == JSOP_SPREADNEW || op == JSOP_SPREADSUPERCALL;
     frame.popn(3 + construct);
     frame.push(R0);
     return true;
 }
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_CALL()
 {
-    return emitCall();
+    return emitCall(JSOP_CALL);
 }
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_CALL_IGNORES_RV()
 {
-    return emitCall();
+    return emitCall(JSOP_CALL_IGNORES_RV);
 }
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_CALLITER()
 {
-    return emitCall();
+    return emitCall(JSOP_CALLITER);
 }
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_NEW()
 {
-    return emitCall();
+    return emitCall(JSOP_NEW);
 }
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_SUPERCALL()
 {
-    return emitCall();
+    return emitCall(JSOP_SUPERCALL);
 }
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_FUNCALL()
 {
-    return emitCall();
+    return emitCall(JSOP_FUNCALL);
 }
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_FUNAPPLY()
 {
-    return emitCall();
+    return emitCall(JSOP_FUNAPPLY);
 }
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_EVAL()
 {
-    return emitCall();
+    return emitCall(JSOP_EVAL);
 }
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_STRICTEVAL()
 {
-    return emitCall();
+    return emitCall(JSOP_STRICTEVAL);
 }
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_SPREADCALL()
 {
-    return emitSpreadCall();
+    return emitSpreadCall(JSOP_SPREADCALL);
 }
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_SPREADNEW()
 {
-    return emitSpreadCall();
+    return emitSpreadCall(JSOP_SPREADNEW);
 }
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_SPREADSUPERCALL()
 {
-    return emitSpreadCall();
+    return emitSpreadCall(JSOP_SPREADSUPERCALL);
 }
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_SPREADEVAL()
 {
-    return emitSpreadCall();
+    return emitSpreadCall(JSOP_SPREADEVAL);
 }
 
 template <typename Handler>
 bool
 BaselineCodeGen<Handler>::emit_JSOP_STRICTSPREADEVAL()
 {
-    return emitSpreadCall();
+    return emitSpreadCall(JSOP_STRICTSPREADEVAL);
 }
 
 typedef bool (*OptimizeSpreadCallFn)(JSContext*, HandleValue, bool*);
 static const VMFunction OptimizeSpreadCallInfo =
     FunctionInfo<OptimizeSpreadCallFn>(OptimizeSpreadCall, "OptimizeSpreadCall");
 
 template <typename Handler>
 bool
--- a/js/src/jit/BaselineCompiler.h
+++ b/js/src/jit/BaselineCompiler.h
@@ -368,18 +368,27 @@ class BaselineCodeGen
     // Handles JSOP_LT, JSOP_GT, and friends
     MOZ_MUST_USE bool emitCompare();
 
     MOZ_MUST_USE bool emitReturn();
 
     MOZ_MUST_USE bool emitToBoolean();
     MOZ_MUST_USE bool emitTest(bool branchIfTrue);
     MOZ_MUST_USE bool emitAndOr(bool branchIfTrue);
-    MOZ_MUST_USE bool emitCall();
-    MOZ_MUST_USE bool emitSpreadCall();
+
+    MOZ_MUST_USE bool emitCall(JSOp op);
+    MOZ_MUST_USE bool emitSpreadCall(JSOp op);
+
+    MOZ_MUST_USE bool emitDelElem(bool strict);
+    MOZ_MUST_USE bool emitDelProp(bool strict);
+    MOZ_MUST_USE bool emitSetElemSuper(bool strict);
+    MOZ_MUST_USE bool emitSetPropSuper(bool strict);
+
+    MOZ_MUST_USE bool emitBindName(JSOp op);
+    MOZ_MUST_USE bool emitDefLexical(JSOp op);
 
     MOZ_MUST_USE bool emitInitPropGetterSetter();
     MOZ_MUST_USE bool emitInitElemGetterSetter();
 
     MOZ_MUST_USE bool emitFormalArgAccess(uint32_t arg, bool get);
 
     MOZ_MUST_USE bool emitThrowConstAssignment();
     MOZ_MUST_USE bool emitUninitializedLexicalCheck(const ValueOperand& val);
--- a/js/src/vm/BytecodeUtil.h
+++ b/js/src/vm/BytecodeUtil.h
@@ -720,19 +720,25 @@ IsSetElemPC(jsbytecode* pc)
 
 inline bool
 IsElemPC(jsbytecode* pc)
 {
     return CodeSpec[*pc].format & JOF_ELEM;
 }
 
 inline bool
+IsCallOp(JSOp op)
+{
+    return CodeSpec[op].format & JOF_INVOKE;
+}
+
+inline bool
 IsCallPC(jsbytecode* pc)
 {
-    return CodeSpec[*pc].format & JOF_INVOKE;
+    return IsCallOp(JSOp(*pc));
 }
 
 inline bool
 IsStrictEvalPC(jsbytecode* pc)
 {
     JSOp op = JSOp(*pc);
     return op == JSOP_STRICTEVAL || op == JSOP_STRICTSPREADEVAL;
 }