Bug 1520452 part 2 - Move remaining compiler-specific fields from BaselineCodeGen to BaselineCompilerHandler. r=djvj
authorJan de Mooij <jdemooij@mozilla.com>
Sun, 27 Jan 2019 08:54:48 +0000
changeset 515578 ef038a8b19442250bef744c830b4fecb884ad426
parent 515577 11f88edba10fcab0a5e508b1fba9b58203a51fa4
child 515584 d743672a092cac271f2a0ca0a7976161fb2c19f7
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
bugs1520452
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 1520452 part 2 - Move remaining compiler-specific fields from BaselineCodeGen to BaselineCompilerHandler. r=djvj Differential Revision: https://phabricator.services.mozilla.com/D16690
js/src/jit/BaselineCompiler.cpp
js/src/jit/BaselineCompiler.h
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -40,91 +40,88 @@ using namespace js;
 using namespace js::jit;
 
 using mozilla::AssertedCast;
 using mozilla::Maybe;
 
 namespace js {
 namespace jit {
 
-BaselineCompilerHandler::BaselineCompilerHandler(MacroAssembler& masm,
+BaselineCompilerHandler::BaselineCompilerHandler(JSContext* cx,
+                                                 MacroAssembler& masm,
                                                  TempAllocator& alloc,
                                                  JSScript* script)
     : frame_(script, masm),
       alloc_(alloc),
+      analysis_(alloc, script),
       script_(script),
       pc_(script->code()),
-      compileDebugInstrumentation_(script->isDebuggee()) {}
-
-BaselineInterpreterHandler::BaselineInterpreterHandler(MacroAssembler& masm)
+      icEntryIndex_(0),
+      compileDebugInstrumentation_(script->isDebuggee()),
+      ionCompileable_(jit::IsIonEnabled(cx) &&
+                      CanIonCompileScript(cx, script)) {}
+
+BaselineInterpreterHandler::BaselineInterpreterHandler(JSContext* cx,
+                                                       MacroAssembler& masm)
     : frame_(masm) {}
 
 template <typename Handler>
 template <typename... HandlerArgs>
-BaselineCodeGen<Handler>::BaselineCodeGen(JSContext* cx, TempAllocator& alloc,
-                                          JSScript* script,
-                                          HandlerArgs&&... args)
-    : handler(masm, std::forward<HandlerArgs>(args)...),
+BaselineCodeGen<Handler>::BaselineCodeGen(JSContext* cx, HandlerArgs&&... args)
+    : handler(cx, masm, std::forward<HandlerArgs>(args)...),
       cx(cx),
-      ionCompileable_(jit::IsIonEnabled(cx) && CanIonCompileScript(cx, script)),
-      alloc_(alloc),
-      analysis_(alloc, script),
       frame(handler.frame()),
       traceLoggerToggleOffsets_(cx),
-      icEntryIndex_(0),
       pushedBeforeCall_(0),
 #ifdef DEBUG
       inCall_(false),
 #endif
       modifiesArguments_(false) {
 }
 
 BaselineCompiler::BaselineCompiler(JSContext* cx, TempAllocator& alloc,
                                    JSScript* script)
-    : BaselineCodeGen(cx, alloc, script,
-                      /* HandlerArgs = */ alloc, script),
+    : BaselineCodeGen(cx, /* HandlerArgs = */ alloc, script),
       pcMappingEntries_(),
       profilerPushToggleOffset_(),
       profilerEnterFrameToggleOffset_(),
       profilerExitFrameToggleOffset_(),
       traceLoggerScriptTextIdOffset_() {
 #ifdef JS_CODEGEN_NONE
   MOZ_CRASH();
 #endif
 }
 
-BaselineInterpreterGenerator::BaselineInterpreterGenerator(JSContext* cx,
-                                                           TempAllocator& alloc)
-    // Note: the nullptr script here is temporary. See bug 1519378.
-    : BaselineCodeGen(cx, alloc, /* script = */ nullptr) {}
-
-bool BaselineCompilerHandler::init() {
+BaselineInterpreterGenerator::BaselineInterpreterGenerator(JSContext* cx)
+    : BaselineCodeGen(cx /* no handlerArgs */) {}
+
+bool BaselineCompilerHandler::init(JSContext* cx) {
+  if (!analysis_.init(alloc_, cx->caches().gsnCache)) {
+    return false;
+  }
+
   uint32_t len = script_->length();
 
   if (!labels_.init(alloc_, len)) {
     return false;
   }
 
   for (size_t i = 0; i < len; i++) {
     new (&labels_[i]) Label();
   }
 
+  if (!frame_.init(alloc_)) {
+    return false;
+  }
+
   return true;
 }
 
 bool BaselineCompiler::init() {
-  if (!analysis_.init(alloc_, cx->caches().gsnCache)) {
-    return false;
-  }
-
-  if (!handler.init()) {
-    return false;
-  }
-
-  if (!frame.init(alloc_)) {
+  if (!handler.init(cx)) {
     return false;
   }
 
   return true;
 }
 
 bool BaselineCompiler::addPCMappingEntry(bool addIndexEntry) {
   // Don't add multiple entries for a single pc.
@@ -310,17 +307,17 @@ MethodStatus BaselineCompiler::compile()
   if (cx->runtime()->jitRuntime()->isProfilerInstrumentationEnabled(
           cx->runtime())) {
     baselineScript->toggleProfilerInstrumentation(true);
   }
 
   if (modifiesArguments_) {
     baselineScript->setModifiesArguments();
   }
-  if (analysis_.usesEnvironmentChain()) {
+  if (handler.analysis().usesEnvironmentChain()) {
     baselineScript->setUsesEnvironmentChain();
   }
 
 #ifdef JS_TRACE_LOGGING
   // Initialize the tracelogger instrumentation.
   baselineScript->initTraceLogger(script, traceLoggerToggleOffsets_);
 #endif
 
@@ -456,18 +453,18 @@ bool BaselineCompilerCodeGen::emitNextIC
 
   JSScript* script = handler.script();
   uint32_t pcOffset = script->pcToOffset(handler.pc());
 
   // We don't use every ICEntry and we can skip unreachable ops, so we have
   // to loop until we find an ICEntry for the current pc.
   const ICEntry* entry;
   do {
-    entry = &script->icScript()->icEntry(icEntryIndex_);
-    icEntryIndex_++;
+    entry = &script->icScript()->icEntry(handler.icEntryIndex());
+    handler.moveToNextICEntry();
   } while (entry->pcOffset() < pcOffset);
 
   MOZ_RELEASE_ASSERT(entry->pcOffset() == pcOffset);
   MOZ_ASSERT_IF(entry->isForOp(), BytecodeOpHasIC(JSOp(*handler.pc())));
 
   CodeOffset callOffset;
   EmitCallIC(masm, entry, &callOffset);
 
@@ -932,17 +929,17 @@ static const VMFunction IonCompileScript
     FunctionInfo<IonCompileScriptForBaselineFn>(IonCompileScriptForBaseline,
                                                 "IonCompileScriptForBaseline");
 
 template <>
 bool BaselineCompilerCodeGen::emitWarmUpCounterIncrement() {
   // Emit no warm-up counter increments or bailouts if Ion is not
   // enabled, or if the script will never be Ion-compileable
 
-  if (!ionCompileable_) {
+  if (!handler.maybeIonCompileable()) {
     return true;
   }
 
   frame.assertSyncedStack();
 
   Register scriptReg = R2.scratchReg();
   Register countReg = R0.scratchReg();
   Address warmUpCounterAddr(scriptReg, JSScript::offsetOfWarmUpCounter());
@@ -952,17 +949,17 @@ bool BaselineCompilerCodeGen::emitWarmUp
   masm.load32(warmUpCounterAddr, countReg);
   masm.add32(Imm32(1), countReg);
   masm.store32(countReg, warmUpCounterAddr);
 
   jsbytecode* pc = handler.pc();
   if (JSOp(*pc) == JSOP_LOOPENTRY) {
     // If this is a loop inside a catch or finally block, increment the warmup
     // counter but don't attempt OSR (Ion only compiles the try block).
-    if (analysis_.info(pc).loopEntryInCatchOrFinally) {
+    if (handler.analysis().info(pc).loopEntryInCatchOrFinally) {
       return true;
     }
 
     if (!LoopEntryCanIonOsr(pc)) {
       // OSR into Ion not possible at this loop entry.
       return true;
     }
   }
@@ -2978,17 +2975,17 @@ Address BaselineCodeGen<Handler>::getEnv
 
 template <typename Handler>
 bool BaselineCodeGen<Handler>::emit_JSOP_GETALIASEDVAR() {
   frame.syncStack(0);
 
   Address address = getEnvironmentCoordinateAddress(R0.scratchReg());
   masm.loadValue(address, R0);
 
-  if (ionCompileable_) {
+  if (handler.maybeIonCompileable()) {
     // No need to monitor types if we know Ion can't compile this script.
     if (!emitNextIC()) {
       return false;
     }
   }
 
   frame.push(R0);
   return true;
@@ -3139,17 +3136,17 @@ bool BaselineCompilerCodeGen::emit_JSOP_
   // Imports are initialized by this point except in rare circumstances, so
   // don't emit a check unless we have to.
   if (targetEnv->getSlot(shape->slot()).isMagic(JS_UNINITIALIZED_LEXICAL)) {
     if (!emitUninitializedLexicalCheck(R0)) {
       return false;
     }
   }
 
-  if (ionCompileable_) {
+  if (handler.maybeIonCompileable()) {
     // No need to monitor types if we know Ion can't compile this script.
     if (!emitNextIC()) {
       return false;
     }
   }
 
   frame.push(R0);
   return true;
@@ -5732,17 +5729,17 @@ MethodStatus BaselineCompiler::emitBody(
   uint32_t emittedOps = 0;
   mozilla::DebugOnly<jsbytecode*> prevpc = handler.pc();
 
   while (true) {
     JSOp op = JSOp(*handler.pc());
     JitSpew(JitSpew_BaselineOp, "Compiling op @ %d: %s",
             int(script->pcToOffset(handler.pc())), CodeName[op]);
 
-    BytecodeInfo* info = analysis_.maybeInfo(handler.pc());
+    BytecodeInfo* info = handler.analysis().maybeInfo(handler.pc());
 
     // Skip unreachable ops.
     if (!info) {
       // Test if last instructions and stop emitting in that case.
       handler.moveToNextPC();
       if (handler.pc() >= script->codeEnd()) {
         break;
       }
--- a/js/src/jit/BaselineCompiler.h
+++ b/js/src/jit/BaselineCompiler.h
@@ -258,41 +258,34 @@ namespace jit {
 // this class to specialize behavior.
 template <typename Handler>
 class BaselineCodeGen {
  protected:
   Handler handler;
 
   JSContext* cx;
   StackMacroAssembler masm;
-  bool ionCompileable_;
 
-  TempAllocator& alloc_;
-  BytecodeAnalysis analysis_;
   typename Handler::FrameInfoT& frame;
 
   js::Vector<CodeOffset> traceLoggerToggleOffsets_;
 
   NonAssertingLabel return_;
   NonAssertingLabel postBarrierSlot_;
 
-  // Index of the current ICEntry in the script's ICScript.
-  uint32_t icEntryIndex_;
-
   uint32_t pushedBeforeCall_;
 #ifdef DEBUG
   bool inCall_;
 #endif
 
   // Whether any on stack arguments are modified.
   bool modifiesArguments_;
 
   template <typename... HandlerArgs>
-  BaselineCodeGen(JSContext* cx, TempAllocator& alloc, JSScript* script,
-                  HandlerArgs&&... args);
+  explicit BaselineCodeGen(JSContext* cx, HandlerArgs&&... args);
 
   template <typename T>
   void pushArg(const T& t) {
     masm.Push(t);
   }
 
   // Pushes the current script as argument for a VM function.
   void pushScriptArg();
@@ -444,29 +437,35 @@ class BaselineCodeGen {
 };
 
 using RetAddrEntryVector = js::Vector<RetAddrEntry, 16, SystemAllocPolicy>;
 
 // Interface used by BaselineCodeGen for BaselineCompiler.
 class BaselineCompilerHandler {
   CompilerFrameInfo frame_;
   TempAllocator& alloc_;
+  BytecodeAnalysis analysis_;
   FixedList<Label> labels_;
   RetAddrEntryVector retAddrEntries_;
   JSScript* script_;
   jsbytecode* pc_;
+
+  // Index of the current ICEntry in the script's ICScript.
+  uint32_t icEntryIndex_;
+
   bool compileDebugInstrumentation_;
+  bool ionCompileable_;
 
  public:
   using FrameInfoT = CompilerFrameInfo;
 
-  BaselineCompilerHandler(MacroAssembler& masm, TempAllocator& alloc,
-                          JSScript* script);
+  BaselineCompilerHandler(JSContext* cx, MacroAssembler& masm,
+                          TempAllocator& alloc, JSScript* script);
 
-  MOZ_MUST_USE bool init();
+  MOZ_MUST_USE bool init(JSContext* cx);
 
   CompilerFrameInfo& frame() { return frame_; }
 
   jsbytecode* pc() const { return pc_; }
   jsbytecode* maybePC() const { return pc_; }
 
   void moveToNextPC() { pc_ += GetBytecodeLength(pc_); }
   Label* labelOf(jsbytecode* pc) { return &labels_[script_->pcToOffset(pc)]; }
@@ -485,16 +484,23 @@ class BaselineCompilerHandler {
 
   ModuleObject* module() const { return script_->module(); }
 
   void setCompileDebugInstrumentation() { compileDebugInstrumentation_ = true; }
   bool compileDebugInstrumentation() const {
     return compileDebugInstrumentation_;
   }
 
+  bool maybeIonCompileable() const { return ionCompileable_; }
+
+  uint32_t icEntryIndex() const { return icEntryIndex_; }
+  void moveToNextICEntry() { icEntryIndex_++; }
+
+  BytecodeAnalysis& analysis() { return analysis_; }
+
   RetAddrEntryVector& retAddrEntries() { return retAddrEntries_; }
 
   MOZ_MUST_USE bool appendRetAddrEntry(JSContext* cx, RetAddrEntry::Kind kind,
                                        uint32_t retOffset) {
     if (!retAddrEntries_.emplaceBack(script_->pcToOffset(pc_), kind,
                                      CodeOffset(retOffset))) {
       ReportOutOfMemory(cx);
       return false;
@@ -574,18 +580,16 @@ class BaselineCompiler final : private B
       default: {
         PCMappingSlotInfo::SlotLocation loc1 = frame.stackValueSlotLocation(-1);
         PCMappingSlotInfo::SlotLocation loc2 = frame.stackValueSlotLocation(-2);
         return PCMappingSlotInfo::MakeSlotInfo(loc1, loc2);
       }
     }
   }
 
-  BytecodeAnalysis& analysis() { return analysis_; }
-
   MethodStatus emitBody();
 
   void emitInitializeLocals();
   MOZ_MUST_USE bool emitPrologue();
   MOZ_MUST_USE bool emitEpilogue();
   MOZ_MUST_USE bool emitOutOfLinePostBarrierSlot();
   MOZ_MUST_USE bool emitStackCheck();
   MOZ_MUST_USE bool emitArgumentTypeChecks();
@@ -605,40 +609,42 @@ class BaselineCompiler final : private B
 
 // Interface used by BaselineCodeGen for BaselineInterpreterGenerator.
 class BaselineInterpreterHandler {
   InterpreterFrameInfo frame_;
 
  public:
   using FrameInfoT = InterpreterFrameInfo;
 
-  explicit BaselineInterpreterHandler(MacroAssembler& masm);
+  explicit BaselineInterpreterHandler(JSContext* cx, MacroAssembler& masm);
 
   InterpreterFrameInfo& frame() { return frame_; }
 
   // Interpreter doesn't know the script and pc statically.
   jsbytecode* maybePC() const { return nullptr; }
   bool isDefinitelyLastOp() const { return false; }
   JSScript* maybeScript() const { return nullptr; }
   JSFunction* maybeFunction() const { return nullptr; }
 
   // Interpreter doesn't need to keep track of RetAddrEntries, so these methods
   // are no-ops.
   MOZ_MUST_USE bool appendRetAddrEntry(JSContext* cx, RetAddrEntry::Kind kind,
                                        uint32_t retOffset) {
     return true;
   }
   void markLastRetAddrEntryKind(RetAddrEntry::Kind) {}
+
+  bool maybeIonCompileable() const { return true; }
 };
 
 using BaselineInterpreterCodeGen = BaselineCodeGen<BaselineInterpreterHandler>;
 
 class BaselineInterpreterGenerator final : private BaselineInterpreterCodeGen {
  public:
-  BaselineInterpreterGenerator(JSContext* cx, TempAllocator& alloc);
+  explicit BaselineInterpreterGenerator(JSContext* cx);
 };
 
 extern const VMFunction NewArrayCopyOnWriteInfo;
 extern const VMFunction ImplicitThisInfo;
 
 }  // namespace jit
 }  // namespace js