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/. */
10
#include "IonSpewer.h"
12
#include "jsscriptinlines.h"
16
# define ION_SPEW_DIR ""
17
# elif defined(__ANDROID__)
18
# define ION_SPEW_DIR "/data/local/tmp/"
20
# define ION_SPEW_DIR "/tmp/"
25
using namespace js::jit;
27
// IonSpewer singleton.
28
static IonSpewer ionspewer;
30
static bool LoggingChecked = false;
31
static uint32_t LoggingBits = 0;
32
static uint32_t filteredOutCompilations = 0;
34
static const char * const ChannelNames[] =
36
#define IONSPEW_CHANNEL(name) #name,
37
IONSPEW_CHANNEL_LIST(IONSPEW_CHANNEL)
38
#undef IONSPEW_CHANNEL
42
FilterContainsLocation(HandleScript function)
44
static const char *filter = getenv("IONFILTER");
46
// If there is no filter we accept all outputs.
47
if (!filter || !filter[0])
50
// Disable asm.js output when filter is set.
54
const char *filename = function->filename();
55
const size_t line = function->lineno;
56
static size_t filelen = strlen(filename);
57
const char *index = strstr(filter, filename);
59
if (index == filter || index[-1] == ',') {
60
if (index[filelen] == 0 || index[filelen] == ',')
62
if (index[filelen] == ':' && line != size_t(-1)) {
63
size_t read_line = strtoul(&index[filelen + 1], NULL, 10);
64
if (read_line == line)
68
index = strstr(index + filelen, filename);
74
jit::EnableIonDebugLogging()
80
jit::IonSpewNewFunction(MIRGraph *graph, HandleScript function)
82
if (!js_IonOptions.parallelCompilation)
83
ionspewer.beginFunction(graph, function);
87
jit::IonSpewPass(const char *pass)
89
if (!js_IonOptions.parallelCompilation)
90
ionspewer.spewPass(pass);
94
jit::IonSpewPass(const char *pass, LinearScanAllocator *ra)
96
if (!js_IonOptions.parallelCompilation)
97
ionspewer.spewPass(pass, ra);
101
jit::IonSpewEndFunction()
103
if (!js_IonOptions.parallelCompilation)
104
ionspewer.endFunction();
108
IonSpewer::~IonSpewer()
123
if (!c1Spewer.init(ION_SPEW_DIR "ion.cfg"))
125
if (!jsonSpewer.init(ION_SPEW_DIR "ion.json"))
133
IonSpewer::isSpewingFunction() const
135
return inited_ && graph;
139
IonSpewer::beginFunction(MIRGraph *graph, HandleScript function)
144
if (!FilterContainsLocation(function)) {
145
JS_ASSERT(!this->graph);
146
// filter out logs during the compilation.
147
filteredOutCompilations++;
152
this->function = function;
154
c1Spewer.beginFunction(graph, function);
155
jsonSpewer.beginFunction(function);
159
IonSpewer::spewPass(const char *pass)
161
if (!isSpewingFunction())
164
c1Spewer.spewPass(pass);
165
jsonSpewer.beginPass(pass);
166
jsonSpewer.spewMIR(graph);
167
jsonSpewer.spewLIR(graph);
168
jsonSpewer.endPass();
172
IonSpewer::spewPass(const char *pass, LinearScanAllocator *ra)
174
if (!isSpewingFunction())
177
c1Spewer.spewPass(pass);
178
c1Spewer.spewIntervals(pass, ra);
179
jsonSpewer.beginPass(pass);
180
jsonSpewer.spewMIR(graph);
181
jsonSpewer.spewLIR(graph);
182
jsonSpewer.spewIntervals(ra);
183
jsonSpewer.endPass();
187
IonSpewer::endFunction()
189
if (!isSpewingFunction()) {
190
filteredOutCompilations--;
194
c1Spewer.endFunction();
195
jsonSpewer.endFunction();
201
FILE *jit::IonSpewFile = NULL;
204
ContainsFlag(const char *str, const char *flag)
206
size_t flaglen = strlen(flag);
207
const char *index = strstr(str, flag);
209
if ((index == str || index[-1] == ',') && (index[flaglen] == 0 || index[flaglen] == ','))
211
index = strstr(index + flaglen, flag);
221
LoggingChecked = true;
222
const char *env = getenv("IONFLAGS");
225
if (strstr(env, "help")) {
229
"usage: IONFLAGS=option,option,option,... where options can be:\n"
231
" aborts Compilation abort messages\n"
232
" scripts Compiled scripts\n"
233
" mir MIR information\n"
234
" alias Alias analysis\n"
235
" gvn Global Value Numbering\n"
236
" licm Loop invariant code motion\n"
237
" regalloc Register allocation\n"
239
" snapshots Snapshot information\n"
240
" codegen Native code generation\n"
241
" bailouts Bailouts\n"
242
" caches Inline caches\n"
243
" osi Invalidation\n"
244
" safepoints Safepoints\n"
245
" pools Literal Pools (ARM only for now)\n"
246
" cacheflush Instruction Cache flushes (ARM only for now)\n"
247
" logs C1 and JSON visualization logging\n"
248
" trace Generate calls to js::jit::Trace() for effectful instructions\n"
251
" bl-aborts Baseline compiler abort messages\n"
252
" bl-scripts Baseline script-compilation\n"
253
" bl-op Baseline compiler detailed op-specific messages\n"
254
" bl-ic Baseline inline-cache messages\n"
255
" bl-ic-fb Baseline IC fallback stub messages\n"
256
" bl-osr Baseline IC OSR messages\n"
257
" bl-bails Baseline bailouts\n"
258
" bl-all All baseline spew\n"
264
if (ContainsFlag(env, "aborts"))
265
EnableChannel(IonSpew_Abort);
266
if (ContainsFlag(env, "alias"))
267
EnableChannel(IonSpew_Alias);
268
if (ContainsFlag(env, "scripts"))
269
EnableChannel(IonSpew_Scripts);
270
if (ContainsFlag(env, "mir"))
271
EnableChannel(IonSpew_MIR);
272
if (ContainsFlag(env, "gvn"))
273
EnableChannel(IonSpew_GVN);
274
if (ContainsFlag(env, "range"))
275
EnableChannel(IonSpew_Range);
276
if (ContainsFlag(env, "licm"))
277
EnableChannel(IonSpew_LICM);
278
if (ContainsFlag(env, "regalloc"))
279
EnableChannel(IonSpew_RegAlloc);
280
if (ContainsFlag(env, "inline"))
281
EnableChannel(IonSpew_Inlining);
282
if (ContainsFlag(env, "snapshots"))
283
EnableChannel(IonSpew_Snapshots);
284
if (ContainsFlag(env, "codegen"))
285
EnableChannel(IonSpew_Codegen);
286
if (ContainsFlag(env, "bailouts"))
287
EnableChannel(IonSpew_Bailouts);
288
if (ContainsFlag(env, "osi"))
289
EnableChannel(IonSpew_Invalidate);
290
if (ContainsFlag(env, "caches"))
291
EnableChannel(IonSpew_InlineCaches);
292
if (ContainsFlag(env, "safepoints"))
293
EnableChannel(IonSpew_Safepoints);
294
if (ContainsFlag(env, "pools"))
295
EnableChannel(IonSpew_Pools);
296
if (ContainsFlag(env, "cacheflush"))
297
EnableChannel(IonSpew_CacheFlush);
298
if (ContainsFlag(env, "logs"))
299
EnableIonDebugLogging();
300
if (ContainsFlag(env, "trace"))
301
EnableChannel(IonSpew_Trace);
302
if (ContainsFlag(env, "all"))
303
LoggingBits = uint32_t(-1);
305
if (ContainsFlag(env, "bl-aborts"))
306
EnableChannel(IonSpew_BaselineAbort);
307
if (ContainsFlag(env, "bl-scripts"))
308
EnableChannel(IonSpew_BaselineScripts);
309
if (ContainsFlag(env, "bl-op"))
310
EnableChannel(IonSpew_BaselineOp);
311
if (ContainsFlag(env, "bl-ic"))
312
EnableChannel(IonSpew_BaselineIC);
313
if (ContainsFlag(env, "bl-ic-fb"))
314
EnableChannel(IonSpew_BaselineICFallback);
315
if (ContainsFlag(env, "bl-osr"))
316
EnableChannel(IonSpew_BaselineOSR);
317
if (ContainsFlag(env, "bl-bails"))
318
EnableChannel(IonSpew_BaselineBailouts);
319
if (ContainsFlag(env, "bl-all")) {
320
EnableChannel(IonSpew_BaselineAbort);
321
EnableChannel(IonSpew_BaselineScripts);
322
EnableChannel(IonSpew_BaselineOp);
323
EnableChannel(IonSpew_BaselineIC);
324
EnableChannel(IonSpew_BaselineICFallback);
325
EnableChannel(IonSpew_BaselineOSR);
326
EnableChannel(IonSpew_BaselineBailouts);
329
if (LoggingBits != 0)
330
EnableIonDebugLogging();
332
IonSpewFile = stderr;
336
jit::IonSpewStartVA(IonSpewChannel channel, const char *fmt, va_list ap)
338
if (!IonSpewEnabled(channel))
341
IonSpewHeader(channel);
342
vfprintf(stderr, fmt, ap);
346
jit::IonSpewContVA(IonSpewChannel channel, const char *fmt, va_list ap)
348
if (!IonSpewEnabled(channel))
351
vfprintf(stderr, fmt, ap);
355
jit::IonSpewFin(IonSpewChannel channel)
357
if (!IonSpewEnabled(channel))
360
fprintf(stderr, "\n");
364
jit::IonSpewVA(IonSpewChannel channel, const char *fmt, va_list ap)
366
IonSpewStartVA(channel, fmt, ap);
371
jit::IonSpew(IonSpewChannel channel, const char *fmt, ...)
375
IonSpewVA(channel, fmt, ap);
380
jit::IonSpewStart(IonSpewChannel channel, const char *fmt, ...)
384
IonSpewStartVA(channel, fmt, ap);
388
jit::IonSpewCont(IonSpewChannel channel, const char *fmt, ...)
392
IonSpewContVA(channel, fmt, ap);
397
jit::IonSpewHeader(IonSpewChannel channel)
399
if (!IonSpewEnabled(channel))
402
fprintf(stderr, "[%s] ", ChannelNames[channel]);
406
jit::IonSpewEnabled(IonSpewChannel channel)
408
JS_ASSERT(LoggingChecked);
409
return (LoggingBits & (1 << uint32_t(channel))) && !filteredOutCompilations;
413
jit::EnableChannel(IonSpewChannel channel)
415
JS_ASSERT(LoggingChecked);
416
LoggingBits |= (1 << uint32_t(channel));
420
jit::DisableChannel(IonSpewChannel channel)
422
JS_ASSERT(LoggingChecked);
423
LoggingBits &= ~(1 << uint32_t(channel));