Bug 1511891 part 3 - Refactor DefVarOperation so interpreter and JITs can call it directly. r=tcampbell
authorJan de Mooij <jdemooij@mozilla.com>
Fri, 11 Jan 2019 09:12:20 +0000
changeset 453457 452034cea923027f9db55730d5156210ff8e8ad6
parent 453456 3523e71282fd2bbb093866671f80cd923ba189b8
child 453458 8fccd1861a223be784a3cb3215ee341d9bacc5e6
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 3 - Refactor DefVarOperation so interpreter and JITs can call it directly. r=tcampbell Differential Revision: https://phabricator.services.mozilla.com/D13701
js/src/jit/BaselineCompiler.cpp
js/src/jit/CodeGenerator.cpp
js/src/jit/IonBuilder.cpp
js/src/jit/MIR.h
js/src/jit/VMFunctions.cpp
js/src/jit/VMFunctions.h
js/src/vm/Interpreter.cpp
js/src/vm/Interpreter.h
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -3068,37 +3068,31 @@ bool BaselineCodeGen<Handler>::emit_JSOP
   if (!emitNextIC()) {
     return false;
   }
 
   frame.push(R0);
   return true;
 }
 
-typedef bool (*DefVarFn)(JSContext*, HandlePropertyName, unsigned,
-                         HandleObject);
-static const VMFunction DefVarInfo = FunctionInfo<DefVarFn>(DefVar, "DefVar");
+typedef bool (*DefVarFn)(JSContext*, HandleObject, HandleScript, jsbytecode*);
+static const VMFunction DefVarInfo =
+    FunctionInfo<DefVarFn>(DefVarOperation, "DefVarOperation");
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_DEFVAR() {
   frame.syncStack(0);
 
-  unsigned attrs = JSPROP_ENUMERATE;
-  if (!script->isForEval()) {
-    attrs |= JSPROP_PERMANENT;
-  }
-  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(DefVarInfo);
 }
 
 typedef bool (*DefLexicalFn)(JSContext*, HandlePropertyName, unsigned,
                              HandleObject);
 static const VMFunction DefLexicalInfo =
     FunctionInfo<DefLexicalFn>(DefLexical, "DefLexical");
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -5398,26 +5398,29 @@ void CodeGenerator::visitCheckOverRecurs
 
   // Conditional forward (unlikely) branch to failure.
   const void* limitAddr = gen->runtime->addressOfJitStackLimit();
   masm.branchStackPtrRhs(Assembler::AboveOrEqual, AbsoluteAddress(limitAddr),
                          ool->entry());
   masm.bind(ool->rejoin());
 }
 
