blob: 82b76b4b125df8ba855f111910eae751c5cbb5b4 [file] [log] [blame]
/* -*- 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_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"
namespace js {
namespace jit {
// New channels may be added below.
#define JITSPEW_CHANNEL_LIST(_) \
/* Information during sinking */ \
_(Prune) \
/* Information during escape analysis */\
_(Escape) \
/* Information during alias analysis */ \
_(Alias) \
/* Information during GVN */ \
_(GVN) \
/* Information during sincos */ \
_(Sincos) \
/* Information during sinking */ \
_(Sink) \
/* Information during Range analysis */ \
_(Range) \
/* Information during loop unrolling */ \
_(Unrolling) \
/* Information during LICM */ \
_(LICM) \
/* Information during regalloc */ \
_(RegAlloc) \
/* Information during inlining */ \
_(Inlining) \
/* Information during codegen */ \
_(Codegen) \
/* Debug info about safepoints */ \
_(Safepoints) \
/* Debug info about Pools*/ \
_(Pools) \
/* Profiling-related information */ \
_(Profiling) \
/* Information of tracked opt strats */ \
_(OptimizationTracking) \
/* Debug info about the I$ */ \
_(CacheFlush) \
\
/* BASELINE COMPILER SPEW */ \
\
/* Aborting Script Compilation. */ \
_(BaselineAbort) \
/* Script Compilation. */ \
_(BaselineScripts) \
/* Detailed op-specific spew. */ \
_(BaselineOp) \
/* Inline caches. */ \
_(BaselineIC) \
/* Inline cache fallbacks. */ \
_(BaselineICFallback) \
/* OSR from Baseline => Ion. */ \
_(BaselineOSR) \
/* Bailouts. */ \
_(BaselineBailouts) \
/* Debug Mode On Stack Recompile . */ \
_(BaselineDebugModeOSR) \
\
/* ION COMPILER SPEW */ \
\
/* Used to abort SSA construction */ \
_(IonAbort) \
/* Information about compiled scripts */\
_(IonScripts) \
/* Info about failing to log script */ \
_(IonSyncLogs) \
/* Information during MIR building */ \
_(IonMIR) \
/* Information during bailouts */ \
_(IonBailouts) \
/* Information during OSI */ \
_(IonInvalidate) \
/* Debug info about snapshots */ \
_(IonSnapshots) \
/* Generated inline cache stubs */ \
_(IonIC)
enum JitSpewChannel {
#define JITSPEW_CHANNEL(name) JitSpew_##name,
JITSPEW_CHANNEL_LIST(JITSPEW_CHANNEL)
#undef JITSPEW_CHANNEL
JitSpew_Terminator
};
class MIRGenerator;
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 AsmJS / 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_;
}
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);
};
void SpewBeginFunction(MIRGenerator* mir, JSScript* function);
class AutoSpewEndFunction
{
private:
MIRGenerator* mir_;
public:
explicit AutoSpewEndFunction(MIRGenerator* mir)
: mir_(mir)
{ }
~AutoSpewEndFunction();
};
void CheckLogging();
Fprinter& JitSpewPrinter();
class JitSpewIndent
{
JitSpewChannel channel_;
public:
explicit JitSpewIndent(JitSpewChannel channel);
~JitSpewIndent();
};
void JitSpew(JitSpewChannel channel, const char* fmt, ...);
void JitSpewStart(JitSpewChannel channel, const char* fmt, ...);
void JitSpewCont(JitSpewChannel channel, const char* fmt, ...);
void JitSpewFin(JitSpewChannel channel);
void JitSpewHeader(JitSpewChannel channel);
bool JitSpewEnabled(JitSpewChannel channel);
void JitSpewVA(JitSpewChannel channel, const char* fmt, va_list ap);
void JitSpewStartVA(JitSpewChannel channel, const char* fmt, va_list ap);
void JitSpewContVA(JitSpewChannel channel, const char* fmt, va_list ap);
void JitSpewDef(JitSpewChannel channel, const char* str, MDefinition* def);
void EnableChannel(JitSpewChannel channel);
void DisableChannel(JitSpewChannel channel);
void EnableIonDebugSyncLogging();
void EnableIonDebugAsyncLogging();
#else
class GraphSpewer
{
public:
explicit 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()
{
MOZ_CRASH("No empty backend for JitSpewPrinter");
}
class JitSpewIndent
{
public:
explicit JitSpewIndent(JitSpewChannel channel) {}
~JitSpewIndent() {}
};
// The computation of some of the argument of the spewing functions might be
// costly, thus we use variaidic macros to ignore any argument of these
// functions.
static inline void JitSpewCheckArguments(JitSpewChannel channel, const char* fmt)
{ }
#define JitSpewCheckExpandedArgs(channel, fmt, ...) JitSpewCheckArguments(channel, fmt)
#define JitSpewCheckExpandedArgs_(ArgList) JitSpewCheckExpandedArgs ArgList /* Fix MSVC issue */
#define JitSpew(...) JitSpewCheckExpandedArgs_((__VA_ARGS__))
#define JitSpewStart(...) JitSpewCheckExpandedArgs_((__VA_ARGS__))
#define JitSpewCont(...) JitSpewCheckExpandedArgs_((__VA_ARGS__))
static inline void JitSpewFin(JitSpewChannel channel)
{ }
static inline void JitSpewHeader(JitSpewChannel channel)
{ }
static inline bool JitSpewEnabled(JitSpewChannel channel)
{ return false; }
static inline void JitSpewVA(JitSpewChannel channel, const char* fmt, va_list ap)
{ }
static inline void JitSpewDef(JitSpewChannel channel, const char* str, MDefinition* def)
{ }
static inline void EnableChannel(JitSpewChannel)
{ }
static inline void DisableChannel(JitSpewChannel)
{ }
static inline void EnableIonDebugSyncLogging()
{ }
static inline void EnableIonDebugAsyncLogging()
{ }
#endif /* JS_JITSPEW */
template <JitSpewChannel Channel>
class AutoDisableSpew
{
mozilla::DebugOnly<bool> enabled_;
public:
AutoDisableSpew()
: enabled_(JitSpewEnabled(Channel))
{
DisableChannel(Channel);
}
~AutoDisableSpew()
{
#ifdef JS_JITSPEW
if (enabled_)
EnableChannel(Channel);
#endif
}
};
} // namespace jit
} // namespace js
#endif /* jit_JitSpewer_h */