summaryrefslogtreecommitdiffstats
path: root/js/src/jit/JitSpewer.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit/JitSpewer.h')
-rw-r--r--js/src/jit/JitSpewer.h293
1 files changed, 293 insertions, 0 deletions
diff --git a/js/src/jit/JitSpewer.h b/js/src/jit/JitSpewer.h
new file mode 100644
index 000000000..e187f7aa7
--- /dev/null
+++ b/js/src/jit/JitSpewer.h
@@ -0,0 +1,293 @@
+/* -*- 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"
+
+#include "vm/Printer.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 alias analysis */ \
+ _(AliasSummaries) \
+ /* 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) \
+ /* Info about fold linear constants */ \
+ _(FLAC) \
+ /* Effective address analysis info */ \
+ _(EAA) \
+ /* 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) \
+ /* Output a list of MIR expressions */ \
+ _(MIRExpressions) \
+ \
+ /* 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 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_;
+ }
+ 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, ...) MOZ_FORMAT_PRINTF(2, 3);
+void JitSpewStart(JitSpewChannel channel, const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3);
+void JitSpewCont(JitSpewChannel channel, const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3);
+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 */