Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sts=4 et sw=4 tw=99:
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/DebugOnly.h"
11 : #include "mozilla/IntegerPrintfMacros.h"
12 :
13 : #include <stdarg.h>
14 :
15 : #include "jit/C1Spewer.h"
16 : #include "jit/JSONSpewer.h"
17 :
18 : #include "js/RootingAPI.h"
19 :
20 : #include "vm/Printer.h"
21 :
22 : namespace js {
23 : namespace jit {
24 :
25 : // New channels may be added below.
26 : #define JITSPEW_CHANNEL_LIST(_) \
27 : /* Information during sinking */ \
28 : _(Prune) \
29 : /* Information during escape analysis */\
30 : _(Escape) \
31 : /* Information during alias analysis */ \
32 : _(Alias) \
33 : /* Information during alias analysis */ \
34 : _(AliasSummaries) \
35 : /* Information during GVN */ \
36 : _(GVN) \
37 : /* Information during sincos */ \
38 : _(Sincos) \
39 : /* Information during sinking */ \
40 : _(Sink) \
41 : /* Information during Range analysis */ \
42 : _(Range) \
43 : /* Information during loop unrolling */ \
44 : _(Unrolling) \
45 : /* Information during LICM */ \
46 : _(LICM) \
47 : /* Info about fold linear constants */ \
48 : _(FLAC) \
49 : /* Effective address analysis info */ \
50 : _(EAA) \
51 : /* Information during regalloc */ \
52 : _(RegAlloc) \
53 : /* Information during inlining */ \
54 : _(Inlining) \
55 : /* Information during codegen */ \
56 : _(Codegen) \
57 : /* Debug info about safepoints */ \
58 : _(Safepoints) \
59 : /* Debug info about Pools*/ \
60 : _(Pools) \
61 : /* Profiling-related information */ \
62 : _(Profiling) \
63 : /* Information of tracked opt strats */ \
64 : _(OptimizationTracking) \
65 : _(OptimizationTrackingExtended) \
66 : /* Debug info about the I$ */ \
67 : _(CacheFlush) \
68 : /* Output a list of MIR expressions */ \
69 : _(MIRExpressions) \
70 : /* Print control flow graph */ \
71 : _(CFG) \
72 : \
73 : /* BASELINE COMPILER SPEW */ \
74 : \
75 : /* Aborting Script Compilation. */ \
76 : _(BaselineAbort) \
77 : /* Script Compilation. */ \
78 : _(BaselineScripts) \
79 : /* Detailed op-specific spew. */ \
80 : _(BaselineOp) \
81 : /* Inline caches. */ \
82 : _(BaselineIC) \
83 : /* Inline cache fallbacks. */ \
84 : _(BaselineICFallback) \
85 : /* OSR from Baseline => Ion. */ \
86 : _(BaselineOSR) \
87 : /* Bailouts. */ \
88 : _(BaselineBailouts) \
89 : /* Debug Mode On Stack Recompile . */ \
90 : _(BaselineDebugModeOSR) \
91 : \
92 : /* ION COMPILER SPEW */ \
93 : \
94 : /* Used to abort SSA construction */ \
95 : _(IonAbort) \
96 : /* Information about compiled scripts */\
97 : _(IonScripts) \
98 : /* Info about failing to log script */ \
99 : _(IonSyncLogs) \
100 : /* Information during MIR building */ \
101 : _(IonMIR) \
102 : /* Information during bailouts */ \
103 : _(IonBailouts) \
104 : /* Information during OSI */ \
105 : _(IonInvalidate) \
106 : /* Debug info about snapshots */ \
107 : _(IonSnapshots) \
108 : /* Generated inline cache stubs */ \
109 : _(IonIC)
110 :
111 : enum JitSpewChannel {
112 : #define JITSPEW_CHANNEL(name) JitSpew_##name,
113 : JITSPEW_CHANNEL_LIST(JITSPEW_CHANNEL)
114 : #undef JITSPEW_CHANNEL
115 : JitSpew_Terminator
116 : };
117 :
118 : class BacktrackingAllocator;
119 : class MDefinition;
120 : class MIRGenerator;
121 : class MIRGraph;
122 : class TempAllocator;
123 :
124 : // The JitSpewer is only available on debug builds.
125 : // None of the global functions have effect on non-debug builds.
126 : static const int NULL_ID = -1;
127 :
128 : #ifdef JS_JITSPEW
129 :
130 : // Class made to hold the MIR and LIR graphs of an Wasm / Ion compilation.
131 169 : class GraphSpewer
132 : {
133 : private:
134 : MIRGraph* graph_;
135 : LSprinter c1Printer_;
136 : LSprinter jsonPrinter_;
137 : C1Spewer c1Spewer_;
138 : JSONSpewer jsonSpewer_;
139 :
140 : public:
141 : explicit GraphSpewer(TempAllocator *alloc);
142 :
143 260 : bool isSpewing() const {
144 260 : return graph_;
145 : }
146 : void init(MIRGraph* graph, JSScript* function);
147 : void beginFunction(JSScript* function);
148 : void spewPass(const char* pass);
149 : void spewPass(const char* pass, BacktrackingAllocator* ra);
150 : void endFunction();
151 :
152 : void dump(Fprinter& c1, Fprinter& json);
153 : };
154 :
155 : void SpewBeginFunction(MIRGenerator* mir, JSScript* function);
156 : class AutoSpewEndFunction
157 : {
158 : private:
159 : MIRGenerator* mir_;
160 :
161 : public:
162 8 : explicit AutoSpewEndFunction(MIRGenerator* mir)
163 8 : : mir_(mir)
164 8 : { }
165 : ~AutoSpewEndFunction();
166 : };
167 :
168 : void CheckLogging();
169 : Fprinter& JitSpewPrinter();
170 :
171 : class JitSpewIndent
172 : {
173 : JitSpewChannel channel_;
174 :
175 : public:
176 : explicit JitSpewIndent(JitSpewChannel channel);
177 : ~JitSpewIndent();
178 : };
179 :
180 : void JitSpew(JitSpewChannel channel, const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3);
181 : void JitSpewStart(JitSpewChannel channel, const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3);
182 : void JitSpewCont(JitSpewChannel channel, const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3);
183 : void JitSpewFin(JitSpewChannel channel);
184 : void JitSpewHeader(JitSpewChannel channel);
185 : bool JitSpewEnabled(JitSpewChannel channel);
186 : void JitSpewVA(JitSpewChannel channel, const char* fmt, va_list ap) MOZ_FORMAT_PRINTF(2, 0);
187 : void JitSpewStartVA(JitSpewChannel channel, const char* fmt, va_list ap) MOZ_FORMAT_PRINTF(2, 0);
188 : void JitSpewContVA(JitSpewChannel channel, const char* fmt, va_list ap) MOZ_FORMAT_PRINTF(2, 0);
189 : void JitSpewDef(JitSpewChannel channel, const char* str, MDefinition* def);
190 :
191 : void EnableChannel(JitSpewChannel channel);
192 : void DisableChannel(JitSpewChannel channel);
193 : void EnableIonDebugSyncLogging();
194 : void EnableIonDebugAsyncLogging();
195 :
196 : #else
197 :
198 : class GraphSpewer
199 : {
200 : public:
201 : explicit GraphSpewer(TempAllocator *alloc) { }
202 :
203 : bool isSpewing() { return false; }
204 : void init(MIRGraph* graph, JSScript* function) { }
205 : void beginFunction(JSScript* function) { }
206 : void spewPass(const char* pass) { }
207 : void spewPass(const char* pass, BacktrackingAllocator* ra) { }
208 : void endFunction() { }
209 :
210 : void dump(Fprinter& c1, Fprinter& json) { }
211 : };
212 :
213 : static inline void SpewBeginFunction(MIRGenerator* mir, JSScript* function)
214 : { }
215 :
216 : class AutoSpewEndFunction
217 : {
218 : public:
219 : explicit AutoSpewEndFunction(MIRGenerator* mir) { }
220 : ~AutoSpewEndFunction() { }
221 : };
222 :
223 : static inline void CheckLogging()
224 : { }
225 : static inline Fprinter& JitSpewPrinter()
226 : {
227 : MOZ_CRASH("No empty backend for JitSpewPrinter");
228 : }
229 :
230 : class JitSpewIndent
231 : {
232 : public:
233 : explicit JitSpewIndent(JitSpewChannel channel) {}
234 : ~JitSpewIndent() {}
235 : };
236 :
237 : // The computation of some of the argument of the spewing functions might be
238 : // costly, thus we use variaidic macros to ignore any argument of these
239 : // functions.
240 : static inline void JitSpewCheckArguments(JitSpewChannel channel, const char* fmt)
241 : { }
242 :
243 : #define JitSpewCheckExpandedArgs(channel, fmt, ...) JitSpewCheckArguments(channel, fmt)
244 : #define JitSpewCheckExpandedArgs_(ArgList) JitSpewCheckExpandedArgs ArgList /* Fix MSVC issue */
245 : #define JitSpew(...) JitSpewCheckExpandedArgs_((__VA_ARGS__))
246 : #define JitSpewStart(...) JitSpewCheckExpandedArgs_((__VA_ARGS__))
247 : #define JitSpewCont(...) JitSpewCheckExpandedArgs_((__VA_ARGS__))
248 :
249 : static inline void JitSpewFin(JitSpewChannel channel)
250 : { }
251 :
252 : static inline void JitSpewHeader(JitSpewChannel channel)
253 : { }
254 : static inline bool JitSpewEnabled(JitSpewChannel channel)
255 : { return false; }
256 : static inline MOZ_FORMAT_PRINTF(2, 0)
257 : void JitSpewVA(JitSpewChannel channel, const char* fmt, va_list ap)
258 : { }
259 : static inline void JitSpewDef(JitSpewChannel channel, const char* str, MDefinition* def)
260 : { }
261 :
262 : static inline void EnableChannel(JitSpewChannel)
263 : { }
264 : static inline void DisableChannel(JitSpewChannel)
265 : { }
266 : static inline void EnableIonDebugSyncLogging()
267 : { }
268 : static inline void EnableIonDebugAsyncLogging()
269 : { }
270 :
271 : #endif /* JS_JITSPEW */
272 :
273 : template <JitSpewChannel Channel>
274 : class AutoDisableSpew
275 : {
276 : mozilla::DebugOnly<bool> enabled_;
277 :
278 : public:
279 : AutoDisableSpew()
280 : : enabled_(JitSpewEnabled(Channel))
281 : {
282 : DisableChannel(Channel);
283 : }
284 :
285 : ~AutoDisableSpew()
286 : {
287 : #ifdef JS_JITSPEW
288 : if (enabled_)
289 : EnableChannel(Channel);
290 : #endif
291 : }
292 : };
293 :
294 : } // namespace jit
295 : } // namespace js
296 :
297 : #endif /* jit_JitSpewer_h */
|