Backed out 2 changesets (bug 1502159)for spidermonkey busteges on CacheIRCompiler.cpp:1624
authorarthur.iakab <aiakab@mozilla.com>
Fri, 26 Oct 2018 18:18:35 +0300
changeset 499574 fe1c408db5321673b4dfcc2a7236afadbe2bde15
parent 499573 4bf59f00f700b25a3c6d983ed01af60b9ff6d9cc
child 499575 a3c737408598118378a6a44dc32e92342a317f1b
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1502159
milestone65.0a1
backs outcde1c74945a22fc553e7893db1c8845b6263d2c3
3333ccf6f6ff24178faaa3382a9a08197e8af024
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
Backed out 2 changesets (bug 1502159)for spidermonkey busteges on CacheIRCompiler.cpp:1624 Backed out changeset cde1c74945a2 (bug 1502159) Backed out changeset 3333ccf6f6ff (bug 1502159)
js/src/jit/BacktrackingAllocator.h
js/src/jit/C1Spewer.cpp
js/src/jit/C1Spewer.h
js/src/jit/JitSpewer.cpp
js/src/jit/JitSpewer.h
js/src/moz.build
--- a/js/src/jit/BacktrackingAllocator.h
+++ b/js/src/jit/BacktrackingAllocator.h
@@ -613,16 +613,17 @@ class VirtualRegister
 };
 
 // A sequence of code positions, for tellings BacktrackingAllocator::splitAt
 // where to split.
 typedef js::Vector<CodePosition, 4, SystemAllocPolicy> SplitPositionVector;
 
 class BacktrackingAllocator : protected RegisterAllocator
 {
+    friend class C1Spewer;
     friend class JSONSpewer;
 
     // This flag is set when testing new allocator modifications.
     bool testbed;
 
     BitSet* liveIn;
     FixedList<VirtualRegister> vregs;
 
new file mode 100644
--- /dev/null
+++ b/js/src/jit/C1Spewer.cpp
@@ -0,0 +1,209 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * 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/. */
+
+#ifdef JS_JITSPEW
+
+#include "jit/C1Spewer.h"
+
+
+#include <time.h>
+
+#include "jit/BacktrackingAllocator.h"
+#include "jit/LIR.h"
+#include "jit/MIRGraph.h"
+
+#include "vm/Printer.h"
+
+using namespace js;
+using namespace js::jit;
+
+void
+C1Spewer::beginFunction(MIRGraph* graph, JSScript* script)
+{
+    this->graph  = graph;
+
+    out_.printf("begin_compilation\n");
+    if (script) {
+        out_.printf("  name \"%s:%u\"\n", script->filename(), script->lineno());
+        out_.printf("  method \"%s:%u\"\n", script->filename(), script->lineno());
+    } else {
+        out_.printf("  name \"wasm compilation\"\n");
+        out_.printf("  method \"wasm compilation\"\n");
+    }
+    out_.printf("  date %d\n", (int)time(nullptr));
+    out_.printf("end_compilation\n");
+}
+
+void
+C1Spewer::spewPass(const char* pass)
+{
+    out_.printf("begin_cfg\n");
+    out_.printf("  name \"%s\"\n", pass);
+
+    for (MBasicBlockIterator block(graph->begin()); block != graph->end(); block++) {
+        spewPass(out_, *block);
+    }
+
+    out_.printf("end_cfg\n");
+}
+
+void
+C1Spewer::spewRanges(const char* pass, BacktrackingAllocator* regalloc)
+{
+    out_.printf("begin_ranges\n");
+    out_.printf(" name \"%s\"\n", pass);
+
+    for (MBasicBlockIterator block(graph->begin()); block != graph->end(); block++) {
+        spewRanges(out_, *block, regalloc);
+    }
+
+    out_.printf("end_ranges\n");
+}
+
+void
+C1Spewer::endFunction()
+{
+}
+
+static void
+DumpDefinition(GenericPrinter& out, MDefinition* def)
+{
+    out.printf("      ");
+    out.printf("%u %u ", def->id(), unsigned(def->useCount()));
+    def->printName(out);
+    out.printf(" ");
+    def->printOpcode(out);
+    out.printf(" <|@\n");
+}
+
+static void
+DumpLIR(GenericPrinter& out, LNode* ins)
+{
+    out.printf("      ");
+    out.printf("%d ", ins->id());
+    ins->dump(out);
+    out.printf(" <|@\n");
+}
+
+void
+C1Spewer::spewRanges(GenericPrinter& out, BacktrackingAllocator* regalloc, LNode* ins)
+{
+    for (size_t k = 0; k < ins->numDefs(); k++) {
+        const LDefinition* def = ins->isPhi()
+            ? ins->toPhi()->getDef(k)
+            : ins->toInstruction()->getDef(k);
+        uint32_t id = def->virtualRegister();
+        VirtualRegister* vreg = &regalloc->vregs[id];
+
+        for (LiveRange::RegisterLinkIterator iter = vreg->rangesBegin(); iter; iter++) {
+            LiveRange* range = LiveRange::get(*iter);
+            out.printf("%d object \"", id);
+            out.printf("%s", range->bundle()->allocation().toString().get());
+            out.printf("\" %d -1", id);
+            out.printf(" [%u, %u[", range->from().bits(), range->to().bits());
+            for (UsePositionIterator usePos(range->usesBegin()); usePos; usePos++) {
+                out.printf(" %u M", usePos->pos.bits());
+            }
+            out.printf(" \"\"\n");
+        }
+    }
+}
+
+void
+C1Spewer::spewRanges(GenericPrinter& out, MBasicBlock* block, BacktrackingAllocator* regalloc)
+{
+    LBlock* lir = block->lir();
+    if (!lir) {
+        return;
+    }
+
+    for (size_t i = 0; i < lir->numPhis(); i++) {
+        spewRanges(out, regalloc, lir->getPhi(i));
+    }
+
+    for (LInstructionIterator ins = lir->begin(); ins != lir->end(); ins++) {
+        spewRanges(out, regalloc, *ins);
+    }
+}
+
+void
+C1Spewer::spewPass(GenericPrinter& out, MBasicBlock* block)
+{
+    out.printf("  begin_block\n");
+    out.printf("    name \"B%d\"\n", block->id());
+    out.printf("    from_bci -1\n");
+    out.printf("    to_bci -1\n");
+
+    out.printf("    predecessors");
+    for (uint32_t i = 0; i < block->numPredecessors(); i++) {
+        MBasicBlock* pred = block->getPredecessor(i);
+        out.printf(" \"B%d\"", pred->id());
+    }
+    out.printf("\n");
+
+    out.printf("    successors");
+    if (block->hasLastIns()) {
+        for (uint32_t i = 0; i < block->numSuccessors(); i++) {
+            MBasicBlock* successor = block->getSuccessor(i);
+            out.printf(" \"B%d\"", successor->id());
+        }
+    }
+    out.printf("\n");
+
+    out.printf("    xhandlers\n");
+    out.printf("    flags\n");
+
+    if (block->lir() && block->lir()->begin() != block->lir()->end()) {
+        out.printf("    first_lir_id %d\n", block->lir()->firstId());
+        out.printf("    last_lir_id %d\n", block->lir()->lastId());
+    }
+
+    out.printf("    begin_states\n");
+
+    if (block->entryResumePoint()) {
+        out.printf("      begin_locals\n");
+        out.printf("        size %d\n", (int)block->numEntrySlots());
+        out.printf("        method \"None\"\n");
+        for (uint32_t i = 0; i < block->numEntrySlots(); i++) {
+            MDefinition* ins = block->getEntrySlot(i);
+            out.printf("        ");
+            out.printf("%d ", i);
+            if (ins->isUnused()) {
+                out.printf("unused");
+            } else {
+                ins->printName(out);
+            }
+            out.printf("\n");
+        }
+        out.printf("      end_locals\n");
+    }
+    out.printf("    end_states\n");
+
+    out.printf("    begin_HIR\n");
+    for (MPhiIterator phi(block->phisBegin()); phi != block->phisEnd(); phi++) {
+        DumpDefinition(out, *phi);
+    }
+    for (MInstructionIterator i(block->begin()); i != block->end(); i++) {
+        DumpDefinition(out, *i);
+    }
+    out.printf("    end_HIR\n");
+
+    if (block->lir()) {
+        out.printf("    begin_LIR\n");
+        for (size_t i = 0; i < block->lir()->numPhis(); i++) {
+            DumpLIR(out, block->lir()->getPhi(i));
+        }
+        for (LInstructionIterator i(block->lir()->begin()); i != block->lir()->end(); i++) {
+            DumpLIR(out, *i);
+        }
+        out.printf("    end_LIR\n");
+    }
+
+    out.printf("  end_block\n");
+}
+
+#endif /* JS_JITSPEW */
+
new file mode 100644
--- /dev/null
+++ b/js/src/jit/C1Spewer.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * 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/. */
+
+#ifndef jit_C1Spewer_h
+#define jit_C1Spewer_h
+
+#ifdef JS_JITSPEW
+
+#include "NamespaceImports.h"
+
+#include "js/RootingAPI.h"
+#include "vm/Printer.h"
+
+namespace js {
+namespace jit {
+
+class BacktrackingAllocator;
+class MBasicBlock;
+class MIRGraph;
+class LNode;
+
+class C1Spewer
+{
+    MIRGraph* graph;
+    GenericPrinter& out_;
+
+  public:
+    explicit C1Spewer(GenericPrinter& out)
+      : graph(nullptr), out_(out)
+    { }
+
+    void beginFunction(MIRGraph* graph, JSScript* script);
+    void spewPass(const char* pass);
+    void spewRanges(const char* pass, BacktrackingAllocator* regalloc);
+    void endFunction();
+
+  private:
+    void spewPass(GenericPrinter& out, MBasicBlock* block);
+    void spewRanges(GenericPrinter& out, BacktrackingAllocator* regalloc, LNode* ins);
+    void spewRanges(GenericPrinter& out, MBasicBlock* block, BacktrackingAllocator* regalloc);
+};
+
+} // namespace jit
+} // namespace js
+
+#endif /* JS_JITSPEW */
+
+#endif /* jit_C1Spewer_h */
--- a/js/src/jit/JitSpewer.cpp
+++ b/js/src/jit/JitSpewer.cpp
@@ -255,17 +255,19 @@ IonSpewer::~IonSpewer()
     }
 
     jsonOutput_.printf("\n]}\n");
     release();
 }
 
 GraphSpewer::GraphSpewer(TempAllocator *alloc)
   : graph_(nullptr),