-typedef bool (*DefVarFn)(JSContext*, HandlePropertyName, unsigned,
-                         HandleObject);
-static const VMFunction DefVarInfo = FunctionInfo<DefVarFn>(DefVar, "DefVar");
+typedef bool (*DefVarFn)(JSContext*, HandleObject, HandleScript, jsbytecode*);
+static const VMFunction DefVarInfo =
+    FunctionInfo<DefVarFn>(DefVarOperation, "DefVarOperation");
 
 void CodeGenerator::visitDefVar(LDefVar* lir) {
   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*
-  pushArg(Imm32(lir->mir()->attrs()));    // unsigned
-  pushArg(ImmGCPtr(lir->mir()->name()));  // PropertyName*
 
   callVM(DefVarInfo, lir);
 }
 
 typedef bool (*DefLexicalFn)(JSContext*, HandlePropertyName, unsigned);
 static const VMFunction DefLexicalInfo =
     FunctionInfo<DefLexicalFn>(DefGlobalLexical, "DefGlobalLexical");
 
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -12773,28 +12773,20 @@ AbortReasonOr<Ok> IonBuilder::jsop_setar
 
   current->setArg(arg);
   return Ok();
 }
 
 AbortReasonOr<Ok> IonBuilder::jsop_defvar(uint32_t index) {
   MOZ_ASSERT(JSOp(*pc) == JSOP_DEFVAR);
 
-  PropertyName* name = script()->getName(index);
-
-  // Bake in attrs.
-  unsigned attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT;
-  MOZ_ASSERT(!script()->isForEval());
-
   // Pass the EnvironmentChain.
   MOZ_ASSERT(usesEnvironmentChain());
 
-  // Bake the name pointer into the MDefVar.
-  MDefVar* defvar =
-      MDefVar::New(alloc(), name, attrs, current->environmentChain());
+  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());
   MOZ_ASSERT(JSOp(*pc) == JSOP_DEFLET || JSOp(*pc) == JSOP_DEFCONST);
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -6301,35 +6301,26 @@ class MGlobalNameConflictsCheck : public
 
  public:
   INSTRUCTION_HEADER(GlobalNameConflictsCheck)
   TRIVIAL_NEW_WRAPPERS
 };
 
 // If not defined, set a global variable to |undefined|.
 class MDefVar : public MUnaryInstruction, public NoTypePolicy::Data {
-  CompilerPropertyName name_;  // Target name to be defined.
-  unsigned attrs_;             // Attributes to be set.
-
  private:
-  MDefVar(PropertyName* name, unsigned attrs, MDefinition* envChain)
-      : MUnaryInstruction(classOpcode, envChain), name_(name), attrs_(attrs) {}
+  explicit MDefVar(MDefinition* envChain)
+      : MUnaryInstruction(classOpcode, envChain) {}
 
  public:
   INSTRUCTION_HEADER(DefVar)
   TRIVIAL_NEW_WRAPPERS
   NAMED_OPERANDS((0, environmentChain))
 
-  PropertyName* name() const { return name_; }
-  unsigned attrs() const { return attrs_; }
-
   bool possiblyCalls() const override { return true; }
-  bool appendRoots(MRootList& roots) const override {
-    return roots.append(name_);
-  }
 };
 
 class MDefLexical : public MNullaryInstruction {
   CompilerPropertyName name_;  // Target name to be defined.
   unsigned attrs_;             // Attributes to be set.
 
  private:
   MDefLexical(PropertyName* name, unsigned attrs)
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -184,23 +184,16 @@ bool CheckOverRecursedBaseline(JSContext
   if (frame->overRecursed()) {
     ReportOverRecursed(cx);
     return false;
   }
 
   return CheckOverRecursed(cx);
 }
 
-bool DefVar(JSContext* cx, HandlePropertyName dn, unsigned attrs,
-            HandleObject envChain) {
-  // Given the ScopeChain, extract the VarObj.
-  RootedObject obj(cx, &GetVariablesObject(envChain));
-  return DefVarOperation(cx, obj, dn, attrs);
-}
-
 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));
