Bug 1627374 - Eliminate FunctionEmitter dependence on JSFunction* r=tcampbell
authorMatthew Gaudet <mgaudet@mozilla.com>
Mon, 06 Apr 2020 17:14:49 +0000
changeset 522433 ca64fc2b6e7e727394dc0e13e4e42a50b8cb6897
parent 522432 89ccbf43e9e07c8bb941aa2289366f4586ad226b
child 522434 6c29976af9749fab2349d4ea676bc0f58edb7af7
push id37290
push useraciure@mozilla.com
push dateTue, 07 Apr 2020 03:53:09 +0000
treeherdermozilla-central@b7d4ff29805d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstcampbell
bugs1627374
milestone76.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 1627374 - Eliminate FunctionEmitter dependence on JSFunction* r=tcampbell Differential Revision: https://phabricator.services.mozilla.com/D69645
js/src/frontend/FunctionEmitter.cpp
js/src/frontend/FunctionEmitter.h
js/src/frontend/SharedContext.cpp
js/src/frontend/SharedContext.h
js/src/wasm/AsmJS.cpp
--- a/js/src/frontend/FunctionEmitter.cpp
+++ b/js/src/frontend/FunctionEmitter.cpp
@@ -29,17 +29,16 @@ using namespace js::frontend;
 using mozilla::Maybe;
 using mozilla::Some;
 
 FunctionEmitter::FunctionEmitter(BytecodeEmitter* bce, FunctionBox* funbox,
                                  FunctionSyntaxKind syntaxKind,
                                  IsHoisted isHoisted)
     : bce_(bce),
       funbox_(funbox),
