Bug 1511891 part 6 - Merge two DefLexicalOperation functions into one and have the JITs call it directly. r=tcampbell
authorJan de Mooij <jdemooij@mozilla.com>
Fri, 11 Jan 2019 09:14:17 +0000
changeset 453460 745cbd9ae616029f2f146b3ab810709755e4b692
parent 453459 c6e9f5fd0ee7df11463b1bec4b795794752c8fd5
child 453461 0df13a6c64be51a71425190e082e977795ad7242
push id35357
push usernerli@mozilla.com
push dateFri, 11 Jan 2019 21:54:07 +0000
treeherdermozilla-central@0ce024c91511 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstcampbell
bugs1511891
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 1511891 part 6 - Merge two DefLexicalOperation functions into one and have the JITs call it directly. r=tcampbell Differential Revision: https://phabricator.services.mozilla.com/D13704
js/src/jit/BaselineCompiler.cpp
js/src/jit/BytecodeAnalysis.cpp
js/src/jit/CodeGenerator.cpp
js/src/jit/IonBuilder.cpp
js/src/jit/IonBuilder.h
js/src/jit/Lowering.cpp
js/src/jit/MIR.h
js/src/jit/VMFunctions.cpp
js/src/jit/VMFunctions.h
js/src/jit/shared/LIR-shared.h
js/src/vm/Interpreter.cpp
js/src/vm/Interpreter.h
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -3087,40 +3087,34 @@ bool BaselineCodeGen<Handler>::emit_JSOP
 
   pushArg(ImmPtr(pc));
   pushArg(ImmGCPtr(script));
   pushArg(R0.scratchReg());
 
   return callVM(DefVarInfo);
 }
 
-typedef bool (*DefLexicalFn)(JSContext*, HandlePropertyName, unsigned,
-                             HandleObject);
+typedef bool (*DefLexicalFn)(JSContext*, HandleObject, HandleScript,
+                             jsbytecode*);
 static const VMFunction DefLexicalInfo =
-    FunctionInfo<DefLexicalFn>(DefLexical, "DefLexical");
+    FunctionInfo<DefLexicalFn>(DefLexicalOperation, "DefLexicalOperation");
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emitDefLexical(JSOp op) {
   MOZ_ASSERT(op == JSOP_DEFCONST || op == JSOP_DEFLET);
 
   frame.syncStack(0);
 
-  unsigned attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT;
-  if (op == JSOP_DEFCONST) {
-    attrs |= JSPROP_READONLY;
-  }
-  MOZ_ASSERT(attrs <= UINT32_MAX);
-
   masm.loadPtr(frame.addressOfEnvironmentChain(), R0.scratchReg());
 
   prepareVMCall();
 
+  pushArg(ImmPtr(pc));
+  pushArg(ImmGCPtr(script));
   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);
 }
