mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1147403 part 3 - Make IonSpewer work during off-thread compilation. r=h4writer
This commit is contained in:
parent
a9838faded
commit
c3ac0db387
@ -7692,6 +7692,8 @@ CheckFunction(ModuleCompiler& m, LifoAlloc& lifo, MIRGenerator** mir, ModuleComp
|
||||
|
||||
*mir = f.extractMIR();
|
||||
(*mir)->initMinAsmJSHeapLength(m.minHeapLength());
|
||||
jit::SpewBeginFunction(*mir, nullptr);
|
||||
|
||||
*funcOut = func;
|
||||
return true;
|
||||
}
|
||||
@ -7768,8 +7770,7 @@ CheckFunctionsSequential(ModuleCompiler& m)
|
||||
int64_t before = PRMJ_Now();
|
||||
|
||||
JitContext jcx(m.cx(), &mir->alloc());
|
||||
|
||||
IonSpewNewFunction(&mir->graph(), nullptr);
|
||||
jit::AutoSpewEndFunction spewEndFunction(mir);
|
||||
|
||||
if (!OptimizeMIR(mir))
|
||||
return m.failOffset(func->srcBegin(), "internal compiler failure (probably out of memory)");
|
||||
@ -7782,8 +7783,6 @@ CheckFunctionsSequential(ModuleCompiler& m)
|
||||
|
||||
if (!GenerateCode(m, *func, *mir, *lir))
|
||||
return false;
|
||||
|
||||
IonSpewEndFunction();
|
||||
}
|
||||
|
||||
if (!CheckAllFunctionsDefined(m))
|
||||
@ -8022,7 +8021,7 @@ CheckFunctions(ModuleCompiler& m)
|
||||
if (!ParallelCompilationEnabled(m.cx()) || !g.claim())
|
||||
return CheckFunctionsSequential(m);
|
||||
|
||||
JitSpew(JitSpew_IonLogs, "Can't log asm.js script. (Compiled on background thread.)");
|
||||
JitSpew(JitSpew_IonSyncLogs, "Can't log asm.js script. (Compiled on background thread.)");
|
||||
|
||||
// Saturate all helper threads.
|
||||
size_t numParallelJobs = HelperThreadState().maxAsmJSCompilationThreads();
|
||||
|
@ -21,18 +21,9 @@
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
bool
|
||||
C1Spewer::init(const char* path)
|
||||
{
|
||||
return out_.init(path);
|
||||
}
|
||||
|
||||
void
|
||||
C1Spewer::beginFunction(MIRGraph* graph, HandleScript script)
|
||||
C1Spewer::beginFunction(MIRGraph* graph, JSScript* script)
|
||||
{
|
||||
if (!out_.isInitialized())
|
||||
return;
|
||||
|
||||
this->graph = graph;
|
||||
|
||||
out_.printf("begin_compilation\n");
|
||||
@ -50,9 +41,6 @@ C1Spewer::beginFunction(MIRGraph* graph, HandleScript script)
|
||||
void
|
||||
C1Spewer::spewPass(const char* pass)
|
||||
{
|
||||
if (!out_.isInitialized())
|
||||
return;
|
||||
|
||||
out_.printf("begin_cfg\n");
|
||||
out_.printf(" name \"%s\"\n", pass);
|
||||
|
||||
@ -60,15 +48,11 @@ C1Spewer::spewPass(const char* pass)
|
||||
spewPass(out_, *block);
|
||||
|
||||
out_.printf("end_cfg\n");
|
||||
out_.flush();
|
||||
}
|
||||
|
||||
void
|
||||
C1Spewer::spewRanges(const char* pass, BacktrackingAllocator* regalloc)
|
||||
{
|
||||
if (!out_.isInitialized())
|
||||
return;
|
||||
|
||||
out_.printf("begin_ranges\n");
|
||||
out_.printf(" name \"%s\"\n", pass);
|
||||
|
||||
@ -76,7 +60,6 @@ C1Spewer::spewRanges(const char* pass, BacktrackingAllocator* regalloc)
|
||||
spewRanges(out_, *block, regalloc);
|
||||
|
||||
out_.printf("end_ranges\n");
|
||||
out_.flush();
|
||||
}
|
||||
|
||||
void
|
||||
@ -85,10 +68,11 @@ C1Spewer::endFunction()
|
||||
}
|
||||
|
||||
void
|
||||
C1Spewer::finish()
|
||||
C1Spewer::dump(Fprinter& file)
|
||||
{
|
||||
if (out_.isInitialized())
|
||||
out_.finish();
|
||||
if (!out_.hadOutOfMemory())
|
||||
out_.exportInto(file);
|
||||
out_.clear();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "NamespaceImports.h"
|
||||
|
||||
#include "jit/JitAllocPolicy.h"
|
||||
#include "js/RootingAPI.h"
|
||||
#include "vm/Printer.h"
|
||||
|
||||
@ -25,19 +26,19 @@ class LNode;
|
||||
class C1Spewer
|
||||
{
|
||||
MIRGraph* graph;
|
||||
Fprinter out_;
|
||||
LSprinter out_;
|
||||
|
||||
public:
|
||||
C1Spewer()
|
||||
: graph(nullptr), out_()
|
||||
explicit C1Spewer(TempAllocator *alloc)
|
||||
: graph(nullptr), out_(alloc->lifoAlloc())
|
||||
{ }
|
||||
|
||||
bool init(const char* path);
|
||||
void beginFunction(MIRGraph* graph, HandleScript script);
|
||||
void beginFunction(MIRGraph* graph, JSScript* script);
|
||||
void spewPass(const char* pass);
|
||||
void spewRanges(const char* pass, BacktrackingAllocator* regalloc);
|
||||
void endFunction();
|
||||
void finish();
|
||||
|
||||
void dump(Fprinter &file);
|
||||
|
||||
private:
|
||||
void spewPass(GenericPrinter& out, MBasicBlock* block);
|
||||
|
@ -1169,6 +1169,7 @@ bool
|
||||
OptimizeMIR(MIRGenerator* mir)
|
||||
{
|
||||
MIRGraph& graph = mir->graph();
|
||||
GraphSpewer& gs = mir->graphSpewer();
|
||||
TraceLoggerThread* logger;
|
||||
if (GetJitContext()->runtime->onMainThread())
|
||||
logger = TraceLoggerForMainThread(GetJitContext()->runtime);
|
||||
@ -1180,7 +1181,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
return false;
|
||||
}
|
||||
|
||||
IonSpewPass("BuildSSA");
|
||||
gs.spewPass("BuildSSA");
|
||||
AssertBasicGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("Start"))
|
||||
@ -1189,7 +1190,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
if (!mir->compilingAsmJS()) {
|
||||
AutoTraceLog log(logger, TraceLogger_FoldTests);
|
||||
FoldTests(graph);
|
||||
IonSpewPass("Fold Tests");
|
||||
gs.spewPass("Fold Tests");
|
||||
AssertBasicGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("Fold Tests"))
|
||||
@ -1200,7 +1201,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
AutoTraceLog log(logger, TraceLogger_SplitCriticalEdges);
|
||||
if (!SplitCriticalEdges(graph))
|
||||
return false;
|
||||
IonSpewPass("Split Critical Edges");
|
||||
gs.spewPass("Split Critical Edges");
|
||||
AssertGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("Split Critical Edges"))
|
||||
@ -1211,7 +1212,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
AutoTraceLog log(logger, TraceLogger_RenumberBlocks);
|
||||
if (!RenumberBlocks(graph))
|
||||
return false;
|
||||
IonSpewPass("Renumber Blocks");
|
||||
gs.spewPass("Renumber Blocks");
|
||||
AssertGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("Renumber Blocks"))
|
||||
@ -1239,7 +1240,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
: AggressiveObservability;
|
||||
if (!EliminatePhis(mir, graph, observability))
|
||||
return false;
|
||||
IonSpewPass("Eliminate phis");
|
||||
gs.spewPass("Eliminate phis");
|
||||
AssertGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("Eliminate phis"))
|
||||
@ -1258,7 +1259,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
AutoTraceLog log(logger, TraceLogger_ScalarReplacement);
|
||||
if (!ScalarReplacement(mir, graph))
|
||||
return false;
|
||||
IonSpewPass("Scalar Replacement");
|
||||
gs.spewPass("Scalar Replacement");
|
||||
AssertGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("Scalar Replacement"))
|
||||
@ -1269,7 +1270,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
AutoTraceLog log(logger, TraceLogger_ApplyTypes);
|
||||
if (!ApplyTypeInformation(mir, graph))
|
||||
return false;
|
||||
IonSpewPass("Apply types");
|
||||
gs.spewPass("Apply types");
|
||||
AssertExtendedGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("Apply types"))
|
||||
@ -1280,7 +1281,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
AutoTraceLog log(logger, TraceLogger_EagerSimdUnbox);
|
||||
if (!EagerSimdUnbox(mir, graph))
|
||||
return false;
|
||||
IonSpewPass("Eager Simd Unbox");
|
||||
gs.spewPass("Eager Simd Unbox");
|
||||
AssertGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("Eager Simd Unbox"))
|
||||
@ -1292,7 +1293,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
AlignmentMaskAnalysis ama(graph);
|
||||
if (!ama.analyze())
|
||||
return false;
|
||||
IonSpewPass("Alignment Mask Analysis");
|
||||
gs.spewPass("Alignment Mask Analysis");
|
||||
AssertExtendedGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("Alignment Mask Analysis"))
|
||||
@ -1312,7 +1313,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
AliasAnalysis analysis(mir, graph);
|
||||
if (!analysis.analyze())
|
||||
return false;
|
||||
IonSpewPass("Alias analysis");
|
||||
gs.spewPass("Alias analysis");
|
||||
AssertExtendedGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("Alias analysis"))
|
||||
@ -1334,7 +1335,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
AutoTraceLog log(logger, TraceLogger_GVN);
|
||||
if (!gvn.run(ValueNumberer::UpdateAliasAnalysis))
|
||||
return false;
|
||||
IonSpewPass("GVN");
|
||||
gs.spewPass("GVN");
|
||||
AssertExtendedGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("GVN"))
|
||||
@ -1350,7 +1351,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
if (!script || !script->hadFrequentBailouts()) {
|
||||
if (!LICM(mir, graph))
|
||||
return false;
|
||||
IonSpewPass("LICM");
|
||||
gs.spewPass("LICM");
|
||||
AssertExtendedGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("LICM"))
|
||||
@ -1363,7 +1364,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
RangeAnalysis r(mir, graph);
|
||||
if (!r.addBetaNodes())
|
||||
return false;
|
||||
IonSpewPass("Beta");
|
||||
gs.spewPass("Beta");
|
||||
AssertExtendedGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("RA Beta"))
|
||||
@ -1371,7 +1372,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
|
||||
if (!r.analyze() || !r.addRangeAssertions())
|
||||
return false;
|
||||
IonSpewPass("Range Analysis");
|
||||
gs.spewPass("Range Analysis");
|
||||
AssertExtendedGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("Range Analysis"))
|
||||
@ -1379,7 +1380,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
|
||||
if (!r.removeBetaNodes())
|
||||
return false;
|
||||
IonSpewPass("De-Beta");
|
||||
gs.spewPass("De-Beta");
|
||||
AssertExtendedGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("RA De-Beta"))
|
||||
@ -1389,7 +1390,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
bool shouldRunUCE = false;
|
||||
if (!r.prepareForUCE(&shouldRunUCE))
|
||||
return false;
|
||||
IonSpewPass("RA check UCE");
|
||||
gs.spewPass("RA check UCE");
|
||||
AssertExtendedGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("RA check UCE"))
|
||||
@ -1398,7 +1399,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
if (shouldRunUCE) {
|
||||
if (!gvn.run(ValueNumberer::DontUpdateAliasAnalysis))
|
||||
return false;
|
||||
IonSpewPass("UCE After RA");
|
||||
gs.spewPass("UCE After RA");
|
||||
AssertExtendedGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("UCE After RA"))
|
||||
@ -1409,7 +1410,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
if (mir->optimizationInfo().autoTruncateEnabled()) {
|
||||
if (!r.truncate())
|
||||
return false;
|
||||
IonSpewPass("Truncate Doubles");
|
||||
gs.spewPass("Truncate Doubles");
|
||||
AssertExtendedGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("Truncate Doubles"))
|
||||
@ -1422,7 +1423,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
if (!UnrollLoops(graph, r.loopIterationBounds))
|
||||
return false;
|
||||
|
||||
IonSpewPass("Unroll Loops");
|
||||
gs.spewPass("Unroll Loops");
|
||||
AssertExtendedGraphCoherency(graph);
|
||||
}
|
||||
}
|
||||
@ -1432,7 +1433,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
EffectiveAddressAnalysis eaa(mir, graph);
|
||||
if (!eaa.analyze())
|
||||
return false;
|
||||
IonSpewPass("Effective Address Analysis");
|
||||
gs.spewPass("Effective Address Analysis");
|
||||
AssertExtendedGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("Effective Address Analysis"))
|
||||
@ -1443,7 +1444,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
AutoTraceLog log(logger, TraceLogger_EliminateDeadCode);
|
||||
if (!EliminateDeadCode(mir, graph))
|
||||
return false;
|
||||
IonSpewPass("DCE");
|
||||
gs.spewPass("DCE");
|
||||
AssertExtendedGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("DCE"))
|
||||
@ -1454,7 +1455,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
AutoTraceLog log(logger, TraceLogger_EliminateDeadCode);
|
||||
if (!Sink(mir, graph))
|
||||
return false;
|
||||
IonSpewPass("Sink");
|
||||
gs.spewPass("Sink");
|
||||
AssertExtendedGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("Sink"))
|
||||
@ -1467,7 +1468,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
AutoTraceLog log(logger, TraceLogger_MakeLoopsContiguous);
|
||||
if (!MakeLoopsContiguous(graph))
|
||||
return false;
|
||||
IonSpewPass("Make loops contiguous");
|
||||
gs.spewPass("Make loops contiguous");
|
||||
AssertExtendedGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("Make loops contiguous"))
|
||||
@ -1482,7 +1483,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
EdgeCaseAnalysis edgeCaseAnalysis(mir, graph);
|
||||
if (!edgeCaseAnalysis.analyzeLate())
|
||||
return false;
|
||||
IonSpewPass("Edge Case Analysis (Late)");
|
||||
gs.spewPass("Edge Case Analysis (Late)");
|
||||
AssertGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("Edge Case Analysis (Late)"))
|
||||
@ -1497,7 +1498,7 @@ OptimizeMIR(MIRGenerator* mir)
|
||||
// before its bounds check.
|
||||
if (!EliminateRedundantChecks(graph))
|
||||
return false;
|
||||
IonSpewPass("Bounds Check Elimination");
|
||||
gs.spewPass("Bounds Check Elimination");
|
||||
AssertGraphCoherency(graph);
|
||||
}
|
||||
|
||||
@ -1515,6 +1516,7 @@ LIRGraph*
|
||||
GenerateLIR(MIRGenerator* mir)
|
||||
{
|
||||
MIRGraph& graph = mir->graph();
|
||||
GraphSpewer& gs = mir->graphSpewer();
|
||||
|
||||
TraceLoggerThread* logger;
|
||||
if (GetJitContext()->runtime->onMainThread())
|
||||
@ -1531,7 +1533,7 @@ GenerateLIR(MIRGenerator* mir)
|
||||
AutoTraceLog log(logger, TraceLogger_GenerateLIR);
|
||||
if (!lirgen.generate())
|
||||
return nullptr;
|
||||
IonSpewPass("Generate LIR");
|
||||
gs.spewPass("Generate LIR");
|
||||
|
||||
if (mir->shouldCancel("Generate LIR"))
|
||||
return nullptr;
|
||||
@ -1558,7 +1560,7 @@ GenerateLIR(MIRGenerator* mir)
|
||||
return nullptr;
|
||||
#endif
|
||||
|
||||
IonSpewPass("Allocate Registers [Backtracking]");
|
||||
gs.spewPass("Allocate Registers [Backtracking]");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1573,7 +1575,7 @@ GenerateLIR(MIRGenerator* mir)
|
||||
return nullptr;
|
||||
if (!integrity.check(true))
|
||||
return nullptr;
|
||||
IonSpewPass("Allocate Registers [Stupid]");
|
||||
gs.spewPass("Allocate Registers [Stupid]");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1615,6 +1617,7 @@ CompileBackEnd(MIRGenerator* mir)
|
||||
{
|
||||
// Everything in CompileBackEnd can potentially run on a helper thread.
|
||||
AutoEnterIonCompilation enter;
|
||||
AutoSpewEndFunction spewEndFunction(mir);
|
||||
|
||||
if (!OptimizeMIR(mir))
|
||||
return nullptr;
|
||||
@ -1918,15 +1921,14 @@ IonCompile(JSContext* cx, JSScript* script,
|
||||
if (recompile)
|
||||
builderScript->ionScript()->setRecompiling();
|
||||
|
||||
#ifdef DEBUG
|
||||
IonSpewFunction ionSpewFunction(graph, builderScript);
|
||||
#endif
|
||||
SpewBeginFunction(builder, builderScript);
|
||||
|
||||
bool succeeded = builder->build();
|
||||
builder->clearForBackEnd();
|
||||
|
||||
if (!succeeded) {
|
||||
AbortReason reason = builder->abortReason();
|
||||
builder->graphSpewer().endFunction();
|
||||
if (reason == AbortReason_PreliminaryObjects) {
|
||||
// Some group was accessed which has associated preliminary objects
|
||||
// to analyze. Do this now and we will try to build again shortly.
|
||||
@ -1960,7 +1962,8 @@ IonCompile(JSContext* cx, JSScript* script,
|
||||
if (!recompile)
|
||||
builderScript->setIonScript(cx, ION_COMPILING_SCRIPT);
|
||||
|
||||
JitSpew(JitSpew_IonLogs, "Can't log script %s:%" PRIuSIZE ". (Compiled on background thread.)",
|
||||
JitSpew(JitSpew_IonSyncLogs, "Can't log script %s:%" PRIuSIZE
|
||||
". (Compiled on background thread.)",
|
||||
builderScript->filename(), builderScript->lineno());
|
||||
|
||||
JSRuntime* rt = cx->runtime();
|
||||
@ -1974,6 +1977,7 @@ IonCompile(JSContext* cx, JSScript* script,
|
||||
|
||||
if (!StartOffThreadIonCompile(cx, builder)) {
|
||||
JitSpew(JitSpew_IonAbort, "Unable to start off-thread ion compilation.");
|
||||
builder->graphSpewer().endFunction();
|
||||
return AbortReason_Alloc;
|
||||
}
|
||||
|
||||
|
@ -17,17 +17,9 @@
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
JSONSpewer::~JSONSpewer()
|
||||
{
|
||||
if (out_.isInitialized())
|
||||
out_.finish();
|
||||
}
|
||||
|
||||
void
|
||||
JSONSpewer::indent()
|
||||
{
|
||||
if (!out_.isInitialized())
|
||||
return;
|
||||
MOZ_ASSERT(indentLevel_ >= 0);
|
||||
out_.printf("\n");
|
||||
for (int i = 0; i < indentLevel_; i++)
|
||||
@ -37,9 +29,6 @@ JSONSpewer::indent()
|
||||
void
|
||||
JSONSpewer::property(const char* name)
|
||||
{
|
||||
if (!out_.isInitialized())
|
||||
return;
|
||||
|
||||
if (!first_)
|
||||
out_.printf(",");
|
||||
indent();
|
||||
@ -50,9 +39,6 @@ JSONSpewer::property(const char* name)
|
||||
void
|
||||
JSONSpewer::beginObject()
|
||||
{
|
||||
if (!out_.isInitialized())
|
||||
return;
|
||||
|
||||
if (!first_) {
|
||||
out_.printf(",");
|
||||
indent();
|
||||
@ -65,9 +51,6 @@ JSONSpewer::beginObject()
|
||||
void
|
||||
JSONSpewer::beginObjectProperty(const char* name)
|
||||
{
|
||||
if (!out_.isInitialized())
|
||||
return;
|
||||
|
||||
property(name);
|
||||
out_.printf("{");
|
||||
indentLevel_++;
|
||||
@ -77,9 +60,6 @@ JSONSpewer::beginObjectProperty(const char* name)
|
||||
void
|
||||
JSONSpewer::beginListProperty(const char* name)
|
||||
{
|
||||
if (!out_.isInitialized())
|
||||
return;
|
||||
|
||||
property(name);
|
||||
out_.printf("[");
|
||||
first_ = true;
|
||||
@ -88,9 +68,6 @@ JSONSpewer::beginListProperty(const char* name)
|
||||
void
|
||||
JSONSpewer::stringProperty(const char* name, const char* format, ...)
|
||||
{
|
||||
if (!out_.isInitialized())
|
||||
return;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
|
||||
@ -105,9 +82,6 @@ JSONSpewer::stringProperty(const char* name, const char* format, ...)
|
||||
void
|
||||
JSONSpewer::stringValue(const char* format, ...)
|
||||
{
|
||||
if (!out_.isInitialized())
|
||||
return;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
|
||||
@ -124,9 +98,6 @@ JSONSpewer::stringValue(const char* format, ...)
|
||||
void
|
||||
JSONSpewer::integerProperty(const char* name, int value)
|
||||
{
|
||||
if (!out_.isInitialized())
|
||||
return;
|
||||
|
||||
property(name);
|
||||
out_.printf("%d", value);
|
||||
}
|
||||
@ -134,9 +105,6 @@ JSONSpewer::integerProperty(const char* name, int value)
|
||||
void
|
||||
JSONSpewer::integerValue(int value)
|
||||
{
|
||||
if (!out_.isInitialized())
|
||||
return;
|
||||
|
||||
if (!first_)
|
||||
out_.printf(",");
|
||||
out_.printf("%d", value);
|
||||
@ -146,9 +114,6 @@ JSONSpewer::integerValue(int value)
|
||||
void
|
||||
JSONSpewer::endObject()
|
||||
{
|
||||
if (!out_.isInitialized())
|
||||
return;
|
||||
|
||||
indentLevel_--;
|
||||
indent();
|
||||
out_.printf("}");
|
||||
@ -158,38 +123,19 @@ JSONSpewer::endObject()
|
||||
void
|
||||
JSONSpewer::endList()
|
||||
{
|
||||
if (!out_.isInitialized())
|
||||
return;
|
||||
|
||||
out_.printf("]");
|
||||
first_ = false;
|
||||
}
|
||||
|
||||
bool
|
||||
JSONSpewer::init(const char* path)
|
||||
{
|
||||
if (out_.init(path))
|
||||
return false;
|
||||
|
||||
beginObject();
|
||||
beginListProperty("functions");
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
JSONSpewer::beginFunction(JSScript* script)
|
||||
{
|
||||
if (inFunction_)
|
||||
endFunction();
|
||||
|
||||
beginObject();
|
||||
if (script)
|
||||
stringProperty("name", "%s:%d", script->filename(), script->lineno());
|
||||
else
|
||||
stringProperty("name", "asm.js compilation");
|
||||
beginListProperty("passes");
|
||||
|
||||
inFunction_ = true;
|
||||
}
|
||||
|
||||
void
|
||||
@ -294,9 +240,6 @@ JSONSpewer::spewMDef(MDefinition* def)
|
||||
void
|
||||
JSONSpewer::spewMIR(MIRGraph* mir)
|
||||
{
|
||||
if (!out_.isInitialized())
|
||||
return;
|
||||
|
||||
beginObjectProperty("mir");
|
||||
beginListProperty("blocks");
|
||||
|
||||
@ -343,9 +286,6 @@ JSONSpewer::spewMIR(MIRGraph* mir)
|
||||
void
|
||||
JSONSpewer::spewLIns(LNode* ins)
|
||||
{
|
||||
if (!out_.isInitialized())
|
||||
return;
|
||||
|
||||
beginObject();
|
||||
|
||||
integerProperty("id", ins->id());
|
||||
@ -366,9 +306,6 @@ JSONSpewer::spewLIns(LNode* ins)
|
||||
void
|
||||
JSONSpewer::spewLIR(MIRGraph* mir)
|
||||
{
|
||||
if (!out_.isInitialized())
|
||||
return;
|
||||
|
||||
beginObjectProperty("lir");
|
||||
beginListProperty("blocks");
|
||||
|
||||
@ -397,9 +334,6 @@ JSONSpewer::spewLIR(MIRGraph* mir)
|
||||
void
|
||||
JSONSpewer::spewRanges(BacktrackingAllocator* regalloc)
|
||||
{
|
||||
if (!out_.isInitialized())
|
||||
return;
|
||||
|
||||
beginObjectProperty("ranges");
|
||||
beginListProperty("blocks");
|
||||
|
||||
@ -446,32 +380,21 @@ void
|
||||
JSONSpewer::endPass()
|
||||
{
|
||||
endObject();
|
||||
out_.flush();
|
||||
}
|
||||
|
||||
void
|
||||
JSONSpewer::endFunction()
|
||||
{
|
||||
MOZ_ASSERT(inFunction_);
|
||||
endList();
|
||||
endObject();
|
||||
out_.flush();
|
||||
inFunction_ = false;
|
||||
}
|
||||
|
||||
void
|
||||
JSONSpewer::finish()
|
||||
JSONSpewer::dump(Fprinter& file)
|
||||
{
|
||||
if (!out_.isInitialized())
|
||||
return;
|
||||
|
||||
if (inFunction_)
|
||||
endFunction();
|
||||
|
||||
endList();
|
||||
endObject();
|
||||
out_.printf("\n");
|
||||
|
||||
out_.finish();
|
||||
if (!out_.hadOutOfMemory())
|
||||
out_.exportInto(file);
|
||||
else
|
||||
file.put("{}");
|
||||
out_.clear();
|
||||
}
|
||||
|
||||
|
@ -9,8 +9,8 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "jit/JitAllocPolicy.h"
|
||||
#include "js/TypeDecls.h"
|
||||
|
||||
#include "vm/Printer.h"
|
||||
|
||||
namespace js {
|
||||
@ -25,13 +25,9 @@ class LNode;
|
||||
class JSONSpewer
|
||||
{
|
||||
private:
|
||||
// Set by beginFunction(); unset by endFunction().
|
||||
// Used to correctly format output in case of abort during compilation.
|
||||
bool inFunction_;
|
||||
|
||||
int indentLevel_;
|
||||
bool first_;
|
||||
Fprinter out_;
|
||||
LSprinter out_;
|
||||
|
||||
void indent();
|
||||
|
||||
@ -47,15 +43,12 @@ class JSONSpewer
|
||||
void endList();
|
||||
|
||||
public:
|
||||
JSONSpewer()
|
||||
: inFunction_(false),
|
||||
indentLevel_(0),
|
||||
explicit JSONSpewer(TempAllocator *alloc)
|
||||
: indentLevel_(0),
|
||||
first_(true),
|
||||
out_()
|
||||
out_(alloc->lifoAlloc())
|
||||
{ }
|
||||
~JSONSpewer();
|
||||
|
||||
bool init(const char* path);
|
||||
void beginFunction(JSScript* script);
|
||||
void beginPass(const char * pass);
|
||||
void spewMDef(MDefinition* def);
|
||||
@ -66,7 +59,8 @@ class JSONSpewer
|
||||
void spewRanges(BacktrackingAllocator* regalloc);
|
||||
void endPass();
|
||||
void endFunction();
|
||||
void finish();
|
||||
|
||||
void dump(Fprinter& file);
|
||||
};
|
||||
|
||||
} // namespace jit
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
#include "jit/JitSpewer.h"
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
|
||||
#include "jit/Ion.h"
|
||||
#include "jit/MIR.h"
|
||||
|
||||
@ -26,12 +28,67 @@
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
class IonSpewer
|
||||
{
|
||||
private:
|
||||
PRLock* outputLock_;
|
||||
Fprinter c1Output_;
|
||||
Fprinter jsonOutput_;
|
||||
bool firstFunction_;
|
||||
bool asyncLogging_;
|
||||
bool inited_;
|
||||
|
||||
void release();
|
||||
|
||||
public:
|
||||
IonSpewer()
|
||||
: firstFunction_(false),
|
||||
asyncLogging_(false),
|
||||
inited_(false)
|
||||
{ }
|
||||
|
||||
// File output is terminated safely upon destruction.
|
||||
~IonSpewer();
|
||||
|
||||
bool init();
|
||||
bool isEnabled() {
|
||||
return inited_;
|
||||
}
|
||||
void setAsyncLogging(bool incremental) {
|
||||
asyncLogging_ = incremental;
|
||||
}
|
||||
bool getAsyncLogging() {
|
||||
return asyncLogging_;
|
||||
}
|
||||
|
||||
void beginFunction();
|
||||
void spewPass(GraphSpewer* gs);
|
||||
void endFunction(GraphSpewer* gs);
|
||||
|
||||
// Lock used to sequentialized asynchronous compilation output.
|
||||
void lockOutput() {
|
||||
PR_Lock(outputLock_);
|
||||
}
|
||||
void unlockOutput() {
|
||||
PR_Unlock(outputLock_);
|
||||
}
|
||||
};
|
||||
|
||||
class AutoLockIonSpewerOutput
|
||||
{
|
||||
private:
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
public:
|
||||
explicit AutoLockIonSpewerOutput(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
|
||||
~AutoLockIonSpewerOutput();
|
||||
};
|
||||
|
||||
// IonSpewer singleton.
|
||||
static IonSpewer ionspewer;
|
||||
|
||||
static bool LoggingChecked = false;
|
||||
static uint32_t LoggingBits = 0;
|
||||
static uint32_t filteredOutCompilations = 0;
|
||||
static mozilla::Atomic<uint32_t, mozilla::Relaxed> filteredOutCompilations(0);
|
||||
|
||||
static const char * const ChannelNames[] =
|
||||
{
|
||||
@ -41,7 +98,7 @@ static const char * const ChannelNames[] =
|
||||
};
|
||||
|
||||
static bool
|
||||
FilterContainsLocation(HandleScript function)
|
||||
FilterContainsLocation(JSScript* function)
|
||||
{
|
||||
static const char* filter = getenv("IONFILTER");
|
||||
|
||||
@ -73,48 +130,31 @@ FilterContainsLocation(HandleScript function)
|
||||
}
|
||||
|
||||
void
|
||||
jit::EnableIonDebugLogging()
|
||||
jit::EnableIonDebugSyncLogging()
|
||||
{
|
||||
EnableChannel(JitSpew_IonLogs);
|
||||
ionspewer.init();
|
||||
ionspewer.setAsyncLogging(false);
|
||||
EnableChannel(JitSpew_IonSyncLogs);
|
||||
}
|
||||
|
||||
void
|
||||
jit::IonSpewNewFunction(MIRGraph* graph, HandleScript func)
|
||||
jit::EnableIonDebugAsyncLogging()
|
||||
{
|
||||
if (GetJitContext()->runtime->onMainThread())
|
||||
ionspewer.beginFunction(graph, func);
|
||||
ionspewer.init();
|
||||
ionspewer.setAsyncLogging(true);
|
||||
}
|
||||
|
||||
void
|
||||
jit::IonSpewPass(const char* pass)
|
||||
IonSpewer::release()
|
||||
{
|
||||
if (GetJitContext()->runtime->onMainThread())
|
||||
ionspewer.spewPass(pass);
|
||||
}
|
||||
|
||||
void
|
||||
jit::IonSpewPass(const char* pass, BacktrackingAllocator* ra)
|
||||
{
|
||||
if (GetJitContext()->runtime->onMainThread())
|
||||
ionspewer.spewPass(pass, ra);
|
||||
}
|
||||
|
||||
void
|
||||
jit::IonSpewEndFunction()
|
||||
{
|
||||
if (GetJitContext()->runtime->onMainThread())
|
||||
ionspewer.endFunction();
|
||||
}
|
||||
|
||||
|
||||
IonSpewer::~IonSpewer()
|
||||
{
|
||||
if (!inited_)
|
||||
return;
|
||||
|
||||
c1Spewer.finish();
|
||||
jsonSpewer.finish();
|
||||
if (c1Output_.isInitialized())
|
||||
c1Output_.finish();
|
||||
if (jsonOutput_.isInitialized())
|
||||
jsonOutput_.finish();
|
||||
if (outputLock_)
|
||||
PR_DestroyLock(outputLock_);
|
||||
outputLock_ = nullptr;
|
||||
inited_ = false;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -123,85 +163,176 @@ IonSpewer::init()
|
||||
if (inited_)
|
||||
return true;
|
||||
|
||||
if (!c1Spewer.init(JIT_SPEW_DIR "ion.cfg"))
|
||||
return false;
|
||||
if (!jsonSpewer.init(JIT_SPEW_DIR "ion.json"))
|
||||
outputLock_ = PR_NewLock();
|
||||
if (!outputLock_ ||
|
||||
!c1Output_.init(JIT_SPEW_DIR "ion.cfg") ||
|
||||
!jsonOutput_.init(JIT_SPEW_DIR "ion.json"))
|
||||
{
|
||||
release();
|
||||
return false;
|
||||
}
|
||||
|
||||
jsonOutput_.printf("{\n \"functions\": [\n");
|
||||
firstFunction_ = true;
|
||||
|
||||
inited_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IonSpewer::isSpewingFunction() const
|
||||
AutoLockIonSpewerOutput::AutoLockIonSpewerOutput(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)
|
||||
{
|
||||
return inited_ && graph;
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
ionspewer.lockOutput();
|
||||
}
|
||||
|
||||
AutoLockIonSpewerOutput::~AutoLockIonSpewerOutput()
|
||||
{
|
||||
ionspewer.unlockOutput();
|
||||
}
|
||||
|
||||
void
|
||||
IonSpewer::beginFunction(MIRGraph* graph, HandleScript function)
|
||||
IonSpewer::beginFunction()
|
||||
{
|
||||
// If we are doing a synchronous logging then we spew everything as we go,
|
||||
// as this is useful in case of failure during the compilation. On the other
|
||||
// hand, it is recommended to disabled off main thread compilation.
|
||||
if (!getAsyncLogging() && !firstFunction_) {
|
||||
AutoLockIonSpewerOutput outputLock;
|
||||
jsonOutput_.put(","); // separate functions
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IonSpewer::spewPass(GraphSpewer* gs)
|
||||
{
|
||||
if (!getAsyncLogging()) {
|
||||
AutoLockIonSpewerOutput outputLock;
|
||||
gs->dump(c1Output_, jsonOutput_);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IonSpewer::endFunction(GraphSpewer* gs)
|
||||
{
|
||||
AutoLockIonSpewerOutput outputLock;
|
||||
if (getAsyncLogging() && !firstFunction_)
|
||||
jsonOutput_.put(","); // separate functions
|
||||
|
||||
gs->dump(c1Output_, jsonOutput_);
|
||||
firstFunction_ = false;
|
||||
}
|
||||
|
||||
IonSpewer::~IonSpewer()
|
||||
{
|
||||
if (!inited_)
|
||||
return;
|
||||
|
||||
jsonOutput_.printf("\n]}\n");
|
||||
release();
|
||||
}
|
||||
|
||||
void
|
||||
GraphSpewer::init(MIRGraph* graph, JSScript* function)
|
||||
{
|
||||
MOZ_ASSERT(!isSpewing());
|
||||
if (!ionspewer.isEnabled())
|
||||
return;
|
||||
|
||||
if (!FilterContainsLocation(function)) {
|
||||
MOZ_ASSERT(!this->graph);
|
||||
// filter out logs during the compilation.
|
||||
filteredOutCompilations++;
|
||||
MOZ_ASSERT(!isSpewing());
|
||||
return;
|
||||
}
|
||||
|
||||
this->graph = graph;
|
||||
|
||||
c1Spewer.beginFunction(graph, function);
|
||||
jsonSpewer.beginFunction(function);
|
||||
graph_ = graph;
|
||||
MOZ_ASSERT(isSpewing());
|
||||
}
|
||||
|
||||
void
|
||||
IonSpewer::spewPass(const char* pass)
|
||||
GraphSpewer::beginFunction(JSScript* function)
|
||||
{
|
||||
if (!isSpewingFunction())
|
||||
if (!isSpewing())
|
||||
return;
|
||||
|
||||
c1Spewer.spewPass(pass);
|
||||
jsonSpewer.beginPass(pass);
|
||||
jsonSpewer.spewMIR(graph);
|
||||
jsonSpewer.spewLIR(graph);
|
||||
jsonSpewer.endPass();
|
||||
c1Spewer_.beginFunction(graph_, function);
|
||||
jsonSpewer_.beginFunction(function);
|
||||
|
||||
ionspewer.beginFunction();
|
||||
}
|
||||
|
||||
void
|
||||
IonSpewer::spewPass(const char* pass, BacktrackingAllocator* ra)
|
||||
GraphSpewer::spewPass(const char* pass)
|
||||
{
|
||||
if (!isSpewingFunction())
|
||||
if (!isSpewing())
|
||||
return;
|
||||
|
||||
c1Spewer.spewPass(pass);
|
||||
c1Spewer.spewRanges(pass, ra);
|
||||
jsonSpewer.beginPass(pass);
|
||||
jsonSpewer.spewMIR(graph);
|
||||
jsonSpewer.spewLIR(graph);
|
||||
jsonSpewer.spewRanges(ra);
|
||||
jsonSpewer.endPass();
|
||||
c1Spewer_.spewPass(pass);
|
||||
|
||||
jsonSpewer_.beginPass(pass);
|
||||
jsonSpewer_.spewMIR(graph_);
|
||||
jsonSpewer_.spewLIR(graph_);
|
||||
jsonSpewer_.endPass();
|
||||
|
||||
ionspewer.spewPass(this);
|
||||
}
|
||||
|
||||
void
|
||||
IonSpewer::endFunction()
|
||||
GraphSpewer::spewPass(const char* pass, BacktrackingAllocator* ra)
|
||||
{
|
||||
if (!isSpewingFunction()) {
|
||||
if (inited_) {
|
||||
MOZ_ASSERT(filteredOutCompilations != 0);
|
||||
filteredOutCompilations--;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
GraphSpewer::endFunction()
|
||||
{
|
||||
if (!ionspewer.isEnabled())
|
||||
return;
|
||||
|
||||
if (!isSpewing()) {
|
||||
MOZ_ASSERT(filteredOutCompilations != 0);
|
||||
filteredOutCompilations--;
|
||||
return;
|
||||
}
|
||||
|
||||
c1Spewer.endFunction();
|
||||
jsonSpewer.endFunction();
|
||||
c1Spewer_.endFunction();
|
||||
jsonSpewer_.endFunction();
|
||||
|
||||
this->graph = nullptr;
|
||||
ionspewer.endFunction(this);
|
||||
graph_ = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
GraphSpewer::dump(Fprinter& c1Out, Fprinter& jsonOut)
|
||||
{
|
||||
c1Spewer_.dump(c1Out);
|
||||
jsonSpewer_.dump(jsonOut);
|
||||
}
|
||||
|
||||
void
|
||||
jit::SpewBeginFunction(MIRGenerator* mir, JSScript* function)
|
||||
{
|
||||
MIRGraph* graph = &mir->graph();
|
||||
mir->graphSpewer().init(graph, function);
|
||||
mir->graphSpewer().beginFunction(function);
|
||||
}
|
||||
|
||||
AutoSpewEndFunction::~AutoSpewEndFunction()
|
||||
{
|
||||
mir_->graphSpewer().endFunction();
|
||||
}
|
||||
|
||||
Fprinter&
|
||||
jit::JitSpewPrinter()
|
||||
@ -260,6 +391,7 @@ jit::CheckLogging()
|
||||
" range Range Analysis\n"
|
||||
" unroll Loop unrolling\n"
|
||||
" logs C1 and JSON visualization logging\n"
|
||||
" logs-sync Same as logs, but flushes between each pass (sync. compiled functions only).\n"
|
||||
" profiling Profiling-related information\n"
|
||||
" trackopts Optimization tracking information\n"
|
||||
" all Everything\n"
|
||||
@ -319,7 +451,9 @@ jit::CheckLogging()
|
||||
if (ContainsFlag(env, "cacheflush"))
|
||||
EnableChannel(JitSpew_CacheFlush);
|
||||
if (ContainsFlag(env, "logs"))
|
||||
EnableIonDebugLogging();
|
||||
EnableIonDebugAsyncLogging();
|
||||
if (ContainsFlag(env, "logs-sync"))
|
||||
EnableIonDebugSyncLogging();
|
||||
if (ContainsFlag(env, "profiling"))
|
||||
EnableChannel(JitSpew_Profiling);
|
||||
if (ContainsFlag(env, "trackopts"))
|
||||
@ -461,15 +595,5 @@ jit::DisableChannel(JitSpewChannel channel)
|
||||
LoggingBits &= ~(1 << uint32_t(channel));
|
||||
}
|
||||
|
||||
IonSpewFunction::IonSpewFunction(MIRGraph* graph, JS::HandleScript function)
|
||||
{
|
||||
IonSpewNewFunction(graph, function);
|
||||
}
|
||||
|
||||
IonSpewFunction::~IonSpewFunction()
|
||||
{
|
||||
IonSpewEndFunction();
|
||||
}
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
@ -77,7 +77,7 @@ namespace jit {
|
||||
/* Information about compiled scripts */\
|
||||
_(IonScripts) \
|
||||
/* Info about failing to log script */ \
|
||||
_(IonLogs) \
|
||||
_(IonSyncLogs) \
|
||||
/* Information during MIR building */ \
|
||||
_(IonMIR) \
|
||||
/* Information during bailouts */ \
|
||||
@ -103,41 +103,45 @@ static const int NULL_ID = -1;
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
class IonSpewer
|
||||
// Class made to hold the MIR and LIR graphs of an AsmJS / Ion compilation.
|
||||
class GraphSpewer
|
||||
{
|
||||
private:
|
||||
MIRGraph* graph;
|
||||
C1Spewer c1Spewer;
|
||||
JSONSpewer jsonSpewer;
|
||||
bool inited_;
|
||||
MIRGraph* graph_;
|
||||
C1Spewer c1Spewer_;
|
||||
JSONSpewer jsonSpewer_;
|
||||
|
||||
public:
|
||||
IonSpewer()
|
||||
: graph(nullptr), inited_(false)
|
||||
explicit GraphSpewer(TempAllocator *alloc)
|
||||
: graph_(nullptr),
|
||||
c1Spewer_(alloc),
|
||||
jsonSpewer_(alloc)
|
||||
{ }
|
||||
|
||||
// File output is terminated safely upon destruction.
|
||||
~IonSpewer();
|
||||
|
||||
bool init();
|
||||
void beginFunction(MIRGraph* graph, JS::HandleScript);
|
||||
bool isSpewingFunction() const;
|
||||
bool isSpewing() const {
|
||||
return graph_;
|
||||
}
|
||||
void init(MIRGraph* graph, JSScript* function);
|
||||
void beginFunction(JSScript* function);
|
||||
void spewPass(const char* pass);
|
||||
void spewPass(const char* pass, BacktrackingAllocator* ra);
|
||||
void endFunction();
|
||||
|
||||
void dump(Fprinter& c1, Fprinter& json);
|
||||
};
|
||||
|
||||
class IonSpewFunction
|
||||
void SpewBeginFunction(MIRGenerator* mir, JSScript* function);
|
||||
class AutoSpewEndFunction
|
||||
{
|
||||
public:
|
||||
IonSpewFunction(MIRGraph* graph, JS::HandleScript function);
|
||||
~IonSpewFunction();
|
||||
};
|
||||
private:
|
||||
MIRGenerator* mir_;
|
||||
|
||||
void IonSpewNewFunction(MIRGraph* graph, JS::HandleScript function);
|
||||
void IonSpewPass(const char* pass);
|
||||
void IonSpewPass(const char* pass, BacktrackingAllocator* ra);
|
||||
void IonSpewEndFunction();
|
||||
public:
|
||||
explicit AutoSpewEndFunction(MIRGenerator* mir)
|
||||
: mir_(mir)
|
||||
{ }
|
||||
~AutoSpewEndFunction();
|
||||
};
|
||||
|
||||
void CheckLogging();
|
||||
Fprinter& JitSpewPrinter();
|
||||
@ -154,19 +158,36 @@ void JitSpewDef(JitSpewChannel channel, const char* str, MDefinition* def);
|
||||
|
||||
void EnableChannel(JitSpewChannel channel);
|
||||
void DisableChannel(JitSpewChannel channel);
|
||||
void EnableIonDebugLogging();
|
||||
void EnableIonDebugSyncLogging();
|
||||
void EnableIonDebugAsyncLogging();
|
||||
|
||||
#else
|
||||
|
||||
static inline void IonSpewNewFunction(MIRGraph* graph, JS::HandleScript function)
|
||||
{ }
|
||||
static inline void IonSpewPass(const char* pass)
|
||||
{ }
|
||||
static inline void IonSpewPass(const char* pass, BacktrackingAllocator* ra)
|
||||
{ }
|
||||
static inline void IonSpewEndFunction()
|
||||
class GraphSpewer
|
||||
{
|
||||
public:
|
||||
GraphSpewer(TempAllocator *alloc) { }
|
||||
|
||||
bool isSpewing() { return false; }
|
||||
void init(MIRGraph* graph, JSScript* function) { }
|
||||
void beginFunction(JSScript* function) { }
|
||||
void spewPass(const char* pass) { }
|
||||
void spewPass(const char* pass, BacktrackingAllocator* ra) { }
|
||||
void endFunction() { }
|
||||
|
||||
void dump(Fprinter& c1, Fprinter& json) { }
|
||||
};
|
||||
|
||||
static inline void SpewBeginFunction(MIRGenerator* mir, JSScript* function)
|
||||
{ }
|
||||
|
||||
class AutoSpewEndFunction
|
||||
{
|
||||
public:
|
||||
explicit AutoSpewEndFunction(MIRGenerator* mir) { }
|
||||
~AutoSpewEndFunction() { }
|
||||
};
|
||||
|
||||
static inline void CheckLogging()
|
||||
{ }
|
||||
static inline Fprinter& JitSpewPrinter()
|
||||
@ -195,7 +216,9 @@ static inline void EnableChannel(JitSpewChannel)
|
||||
{ }
|
||||
static inline void DisableChannel(JitSpewChannel)
|
||||
{ }
|
||||
static inline void EnableIonDebugLogging()
|
||||
static inline void EnableIonDebugSyncLogging()
|
||||
{ }
|
||||
static inline void EnableIonDebugAsyncLogging()
|
||||
{ }
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
@ -245,6 +245,14 @@ class MIRGenerator
|
||||
}
|
||||
bool needsAsmJSBoundsCheckBranch(const MAsmJSHeapAccess* access) const;
|
||||
size_t foldableOffsetRange(const MAsmJSHeapAccess* access) const;
|
||||
|
||||
private:
|
||||
GraphSpewer gs_;
|
||||
|
||||
public:
|
||||
GraphSpewer& graphSpewer() {
|
||||
return gs_;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace jit
|
||||
|
@ -48,7 +48,8 @@ MIRGenerator::MIRGenerator(CompileCompartment* compartment, const JitCompileOpti
|
||||
#if defined(ASMJS_MAY_USE_SIGNAL_HANDLERS_FOR_OOB)
|
||||
usesSignalHandlersForAsmJSOOB_(usesSignalHandlersForAsmJSOOB),
|
||||
#endif
|
||||
options(options)
|
||||
options(options),
|
||||
gs_(alloc)
|
||||
{ }
|
||||
|
||||
bool
|
||||
|
@ -1054,6 +1054,7 @@ HelperThread::handleAsmJSWorkload()
|
||||
&asmData->mir->alloc());
|
||||
|
||||
int64_t before = PRMJ_Now();
|
||||
jit::AutoSpewEndFunction spewEndFunction(asmData->mir);
|
||||
|
||||
if (!OptimizeMIR(asmData->mir))
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user