michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=8 sts=4 et sw=4 tw=99: michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef jit_IonSpewer_h michael@0: #define jit_IonSpewer_h michael@0: michael@0: #include "mozilla/DebugOnly.h" michael@0: michael@0: #include michael@0: michael@0: #include "jit/C1Spewer.h" michael@0: #include "jit/JSONSpewer.h" michael@0: #include "js/RootingAPI.h" michael@0: michael@0: namespace js { michael@0: namespace jit { michael@0: michael@0: // New channels may be added below. michael@0: #define IONSPEW_CHANNEL_LIST(_) \ michael@0: /* Used to abort SSA construction */ \ michael@0: _(Abort) \ michael@0: /* Information about compiled scripts */\ michael@0: _(Scripts) \ michael@0: /* Information during MIR building */ \ michael@0: _(Logs) \ michael@0: /* Info about failing to log script */ \ michael@0: _(MIR) \ michael@0: /* Information during alias analysis */ \ michael@0: _(Alias) \ michael@0: /* Information during GVN */ \ michael@0: _(GVN) \ michael@0: /* Information during Range analysis */ \ michael@0: _(Range) \ michael@0: /* Information during LICM */ \ michael@0: _(LICM) \ michael@0: /* Information during regalloc */ \ michael@0: _(RegAlloc) \ michael@0: /* Information during inlining */ \ michael@0: _(Inlining) \ michael@0: /* Information during codegen */ \ michael@0: _(Codegen) \ michael@0: /* Information during bailouts */ \ michael@0: _(Bailouts) \ michael@0: /* Information during OSI */ \ michael@0: _(Invalidate) \ michael@0: /* Debug info about snapshots */ \ michael@0: _(Snapshots) \ michael@0: /* Generated inline cache stubs */ \ michael@0: _(InlineCaches) \ michael@0: /* Debug info about safepoints */ \ michael@0: _(Safepoints) \ michael@0: /* Debug info about Pools*/ \ michael@0: _(Pools) \ michael@0: /* Calls to js::jit::Trace() */ \ michael@0: _(Trace) \ michael@0: /* Debug info about the I$ */ \ michael@0: _(CacheFlush) \ michael@0: \ michael@0: /* BASELINE COMPILER SPEW */ \ michael@0: \ michael@0: /* Aborting Script Compilation. */ \ michael@0: _(BaselineAbort) \ michael@0: /* Script Compilation. */ \ michael@0: _(BaselineScripts) \ michael@0: /* Detailed op-specific spew. */ \ michael@0: _(BaselineOp) \ michael@0: /* Inline caches. */ \ michael@0: _(BaselineIC) \ michael@0: /* Inline cache fallbacks. */ \ michael@0: _(BaselineICFallback) \ michael@0: /* OSR from Baseline => Ion. */ \ michael@0: _(BaselineOSR) \ michael@0: /* Bailouts. */ \ michael@0: _(BaselineBailouts) \ michael@0: /* Debug Mode On Stack Recompile . */ \ michael@0: _(BaselineDebugModeOSR) michael@0: michael@0: michael@0: enum IonSpewChannel { michael@0: #define IONSPEW_CHANNEL(name) IonSpew_##name, michael@0: IONSPEW_CHANNEL_LIST(IONSPEW_CHANNEL) michael@0: #undef IONSPEW_CHANNEL michael@0: IonSpew_Terminator michael@0: }; michael@0: michael@0: michael@0: // The IonSpewer is only available on debug builds. michael@0: // None of the global functions have effect on non-debug builds. michael@0: static const int NULL_ID = -1; michael@0: michael@0: #ifdef DEBUG michael@0: michael@0: class IonSpewer michael@0: { michael@0: private: michael@0: MIRGraph *graph; michael@0: JS::HandleScript function; michael@0: C1Spewer c1Spewer; michael@0: JSONSpewer jsonSpewer; michael@0: bool inited_; michael@0: michael@0: public: michael@0: IonSpewer() michael@0: : graph(nullptr), function(NullPtr()), inited_(false) michael@0: { } michael@0: michael@0: // File output is terminated safely upon destruction. michael@0: ~IonSpewer(); michael@0: michael@0: bool init(); michael@0: void beginFunction(MIRGraph *graph, JS::HandleScript); michael@0: bool isSpewingFunction() const; michael@0: void spewPass(const char *pass); michael@0: void spewPass(const char *pass, LinearScanAllocator *ra); michael@0: void endFunction(); michael@0: }; michael@0: michael@0: void IonSpewNewFunction(MIRGraph *graph, JS::HandleScript function); michael@0: void IonSpewPass(const char *pass); michael@0: void IonSpewPass(const char *pass, LinearScanAllocator *ra); michael@0: void IonSpewEndFunction(); michael@0: michael@0: void CheckLogging(); michael@0: extern FILE *IonSpewFile; michael@0: void IonSpew(IonSpewChannel channel, const char *fmt, ...); michael@0: void IonSpewStart(IonSpewChannel channel, const char *fmt, ...); michael@0: void IonSpewCont(IonSpewChannel channel, const char *fmt, ...); michael@0: void IonSpewFin(IonSpewChannel channel); michael@0: void IonSpewHeader(IonSpewChannel channel); michael@0: bool IonSpewEnabled(IonSpewChannel channel); michael@0: void IonSpewVA(IonSpewChannel channel, const char *fmt, va_list ap); michael@0: void IonSpewStartVA(IonSpewChannel channel, const char *fmt, va_list ap); michael@0: void IonSpewContVA(IonSpewChannel channel, const char *fmt, va_list ap); michael@0: michael@0: void EnableChannel(IonSpewChannel channel); michael@0: void DisableChannel(IonSpewChannel channel); michael@0: void EnableIonDebugLogging(); michael@0: michael@0: #else michael@0: michael@0: static inline void IonSpewNewFunction(MIRGraph *graph, JS::HandleScript function) michael@0: { } michael@0: static inline void IonSpewPass(const char *pass) michael@0: { } michael@0: static inline void IonSpewPass(const char *pass, LinearScanAllocator *ra) michael@0: { } michael@0: static inline void IonSpewEndFunction() michael@0: { } michael@0: michael@0: static inline void CheckLogging() michael@0: { } michael@0: static FILE *const IonSpewFile = nullptr; michael@0: static inline void IonSpew(IonSpewChannel, const char *fmt, ...) michael@0: { } michael@0: static inline void IonSpewStart(IonSpewChannel channel, const char *fmt, ...) michael@0: { } michael@0: static inline void IonSpewCont(IonSpewChannel channel, const char *fmt, ...) michael@0: { } michael@0: static inline void IonSpewFin(IonSpewChannel channel) michael@0: { } michael@0: michael@0: static inline void IonSpewHeader(IonSpewChannel channel) michael@0: { } michael@0: static inline bool IonSpewEnabled(IonSpewChannel channel) michael@0: { return false; } michael@0: static inline void IonSpewVA(IonSpewChannel channel, const char *fmt, va_list ap) michael@0: { } michael@0: michael@0: static inline void EnableChannel(IonSpewChannel) michael@0: { } michael@0: static inline void DisableChannel(IonSpewChannel) michael@0: { } michael@0: static inline void EnableIonDebugLogging() michael@0: { } michael@0: michael@0: #endif /* DEBUG */ michael@0: michael@0: template michael@0: class AutoDisableSpew michael@0: { michael@0: mozilla::DebugOnly enabled_; michael@0: michael@0: public: michael@0: AutoDisableSpew() michael@0: : enabled_(IonSpewEnabled(Channel)) michael@0: { michael@0: DisableChannel(Channel); michael@0: } michael@0: michael@0: ~AutoDisableSpew() michael@0: { michael@0: #ifdef DEBUG michael@0: if (enabled_) michael@0: EnableChannel(Channel); michael@0: #endif michael@0: } michael@0: }; michael@0: michael@0: } /* ion */ michael@0: } /* js */ michael@0: michael@0: #endif /* jit_IonSpewer_h */