--- a/js/src/jit/BytecodeAnalysis.cpp
+++ b/js/src/jit/BytecodeAnalysis.cpp
@@ -171,16 +171,18 @@ bool BytecodeAnalysis::init(TempAllocato
       case JSOP_STRICTSETNAME:
       case JSOP_DELNAME:
       case JSOP_GETALIASEDVAR:
       case JSOP_SETALIASEDVAR:
       case JSOP_LAMBDA:
       case JSOP_LAMBDA_ARROW:
       case JSOP_DEFFUN:
       case JSOP_DEFVAR:
+      case JSOP_DEFLET:
+      case JSOP_DEFCONST:
       case JSOP_PUSHLEXICALENV:
       case JSOP_POPLEXICALENV:
       case JSOP_IMPLICITTHIS:
         usesEnvironmentChain_ = true;
         break;
 
       case JSOP_GETGNAME:
       case JSOP_SETGNAME:
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -5415,23 +5415,30 @@ void CodeGenerator::visitDefVar(LDefVar*
 
   pushArg(ImmPtr(pc));                    // jsbytecode*
   pushArg(ImmGCPtr(script));              // JSScript*
   pushArg(envChain);                      // JSObject*
 
   callVM(DefVarInfo, lir);
 }
 
-typedef bool (*DefLexicalFn)(JSContext*, HandlePropertyName, unsigned);
+typedef bool (*DefLexicalFn)(JSContext*, HandleObject, HandleScript,
+                             jsbytecode*);
 static const VMFunction DefLexicalInfo =
-    FunctionInfo<DefLexicalFn>(DefGlobalLexical, "DefGlobalLexical");
+    FunctionInfo<DefLexicalFn>(DefLexicalOperation, "DefLexicalOperation");
 
 void CodeGenerator::visitDefLexical(LDefLexical* lir) {
-  pushArg(Imm32(lir->mir()->attrs()));    // unsigned
-  pushArg(ImmGCPtr(lir->mir()->name()));  // PropertyName*
+  Register envChain = ToRegister(lir->environmentChain());
+
+  JSScript* script = current->mir()->info().script();
+  jsbytecode* pc = lir->mir()->resumePoint()->pc();
+
+  pushArg(ImmPtr(pc));        // jsbytecode*
+  pushArg(ImmGCPtr(script));  // JSScript*
+  pushArg(envChain);          // JSObject*
 
   callVM(DefLexicalInfo, lir);
 }
 
 typedef bool (*DefFunOperationFn)(JSContext*, HandleScript, HandleObject,
                                   HandleFunction);
 static const VMFunction DefFunOperationInfo =
     FunctionInfo<DefFunOperationFn>(DefFunOperation, "DefFunOperation");
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -1910,21 +1910,21 @@ AbortReasonOr<Ok> IonBuilder::inspectOpc
 
     case JSOP_NEG:
       return jsop_neg();
 
     case JSOP_TOSTRING:
       return jsop_tostring();
 
     case JSOP_DEFVAR:
-      return jsop_defvar(GET_UINT32_INDEX(pc));
+      return jsop_defvar();
 
     case JSOP_DEFLET:
     case JSOP_DEFCONST:
-      return jsop_deflexical(GET_UINT32_INDEX(pc));
+      return jsop_deflexical();
 
     case JSOP_DEFFUN:
       return jsop_deffun();
 
     case JSOP_EQ:
     case JSOP_NE:
     case JSOP_STRICTEQ:
     case JSOP_STRICTNE:
@@ -12770,42 +12770,37 @@ AbortReasonOr<Ok> IonBuilder::jsop_setar
     current->setArg(arg);
     return Ok();
   }
 
   current->setArg(arg);
   return Ok();
 }
 
