JitSpewer.h (11272B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef jit_JitSpewer_h 8 #define jit_JitSpewer_h 9 10 #include "mozilla/Assertions.h" 11 #include "mozilla/Attributes.h" 12 #include "mozilla/IntegerPrintfMacros.h" 13 14 #include <stdarg.h> 15 16 #include "jit/GraphSpewer.h" 17 #include "js/Printer.h" 18 #include "js/TypeDecls.h" 19 #include "wasm/WasmTypeDecls.h" 20 21 enum JSValueType : uint8_t; 22 23 namespace js { 24 namespace jit { 25 26 // New channels may be added below. 27 #define JITSPEW_CHANNEL_LIST(_) \ 28 /* Information during sinking */ \ 29 _(Prune) \ 30 /* Information during escape analysis */ \ 31 _(Escape) \ 32 /* Information during alias analysis */ \ 33 _(Alias) \ 34 /* Information during alias analysis */ \ 35 _(AliasSummaries) \ 36 /* Information during GVN */ \ 37 _(GVN) \ 38 /* Information during sinking */ \ 39 _(Sink) \ 40 /* Information during Range analysis */ \ 41 _(Range) \ 42 /* Information during LICM */ \ 43 _(LICM) \ 44 /* Information during Branch Hinting */ \ 45 _(BranchHint) \ 46 /* Info about fold linear constants */ \ 47 _(FLAC) \ 48 /* Effective address analysis info */ \ 49 _(EAA) \ 50 /* Wasm Bounds Check Elimination */ \ 51 _(WasmBCE) \ 52 /* Information during regalloc */ \ 53 _(RegAlloc) \ 54 /* Information during inlining */ \ 55 _(Inlining) \ 56 /* Information during codegen */ \ 57 _(Codegen) \ 58 /* Debug info about safepoints */ \ 59 _(Safepoints) \ 60 /* Debug info about Pools*/ \ 61 _(Pools) \ 62 /* Profiling-related information */ \ 63 _(Profiling) \ 64 /* Debug info about the I$ */ \ 65 _(CacheFlush) \ 66 /* Info about redundant shape guards */ \ 67 _(RedundantShapeGuards) \ 68 /* Info about redundant GC barriers */ \ 69 _(RedundantGCBarriers) \ 70 /* Info about loads used as keys */ \ 71 _(MarkLoadsUsedAsPropertyKeys) \ 72 /* Output a list of MIR expressions */ \ 73 _(MIRExpressions) \ 74 /* Summary info about loop unrolling */ \ 75 _(Unroll) \ 76 /* Detailed info about loop unrolling */ \ 77 _(UnrollDetails) \ 78 /* Information about stub folding */ \ 79 _(StubFolding) \ 80 /* Additional information about stub folding */ \ 81 _(StubFoldingDetails) \ 82 \ 83 /* BASELINE COMPILER SPEW */ \ 84 \ 85 /* Aborting Script Compilation. */ \ 86 _(BaselineAbort) \ 87 /* Script Compilation. */ \ 88 _(BaselineScripts) \ 89 /* Detailed op-specific spew. */ \ 90 _(BaselineOp) \ 91 /* Inline caches. */ \ 92 _(BaselineIC) \ 93 /* Inline cache fallbacks. */ \ 94 _(BaselineICFallback) \ 95 /* OSR from Baseline => Ion. */ \ 96 _(BaselineOSR) \ 97 /* Bailouts. */ \ 98 _(BaselineBailouts) \ 99 /* Debug Mode On Stack Recompile . */ \ 100 _(BaselineDebugModeOSR) \ 101 \ 102 /* ION COMPILER SPEW */ \ 103 \ 104 /* Used to abort SSA construction */ \ 105 _(IonAbort) \ 106 /* Information about compiled scripts */ \ 107 _(IonScripts) \ 108 /* Info about failing to log script */ \ 109 _(IonSyncLogs) \ 110 /* Information during MIR building */ \ 111 _(IonMIR) \ 112 /* Information during bailouts */ \ 113 _(IonBailouts) \ 114 /* Information during OSI */ \ 115 _(IonInvalidate) \ 116 /* Debug info about snapshots */ \ 117 _(IonSnapshots) \ 118 /* Generated inline cache stubs */ \ 119 _(IonIC) \ 120 \ 121 /* WARP SPEW */ \ 122 \ 123 /* Generated WarpSnapshots */ \ 124 _(WarpSnapshots) \ 125 /* CacheIR transpiler logging */ \ 126 _(WarpTranspiler) \ 127 /* Trial inlining for Warp */ \ 128 _(WarpTrialInlining) 129 130 enum JitSpewChannel { 131 #define JITSPEW_CHANNEL(name) JitSpew_##name, 132 JITSPEW_CHANNEL_LIST(JITSPEW_CHANNEL) 133 #undef JITSPEW_CHANNEL 134 JitSpew_Terminator 135 }; 136 137 class BacktrackingAllocator; 138 class MDefinition; 139 class MIRGenerator; 140 class MIRGraph; 141 class TempAllocator; 142 143 const char* ValTypeToString(JSValueType type); 144 145 // The JitSpewer is only available on debug builds. 146 // None of the global functions have effect on non-debug builds. 147 #ifdef JS_JITSPEW 148 149 // Class made to hold the MIR and LIR graphs of an Wasm / Ion compilation and 150 // automatically spew them to JITSPEW. 151 class JitSpewGraphSpewer { 152 private: 153 MIRGraph* graph_; 154 LSprinter jsonPrinter_; 155 GraphSpewer graphSpewer_; 156 157 public: 158 explicit JitSpewGraphSpewer(TempAllocator* alloc, 159 const wasm::CodeMetadata* wasmCodeMeta = nullptr); 160 161 bool isSpewing() const { return graph_; } 162 void init(MIRGraph* graph, JSScript* function); 163 void beginFunction(JSScript* function); 164 void beginWasmFunction(unsigned funcIndex); 165 void spewPass(const char* pass, BacktrackingAllocator* ra = nullptr); 166 void endFunction(); 167 168 void dump(Fprinter& json); 169 }; 170 171 void CheckLogging(); 172 Fprinter& JitSpewPrinter(); 173 174 class JitSpewIndent { 175 JitSpewChannel channel_; 176 177 public: 178 explicit JitSpewIndent(JitSpewChannel channel); 179 ~JitSpewIndent(); 180 }; 181 182 void JitSpew(JitSpewChannel channel, const char* fmt, ...) 183 MOZ_FORMAT_PRINTF(2, 3); 184 void JitSpewStart(JitSpewChannel channel, const char* fmt, ...) 185 MOZ_FORMAT_PRINTF(2, 3); 186 void JitSpewCont(JitSpewChannel channel, const char* fmt, ...) 187 MOZ_FORMAT_PRINTF(2, 3); 188 void JitSpewFin(JitSpewChannel channel); 189 void JitSpewHeader(JitSpewChannel channel); 190 191 } // namespace jit 192 193 namespace jitspew::detail { 194 extern bool LoggingChecked; 195 extern uint64_t LoggingBits; 196 extern mozilla::Atomic<uint32_t, mozilla::Relaxed> filteredOutCompilations; 197 } // namespace jitspew::detail 198 199 namespace jit { 200 201 static inline bool JitSpewEnabled(JitSpewChannel channel) { 202 MOZ_ASSERT(jitspew::detail::LoggingChecked); 203 return (jitspew::detail::LoggingBits & (uint64_t(1) << uint32_t(channel))) && 204 !jitspew::detail::filteredOutCompilations; 205 } 206 207 void JitSpewVA(JitSpewChannel channel, const char* fmt, va_list ap) 208 MOZ_FORMAT_PRINTF(2, 0); 209 void JitSpewStartVA(JitSpewChannel channel, const char* fmt, va_list ap) 210 MOZ_FORMAT_PRINTF(2, 0); 211 void JitSpewContVA(JitSpewChannel channel, const char* fmt, va_list ap) 212 MOZ_FORMAT_PRINTF(2, 0); 213 void JitSpewDef(JitSpewChannel channel, const char* str, MDefinition* def); 214 215 void EnableChannel(JitSpewChannel channel); 216 void DisableChannel(JitSpewChannel channel); 217 void EnableIonDebugSyncLogging(); 218 void EnableIonDebugAsyncLogging(); 219 220 # define JitSpewIfEnabled(channel, fmt, ...) \ 221 do { \ 222 if (JitSpewEnabled(channel)) { \ 223 JitSpew(channel, fmt, __VA_ARGS__); \ 224 } \ 225 } while (false); 226 227 #else 228 229 class JitSpewGraphSpewer { 230 public: 231 explicit JitSpewGraphSpewer( 232 TempAllocator* alloc, const wasm::CodeMetadata* wasmCodeMeta = nullptr) {} 233 234 bool isSpewing() { return false; } 235 void init(MIRGraph* graph, JSScript* function) {} 236 void beginFunction(JSScript* function) {} 237 void beginWasmFunction(unsigned funcIndex) {} 238 void spewPass(const char* pass, BacktrackingAllocator* ra = nullptr) {} 239 void endFunction() {} 240 241 void dump(Fprinter& c1, Fprinter& json) {} 242 }; 243 244 static inline void CheckLogging() {} 245 static inline Fprinter& JitSpewPrinter() { 246 MOZ_CRASH("No empty backend for JitSpewPrinter"); 247 } 248 249 class JitSpewIndent { 250 public: 251 explicit JitSpewIndent(JitSpewChannel channel) {} 252 ~JitSpewIndent() {} 253 }; 254 255 // The computation of some of the argument of the spewing functions might be 256 // costly, thus we use variaidic macros to ignore any argument of these 257 // functions. 258 static inline void JitSpewCheckArguments(JitSpewChannel channel, 259 const char* fmt) {} 260 261 # define JitSpewCheckExpandedArgs(channel, fmt, ...) \ 262 JitSpewCheckArguments(channel, fmt) 263 # define JitSpewCheckExpandedArgs_(ArgList) \ 264 JitSpewCheckExpandedArgs ArgList /* Fix MSVC issue */ 265 # define JitSpew(...) JitSpewCheckExpandedArgs_((__VA_ARGS__)) 266 # define JitSpewStart(...) JitSpewCheckExpandedArgs_((__VA_ARGS__)) 267 # define JitSpewCont(...) JitSpewCheckExpandedArgs_((__VA_ARGS__)) 268 269 # define JitSpewIfEnabled(channel, fmt, ...) \ 270 JitSpewCheckArguments(channel, fmt) 271 272 static inline void JitSpewFin(JitSpewChannel channel) {} 273 274 static inline void JitSpewHeader(JitSpewChannel channel) {} 275 static inline bool JitSpewEnabled(JitSpewChannel channel) { return false; } 276 static inline MOZ_FORMAT_PRINTF(2, 0) void JitSpewVA(JitSpewChannel channel, 277 const char* fmt, 278 va_list ap) {} 279 static inline void JitSpewDef(JitSpewChannel channel, const char* str, 280 MDefinition* def) {} 281 282 static inline void EnableChannel(JitSpewChannel) {} 283 static inline void DisableChannel(JitSpewChannel) {} 284 static inline void EnableIonDebugSyncLogging() {} 285 static inline void EnableIonDebugAsyncLogging() {} 286 287 #endif /* JS_JITSPEW */ 288 289 } // namespace jit 290 } // namespace js 291 292 #endif /* jit_JitSpewer_h */