--- a/js/src/jit/VMFunctions.h
+++ b/js/src/jit/VMFunctions.h
@@ -916,18 +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 DefVar(JSContext* cx, HandlePropertyName dn, unsigned attrs,
-                         HandleObject scopeChain);
 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,
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -3613,27 +3613,18 @@ static MOZ_NEVER_INLINE JS_HAZ_JSNATIVE_
 
       MOZ_ASSERT(!IsUninitializedLexical(REGS.fp()->unaliasedLocal(i)));
 
       REGS.fp()->unaliasedLocal(i) = REGS.sp[-1];
     }
     END_CASE(JSOP_SETLOCAL)
 
     CASE(JSOP_DEFVAR) {
-      /* ES5 10.5 step 8 (with subsequent errata). */
-      unsigned attrs = JSPROP_ENUMERATE;
-      if (!REGS.fp()->isEvalFrame()) {
-        attrs |= JSPROP_PERMANENT;
-      }
-
-      /* Step 8b. */
-      ReservedRooted<JSObject*> obj(&rootObject0, &REGS.fp()->varObj());
-      ReservedRooted<PropertyName*> name(&rootName0, script->getName(REGS.pc));
-
-      if (!DefVarOperation(cx, obj, name, attrs)) {
+      HandleObject env = REGS.fp()->environmentChain();
+      if (!DefVarOperation(cx, env, script, REGS.pc)) {
         goto error;
       }
     }
     END_CASE(JSOP_DEFVAR)
 
     CASE(JSOP_DEFCONST)
     CASE(JSOP_DEFLET) {
       LexicalEnvironmentObject* lexicalEnv;
@@ -4587,46 +4578,56 @@ JSObject* js::LambdaArrow(JSContext* cx,
 }
 
 JSObject* js::BindVarOperation(JSContext* cx, JSObject* envChain) {
   // Note: BindVarOperation has an unused cx argument because the JIT callVM
   // machinery requires this.
   return &GetVariablesObject(envChain);
 }
 
-bool js::DefVarOperation(JSContext* cx, HandleObject varobj,
-                         HandlePropertyName dn, unsigned attrs) {
+bool js::DefVarOperation(JSContext* cx, HandleObject envChain,
+                         HandleScript script, jsbytecode* pc) {
+  MOZ_ASSERT(JSOp(*pc) == JSOP_DEFVAR);
+
+  RootedObject varobj(cx, &GetVariablesObject(envChain));
   MOZ_ASSERT(varobj->isQualifiedVarObj());
 
+  RootedPropertyName name(cx, script->getName(pc));
+
+  unsigned attrs = JSPROP_ENUMERATE;
+  if (!script->isForEval()) {
+    attrs |= JSPROP_PERMANENT;
+  }
+
 #ifdef DEBUG
   // Per spec, it is an error to redeclare a lexical binding. This should
   // have already been checked.
   if (JS_HasExtensibleLexicalEnvironment(varobj)) {
     Rooted<LexicalEnvironmentObject*> lexicalEnv(cx);
     lexicalEnv = &JS_ExtensibleLexicalEnvironment(varobj)
                       ->as<LexicalEnvironmentObject>();
-    MOZ_ASSERT(CheckVarNameConflict(cx, lexicalEnv, dn));
+    MOZ_ASSERT(CheckVarNameConflict(cx, lexicalEnv, name));
   }
 #endif
 
   Rooted<PropertyResult> prop(cx);
   RootedObject obj2(cx);
-  if (!LookupProperty(cx, varobj, dn, &obj2, &prop)) {
+  if (!LookupProperty(cx, varobj, name, &obj2, &prop)) {
     return false;
   }
 
   /* Steps 8c, 8d. */
   if (!prop || (obj2 != varobj && varobj->is<GlobalObject>())) {
-    if (!DefineDataProperty(cx, varobj, dn, UndefinedHandleValue, attrs)) {
+    if (!DefineDataProperty(cx, varobj, name, UndefinedHandleValue, attrs)) {
       return false;
     }
   }
 
   if (varobj->is<GlobalObject>()) {
-    if (!varobj->as<GlobalObject>().realm()->addToVarNames(cx, dn)) {
+    if (!varobj->as<GlobalObject>().realm()->addToVarNames(cx, name)) {
       return false;
     }
   }
 
   return true;
 }
 
 bool js::DefFunOperation(JSContext* cx, HandleScript script,
--- a/js/src/vm/Interpreter.h
+++ b/js/src/vm/Interpreter.h
@@ -441,18 +441,18 @@ bool DeletePropertyJit(JSContext* ctx, H
                        bool* bv);
 
 template <bool strict>
 bool DeleteElementJit(JSContext* cx, HandleValue val, HandleValue index,
                       bool* bv);
 
 JSObject* BindVarOperation(JSContext* cx, JSObject* envChain);
 
-bool DefVarOperation(JSContext* cx, HandleObject varobj, HandlePropertyName dn,
-                     unsigned attrs);
+bool DefVarOperation(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);
 
 bool GetAndClearException(JSContext* cx, MutableHandleValue res);