-AbortReasonOr<Ok> IonBuilder::jsop_defvar(uint32_t index) {
+AbortReasonOr<Ok> IonBuilder::jsop_defvar() {
   MOZ_ASSERT(JSOp(*pc) == JSOP_DEFVAR);
 
   // Pass the EnvironmentChain.
   MOZ_ASSERT(usesEnvironmentChain());
 
   MDefVar* defvar = MDefVar::New(alloc(), current->environmentChain());
   current->add(defvar);
 
   return resumeAfter(defvar);
 }
 
-AbortReasonOr<Ok> IonBuilder::jsop_deflexical(uint32_t index) {
-  MOZ_ASSERT(!script()->hasNonSyntacticScope());
+AbortReasonOr<Ok> IonBuilder::jsop_deflexical() {
   MOZ_ASSERT(JSOp(*pc) == JSOP_DEFLET || JSOp(*pc) == JSOP_DEFCONST);
-
-  PropertyName* name = script()->getName(index);
-  unsigned attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT;
-  if (JSOp(*pc) == JSOP_DEFCONST) {
-    attrs |= JSPROP_READONLY;
-  }
-
-  MDefLexical* deflex = MDefLexical::New(alloc(), name, attrs);
-  current->add(deflex);
-
-  return resumeAfter(deflex);
+  MOZ_ASSERT(usesEnvironmentChain());
+
+  MDefinition* env = current->environmentChain();
+  MDefLexical* defLexical = MDefLexical::New(alloc(), env);
+  current->add(defLexical);
+
+  return resumeAfter(defLexical);
 }
 
 AbortReasonOr<Ok> IonBuilder::jsop_deffun() {
   MOZ_ASSERT(usesEnvironmentChain());
 
   MDefFun* deffun =
       MDefFun::New(alloc(), current->pop(), current->environmentChain());
   current->add(deffun);
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -532,18 +532,18 @@ class IonBuilder : public MIRGenerator,
   AbortReasonOr<Ok> jsop_binary_arith(JSOp op);
   AbortReasonOr<Ok> jsop_binary_arith(JSOp op, MDefinition* left,
                                       MDefinition* right);
   AbortReasonOr<Ok> jsop_pow();
   AbortReasonOr<Ok> jsop_pos();
   AbortReasonOr<Ok> jsop_neg();
   AbortReasonOr<Ok> jsop_tostring();
   AbortReasonOr<Ok> jsop_setarg(uint32_t arg);
-  AbortReasonOr<Ok> jsop_defvar(uint32_t index);
-  AbortReasonOr<Ok> jsop_deflexical(uint32_t index);
+  AbortReasonOr<Ok> jsop_defvar();
+  AbortReasonOr<Ok> jsop_deflexical();
   AbortReasonOr<Ok> jsop_deffun();
   AbortReasonOr<Ok> jsop_notearg();
   AbortReasonOr<Ok> jsop_throwsetconst();
   AbortReasonOr<Ok> jsop_checklexical();
   AbortReasonOr<Ok> jsop_checkaliasedlexical(EnvironmentCoordinate ec);
   AbortReasonOr<Ok> jsop_funcall(uint32_t argc);
   AbortReasonOr<Ok> jsop_funapply(uint32_t argc);
   AbortReasonOr<Ok> jsop_funapplyarguments(uint32_t argc);
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -136,17 +136,18 @@ void LIRGenerator::visitCheckOverRecurse
 void LIRGenerator::visitDefVar(MDefVar* ins) {
   LDefVar* lir =
       new (alloc()) LDefVar(useRegisterAtStart(ins->environmentChain()));
   add(lir, ins);
   assignSafepoint(lir, ins);
 }
 
 void LIRGenerator::visitDefLexical(MDefLexical* ins) {
-  LDefLexical* lir = new (alloc()) LDefLexical();
+  LDefLexical* lir =
+      new (alloc()) LDefLexical(useRegisterAtStart(ins->environmentChain()));
   add(lir, ins);
   assignSafepoint(lir, ins);
 }
 
 void LIRGenerator::visitDefFun(MDefFun* ins) {
   MDefinition* fun = ins->fun();
   MOZ_ASSERT(fun->type() == MIRType::Object);
 
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -6313,33 +6313,27 @@ class MDefVar : public MUnaryInstruction
  public:
   INSTRUCTION_HEADER(DefVar)
   TRIVIAL_NEW_WRAPPERS
   NAMED_OPERANDS((0, environmentChain))
 
   bool possiblyCalls() const override { return true; }
 };
 
-class MDefLexical : public MNullaryInstruction {
-  CompilerPropertyName name_;  // Target name to be defined.
-  unsigned attrs_;             // Attributes to be set.
-
+class MDefLexical : public MUnaryInstruction, public NoTypePolicy::Data {
  private:
-  MDefLexical(PropertyName* name, unsigned attrs)
-      : MNullaryInstruction(classOpcode), name_(name), attrs_(attrs) {}
+  explicit MDefLexical(MDefinition* envChain)
+      : MUnaryInstruction(classOpcode, envChain) {}
 
  public:
   INSTRUCTION_HEADER(DefLexical)
   TRIVIAL_NEW_WRAPPERS
-
-  PropertyName* name() const { return name_; }
-  unsigned attrs() const { return attrs_; }
-  bool appendRoots(MRootList& roots) const override {
-    return roots.append(name_);
-  }
+  NAMED_OPERANDS((0, environmentChain))
+
+  bool possiblyCalls() const override { return true; }
 };
 
 class MDefFun : public MBinaryInstruction, public ObjectPolicy<0>::Data {
  private:
   MDefFun(MDefinition* fun, MDefinition* envChain)
       : MBinaryInstruction(classOpcode, fun, envChain) {}
 
  public:
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -184,33 +184,16 @@ bool CheckOverRecursedBaseline(JSContext
   if (frame->overRecursed()) {
     ReportOverRecursed(cx);
     return false;
   }
 
   return CheckOverRecursed(cx);
 }
 
-bool DefLexical(JSContext* cx, HandlePropertyName dn, unsigned attrs,
-                HandleObject envChain) {
-  // Find the extensible lexical scope.
-  Rooted<LexicalEnvironmentObject*> lexicalEnv(
-      cx, &NearestEnclosingExtensibleLexicalEnvironment(envChain));
-
-  // Find the variables object.
-  RootedObject varObj(cx, &GetVariablesObject(envChain));
-  return DefLexicalOperation(cx, lexicalEnv, varObj, dn, attrs);
-}
-
-bool DefGlobalLexical(JSContext* cx, HandlePropertyName dn, unsigned attrs) {
-  Rooted<LexicalEnvironmentObject*> globalLexical(
-      cx, &cx->global()->lexicalEnvironment());
-  return DefLexicalOperation(cx, globalLexical, cx->global(), dn, attrs);
-}
-
 bool MutatePrototype(JSContext* cx, HandlePlainObject obj, HandleValue value) {
   if (!value.isObjectOrNull()) {
     return true;
   }
 
   RootedObject newProto(cx, value.toObjectOrNull());
   return SetPrototype(cx, obj, newProto);
 }
--- a/js/src/jit/VMFunctions.h
+++ b/js/src/jit/VMFunctions.h
@@ -916,20 +916,16 @@ MOZ_MUST_USE bool InvokeFunctionShuffleN
 
 class InterpreterStubExitFrameLayout;
 bool InvokeFromInterpreterStub(JSContext* cx,
                                InterpreterStubExitFrameLayout* frame);
 
 bool CheckOverRecursed(JSContext* cx);
 bool CheckOverRecursedBaseline(JSContext* cx, BaselineFrame* frame);
 
-MOZ_MUST_USE bool DefLexical(JSContext* cx, HandlePropertyName dn,
-                             unsigned attrs, HandleObject scopeChain);
-MOZ_MUST_USE bool DefGlobalLexical(JSContext* cx, HandlePropertyName dn,
-                                   unsigned attrs);
 MOZ_MUST_USE bool MutatePrototype(JSContext* cx, HandlePlainObject obj,
                                   HandleValue value);
 MOZ_MUST_USE bool InitProp(JSContext* cx, HandleObject obj,
                            HandlePropertyName name, HandleValue value,
                            jsbytecode* pc);
 
 template <bool Equal>
 bool LooselyEqual(JSContext* cx, MutableHandleValue lhs, MutableHandleValue rhs,
--- a/js/src/jit/shared/LIR-shared.h
+++ b/js/src/jit/shared/LIR-shared.h
@@ -707,22 +707,26 @@ class LDefVar : public LCallInstructionH
       : LCallInstructionHelper(classOpcode) {
     setOperand(0, envChain);
   }
 
   const LAllocation* environmentChain() { return getOperand(0); }
   MDefVar* mir() const { return mir_->toDefVar(); }
 };
 
-class LDefLexical : public LCallInstructionHelper<0, 0, 0> {
+class LDefLexical : public LCallInstructionHelper<0, 1, 0> {
  public:
   LIR_HEADER(DefLexical)
 
-  LDefLexical() : LCallInstructionHelper(classOpcode) {}
-
+  explicit LDefLexical(const LAllocation& envChain)
+      : LCallInstructionHelper(classOpcode) {
+    setOperand(0, envChain);
+  }
+
+  const LAllocation* environmentChain() { return getOperand(0); }
   MDefLexical* mir() const { return mir_->toDefLexical(); }
 };
 
 class LDefFun : public LCallInstructionHelper<0, 2, 0> {
  public:
   LIR_HEADER(DefFun)
 
   LDefFun(const LAllocation& fun, const LAllocation& envChain)
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -4617,53 +4617,52 @@ bool js::DefVarOperation(JSContext* cx, 
     if (!varobj->as<GlobalObject>().realm()->addToVarNames(cx, name)) {
       return false;
     }
   }
 
   return true;
 }
 
-bool js::DefLexicalOperation(JSContext* cx,
-                             Handle<LexicalEnvironmentObject*> lexicalEnv,
-                             HandleObject varObj, HandlePropertyName name,
-                             unsigned attrs) {
-  // Redeclaration checks should have already been done.
-  MOZ_ASSERT(CheckLexicalNameConflict(cx, lexicalEnv, varObj, name));
-  RootedId id(cx, NameToId(name));
-  RootedValue uninitialized(cx, MagicValue(JS_UNINITIALIZED_LEXICAL));
-  return NativeDefineDataProperty(cx, lexicalEnv, id, uninitialized, attrs);
-}
-
 bool js::DefLexicalOperation(JSContext* cx, HandleObject envChain,
                              HandleScript script, jsbytecode* pc) {
   MOZ_ASSERT(*pc == JSOP_DEFLET || *pc == JSOP_DEFCONST);
 
-  RootedPropertyName name(cx, script->getName(pc));
-
   unsigned attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT;
   if (*pc == JSOP_DEFCONST) {
     attrs |= JSPROP_READONLY;
   }
 
   Rooted<LexicalEnvironmentObject*> lexicalEnv(cx);
-  RootedObject varObj(cx);
   if (script->hasNonSyntacticScope()) {
     lexicalEnv = &NearestEnclosingExtensibleLexicalEnvironment(envChain);
+  } else {
+    lexicalEnv = &cx->global()->lexicalEnvironment();
+  }
+
+#ifdef DEBUG
+  RootedObject varObj(cx);
+  if (script->hasNonSyntacticScope()) {
     varObj = &GetVariablesObject(envChain);
   } else {
-    lexicalEnv = &cx->global()->lexicalEnvironment();
     varObj = cx->global();
   }
 
   MOZ_ASSERT_IF(!script->hasNonSyntacticScope(),
                 lexicalEnv == &cx->global()->lexicalEnvironment() &&
                     varObj == cx->global());
 
-  return DefLexicalOperation(cx, lexicalEnv, varObj, name, attrs);
+  // Redeclaration checks should have already been done.
+  RootedPropertyName name(cx, script->getName(pc));
+  MOZ_ASSERT(CheckLexicalNameConflict(cx, lexicalEnv, varObj, name));
+#endif
+
+  RootedId id(cx, NameToId(script->getName(pc)));
+  RootedValue uninitialized(cx, MagicValue(JS_UNINITIALIZED_LEXICAL));
+  return NativeDefineDataProperty(cx, lexicalEnv, id, uninitialized, attrs);
 }
 
 bool js::DefFunOperation(JSContext* cx, HandleScript script,
                          HandleObject envChain, HandleFunction fun) {
   /*
    * We define the function as a property of the variable object and not the
    * current scope chain even for the case of function expression statements
    * and functions defined by eval inside let or with blocks.
--- a/js/src/vm/Interpreter.h
+++ b/js/src/vm/Interpreter.h
@@ -444,21 +444,16 @@ template <bool strict>
 bool DeleteElementJit(JSContext* cx, HandleValue val, HandleValue index,
                       bool* bv);
 
 JSObject* BindVarOperation(JSContext* cx, JSObject* envChain);
 
 bool DefVarOperation(JSContext* cx, HandleObject envChain, HandleScript script,
                      jsbytecode* pc);
 
-bool DefLexicalOperation(JSContext* cx,
-                         Handle<LexicalEnvironmentObject*> lexicalEnv,
-                         HandleObject varObj, HandlePropertyName name,
-                         unsigned attrs);
-
 bool DefLexicalOperation(JSContext* cx, HandleObject envChain,
                          HandleScript script, jsbytecode* pc);
 
 bool DefFunOperation(JSContext* cx, HandleScript script, HandleObject envChain,
                      HandleFunction funArg);
 
 bool ThrowMsgOperation(JSContext* cx, const unsigned errorNum);