+    c1Printer_(alloc->lifoAlloc()),
     jsonPrinter_(alloc->lifoAlloc()),
+    c1Spewer_(c1Printer_),
     jsonSpewer_(jsonPrinter_)
 {
 }
 
 void
 GraphSpewer::init(MIRGraph* graph, JSScript* function)
 {
     MOZ_ASSERT(!isSpewing());
@@ -286,28 +288,31 @@ GraphSpewer::init(MIRGraph* graph, JSScr
 
 void
 GraphSpewer::beginFunction(JSScript* function)
 {
     if (!isSpewing()) {
         return;
     }
 
+    c1Spewer_.beginFunction(graph_, function);
     jsonSpewer_.beginFunction(function);
 
     ionspewer.beginFunction();
 }
 
 void
 GraphSpewer::spewPass(const char* pass)
 {
     if (!isSpewing()) {
         return;
     }
 
+    c1Spewer_.spewPass(pass);
+
     jsonSpewer_.beginPass(pass);
     jsonSpewer_.spewMIR(graph_);
     jsonSpewer_.spewLIR(graph_);
     jsonSpewer_.endPass();
 
     ionspewer.spewPass(this);
 
     // As this function is used for debugging, we ignore any of the previous
@@ -321,16 +326,19 @@ GraphSpewer::spewPass(const char* pass)
 
 void
 GraphSpewer::spewPass(const char* pass, BacktrackingAllocator* ra)
 {
     if (!isSpewing()) {
         return;
     }
 
+    c1Spewer_.spewPass(pass);
+    c1Spewer_.spewRanges(pass, ra);
+
     jsonSpewer_.beginPass(pass);
     jsonSpewer_.spewMIR(graph_);
     jsonSpewer_.spewLIR(graph_);
     jsonSpewer_.spewRanges(ra);
     jsonSpewer_.endPass();
 
     ionspewer.spewPass(this);
 }
@@ -343,25 +351,32 @@ GraphSpewer::endFunction()
     }
 
     if (!isSpewing()) {
         MOZ_ASSERT(filteredOutCompilations != 0);
         filteredOutCompilations--;
         return;
     }
 
+    c1Spewer_.endFunction();
     jsonSpewer_.endFunction();
 
     ionspewer.endFunction(this);
     graph_ = nullptr;
 }
 
 void
 GraphSpewer::dump(Fprinter& c1Out, Fprinter& jsonOut)
 {
+    if (!c1Printer_.hadOutOfMemory()) {
+        c1Printer_.exportInto(c1Out);
+        c1Out.flush();
+    }
+    c1Printer_.clear();
+
     if (!jsonPrinter_.hadOutOfMemory()) {
         jsonPrinter_.exportInto(jsonOut);
     } else {
         jsonOut.put("{}");
     }
     jsonOut.flush();
     jsonPrinter_.clear();
 }
--- a/js/src/jit/JitSpewer.h
+++ b/js/src/jit/JitSpewer.h
@@ -7,16 +7,17 @@
 #ifndef jit_JitSpewer_h
 #define jit_JitSpewer_h
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/IntegerPrintfMacros.h"
 
 #include <stdarg.h>
 
+#include "jit/C1Spewer.h"
 #include "jit/JSONSpewer.h"
 
 #include "js/RootingAPI.h"
 
 #include "vm/Printer.h"
 
 namespace js {
 namespace jit {
@@ -119,24 +120,28 @@ enum JitSpewChannel {
 class BacktrackingAllocator;
 class MDefinition;
 class MIRGenerator;
 class MIRGraph;
 class TempAllocator;
 
 // The JitSpewer is only available on debug builds.
 // None of the global functions have effect on non-debug builds.
+static const int NULL_ID = -1;
+
 #ifdef JS_JITSPEW
 
 // Class made to hold the MIR and LIR graphs of an Wasm / Ion compilation.
 class GraphSpewer
 {
   private:
     MIRGraph* graph_;
+    LSprinter c1Printer_;
     LSprinter jsonPrinter_;
+    C1Spewer c1Spewer_;
     JSONSpewer jsonSpewer_;
 
   public:
     explicit GraphSpewer(TempAllocator *alloc);
 
     bool isSpewing() const {
         return graph_;
     }
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -281,16 +281,17 @@ UNIFIED_SOURCES += [
     'jit/BaselineDebugModeOSR.cpp',
     'jit/BaselineFrame.cpp',
     'jit/BaselineFrameInfo.cpp',
     'jit/BaselineIC.cpp',
     'jit/BaselineInspector.cpp',
     'jit/BaselineJIT.cpp',
     'jit/BitSet.cpp',
     'jit/BytecodeAnalysis.cpp',
+    'jit/C1Spewer.cpp',
     'jit/CacheIR.cpp',
     'jit/CacheIRCompiler.cpp',
     'jit/CacheIRSpewer.cpp',
     'jit/CodeGenerator.cpp',
     'jit/CompileWrappers.cpp',
     'jit/EdgeCaseAnalysis.cpp',
     'jit/EffectiveAddressAnalysis.cpp',
     'jit/ExecutableAllocator.cpp',