-      fun_(bce_->cx, funbox_->function()),
       name_(bce_->cx, funbox_->explicitName()),
       syntaxKind_(syntaxKind),
       isHoisted_(isHoisted) {}
 
 bool FunctionEmitter::interpretedCommon() {
   // Mark as singletons any function which will only be executed once, or
   // which is inner to a lambda we only expect to run once. In the latter
   // case, if the lambda runs multiple times then CloneFunctionObject will
@@ -187,17 +186,17 @@ bool FunctionEmitter::emitAgain() {
 #endif
   return true;
 }
 
 bool FunctionEmitter::emitAsmJSModule() {
   MOZ_ASSERT(state_ == State::Start);
 
   MOZ_ASSERT(!funbox_->wasEmitted);
-  MOZ_ASSERT(IsAsmJSModule(fun_));
+  MOZ_ASSERT(funbox_->isAsmJSModule());
 
   //                [stack]
 
   funbox_->wasEmitted = true;
 
   if (!emitFunction()) {
     //              [stack]
     return false;
--- a/js/src/frontend/FunctionEmitter.h
+++ b/js/src/frontend/FunctionEmitter.h
@@ -64,19 +64,16 @@ class MOZ_STACK_CLASS FunctionEmitter {
  public:
   enum class IsHoisted { No, Yes };
 
  private:
   BytecodeEmitter* bce_;
 
   FunctionBox* funbox_;
 
-  // Function linked from funbox_.
-  JS::Rooted<JSFunction*> fun_;
-
   // Function's explicit name.
   JS::Rooted<JSAtom*> name_;
 
   FunctionSyntaxKind syntaxKind_;
   IsHoisted isHoisted_;
 
 #ifdef DEBUG
   // The state of this emitter.
--- a/js/src/frontend/SharedContext.cpp
+++ b/js/src/frontend/SharedContext.cpp
@@ -3,16 +3,17 @@
  * 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 "frontend/SharedContext.h"
 
 #include "frontend/AbstractScopePtr.h"
 #include "frontend/ModuleSharedContext.h"
+#include "wasm/AsmJS.h"
 
 #include "frontend/ParseContext-inl.h"
 #include "vm/EnvironmentObject-inl.h"
 
 namespace js {
 namespace frontend {
 
 void SharedContext::computeAllowSyntax(Scope* scope) {
@@ -140,16 +141,17 @@ FunctionBox::FunctionBox(JSContext* cx, 
       isAnnexB(false),
       wasEmitted(false),
       emitBytecode(false),
       usesArguments(false),
       usesApply(false),
       usesThis(false),
       usesReturn(false),
       hasExprBody_(false),
+      isAsmJSModule_(false),
       nargs_(0),
       explicitName_(explicitName),
       flags_(flags) {
   immutableFlags_.setFlag(ImmutableFlags::IsGenerator,
                           generatorKind == GeneratorKind::Generator);
   immutableFlags_.setFlag(ImmutableFlags::IsAsync,
                           asyncKind == FunctionAsyncKind::AsyncFunction);
   immutableFlags_.setFlag(ImmutableFlags::IsFunction);
@@ -266,16 +268,22 @@ void FunctionBox::setEnclosingScopeForIn
   // For lazy functions inside a function which is being compiled, we cache
   // the incomplete scope object while compiling, and store it to the
   // BaseScript once the enclosing script successfully finishes compilation
   // in FunctionBox::finish.
   MOZ_ASSERT(!enclosingScope_);
   enclosingScope_ = enclosingScope;
 }
 
+void FunctionBox::setAsmJSModule(JSFunction* function) {
+  MOZ_ASSERT(IsAsmJSModule(function));
+  isAsmJSModule_ = true;
+  clobberFunction(function);
+}
+
 void FunctionBox::finish() {
   if (!emitBytecode) {
     // Lazy inner functions need to record their enclosing scope for when they
     // eventually are compiled.
     function()->setEnclosingScope(enclosingScope_.getExistingScope());
   } else {
     // Non-lazy inner functions don't use the enclosingScope_ field.
     MOZ_ASSERT(!enclosingScope_);
--- a/js/src/frontend/SharedContext.h
+++ b/js/src/frontend/SharedContext.h
@@ -350,24 +350,24 @@ class FunctionBox : public SharedContext
   bool hasParameterExprs : 1;      /* parameter list contains expressions */
   bool hasDuplicateParameters : 1; /* parameter list contains duplicate names */
   bool useAsm : 1;                 /* see useAsmOrInsideUseAsm */
   bool isAnnexB : 1;     /* need to emit a synthesized Annex B assignment */
   bool wasEmitted : 1;   /* Bytecode has been emitted for this function. */
   bool emitBytecode : 1; /* need to generate bytecode for this function. */
 
   // Fields for use in heuristics.
-  bool usesArguments : 1; /* contains a free use of 'arguments' */
-  bool usesApply : 1;     /* contains an f.apply() call */
-  bool usesThis : 1;      /* contains 'this' */
-  bool usesReturn : 1;    /* contains a 'return' statement */
-  bool hasExprBody_ : 1;  /* arrow function with expression
-                           * body like: () => 1
-                           * Only used by Reflect.parse */
-
+  bool usesArguments : 1;  /* contains a free use of 'arguments' */
+  bool usesApply : 1;      /* contains an f.apply() call */
+  bool usesThis : 1;       /* contains 'this' */
+  bool usesReturn : 1;     /* contains a 'return' statement */
+  bool hasExprBody_ : 1;   /* arrow function with expression
+                            * body like: () => 1
+                            * Only used by Reflect.parse */
+  bool isAsmJSModule_ : 1; /* Represents an AsmJS module */
   uint16_t nargs_;
 
   JSAtom* explicitName_;
   FunctionFlags flags_;
 
   MutableHandle<FunctionCreationData> functionCreationData() const;
 
   bool hasFunctionCreationData() const;
@@ -424,16 +424,19 @@ class FunctionBox : public SharedContext
   JSFunction* function() const;
 
   // Initialize FunctionBox with a deferred allocation Function
   void initializeFunction(JSFunction* fun) {
     clobberFunction(fun);
     synchronizeArgCount();
   }
 
+  void setAsmJSModule(JSFunction* function);
+  bool isAsmJSModule() { return isAsmJSModule_; }
+
   void clobberFunction(JSFunction* function);
 
   Scope* compilationEnclosingScope() const override {
     // This is used when emitting code for the current FunctionBox and therefore
     // the enclosingScope_ must have be set correctly during initalization.
 
     MOZ_ASSERT(enclosingScope_);
     return enclosingScope_.scope();
--- a/js/src/wasm/AsmJS.cpp
+++ b/js/src/wasm/AsmJS.cpp
@@ -7111,17 +7111,17 @@ static bool DoCompileAsmJS(JSContext* cx
     return false;
   }
 
   // Finished! Clobber the default function created by the parser with the new
   // asm.js module function. Special cases in the bytecode emitter avoid
   // generating bytecode for asm.js functions, allowing this asm.js module
   // function to be the finished result.
   MOZ_ASSERT(funbox->isInterpreted());
-  funbox->clobberFunction(moduleFun);
+  funbox->setAsmJSModule(moduleFun);
 
   // Success! Write to the console with a "warning" message indicating
   // total compilation time.
   *validated = true;
   SuccessfulValidation(parser, time);
   return NoExceptionPending(cx);
 }