~ubuntu-branches/ubuntu/vivid/mozjs24/vivid

« back to all changes in this revision

Viewing changes to js/src/jit/IonSpewer.cpp

  • Committer: Package Import Robot
  • Author(s): Tim Lunn
  • Date: 2014-02-11 21:55:34 UTC
  • Revision ID: package-import@ubuntu.com-20140211215534-m1zyq5aj59md3y07
Tags: upstream-24.2.0
ImportĀ upstreamĀ versionĀ 24.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#ifdef DEBUG
 
8
 
 
9
#include "Ion.h"
 
10
#include "IonSpewer.h"
 
11
 
 
12
#include "jsscriptinlines.h"
 
13
 
 
14
#ifndef ION_SPEW_DIR
 
15
# if defined(_WIN32)
 
16
#  define ION_SPEW_DIR ""
 
17
# elif defined(__ANDROID__)
 
18
#  define ION_SPEW_DIR "/data/local/tmp/"
 
19
# else
 
20
#  define ION_SPEW_DIR "/tmp/"
 
21
# endif
 
22
#endif
 
23
 
 
24
using namespace js;
 
25
using namespace js::jit;
 
26
 
 
27
// IonSpewer singleton.
 
28
static IonSpewer ionspewer;
 
29
 
 
30
static bool LoggingChecked = false;
 
31
static uint32_t LoggingBits = 0;
 
32
static uint32_t filteredOutCompilations = 0;
 
33
 
 
34
static const char * const ChannelNames[] =
 
35
{
 
36
#define IONSPEW_CHANNEL(name) #name,
 
37
    IONSPEW_CHANNEL_LIST(IONSPEW_CHANNEL)
 
38
#undef IONSPEW_CHANNEL
 
39
};
 
40
 
 
41
static bool
 
42
FilterContainsLocation(HandleScript function)
 
43
{
 
44
    static const char *filter = getenv("IONFILTER");
 
45
 
 
46
    // If there is no filter we accept all outputs.
 
47
    if (!filter || !filter[0])
 
48
        return true;
 
49
 
 
50
    // Disable asm.js output when filter is set.
 
51
    if (!function)
 
52
        return false;
 
53
 
 
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);
 
58
    while (index) {
 
59
        if (index == filter || index[-1] == ',') {
 
60
            if (index[filelen] == 0 || index[filelen] == ',')
 
61
                return true;
 
62
            if (index[filelen] == ':' && line != size_t(-1)) {
 
63
                size_t read_line = strtoul(&index[filelen + 1], NULL, 10);
 
64
                if (read_line == line)
 
65
                    return true;
 
66
            }
 
67
        }
 
68
        index = strstr(index + filelen, filename);
 
69
    }
 
70
    return false;
 
71
}
 
72
 
 
73
void
 
74
jit::EnableIonDebugLogging()
 
75
{
 
76
    ionspewer.init();
 
77
}
 
78
 
 
79
void
 
80
jit::IonSpewNewFunction(MIRGraph *graph, HandleScript function)
 
81
{
 
82
    if (!js_IonOptions.parallelCompilation)
 
83
        ionspewer.beginFunction(graph, function);
 
84
}
 
85
 
 
86
void
 
87
jit::IonSpewPass(const char *pass)
 
88
{
 
89
    if (!js_IonOptions.parallelCompilation)
 
90
        ionspewer.spewPass(pass);
 
91
}
 
92
 
 
93
void
 
94
jit::IonSpewPass(const char *pass, LinearScanAllocator *ra)
 
95
{
 
96
    if (!js_IonOptions.parallelCompilation)
 
97
        ionspewer.spewPass(pass, ra);
 
98
}
 
99
 
 
100
void
 
101
jit::IonSpewEndFunction()
 
102
{
 
103
    if (!js_IonOptions.parallelCompilation)
 
104
        ionspewer.endFunction();
 
105
}
 
106
 
 
107
 
 
108
IonSpewer::~IonSpewer()
 
109
{
 
110
    if (!inited_)
 
111
        return;
 
112
 
 
113
    c1Spewer.finish();
 
114
    jsonSpewer.finish();
 
115
}
 
116
 
 
117
bool
 
118
IonSpewer::init()
 
119
{
 
120
    if (inited_)
 
121
        return true;
 
122
 
 
123
    if (!c1Spewer.init(ION_SPEW_DIR "ion.cfg"))
 
124
        return false;
 
125
    if (!jsonSpewer.init(ION_SPEW_DIR "ion.json"))
 
126
        return false;
 
127
 
 
128
    inited_ = true;
 
129
    return true;
 
130
}
 
131
 
 
132
bool
 
133
IonSpewer::isSpewingFunction() const
 
134
{
 
135
    return inited_ && graph;
 
136
}
 
137
 
 
138
void
 
139
IonSpewer::beginFunction(MIRGraph *graph, HandleScript function)
 
140
{
 
141
    if (!inited_)
 
142
        return;
 
143
 
 
144
    if (!FilterContainsLocation(function)) {
 
145
        JS_ASSERT(!this->graph);
 
146
        // filter out logs during the compilation.
 
147
        filteredOutCompilations++;
 
148
        return;
 
149
    }
 
150
 
 
151
    this->graph = graph;
 
152
    this->function = function;
 
153
 
 
154
    c1Spewer.beginFunction(graph, function);
 
155
    jsonSpewer.beginFunction(function);
 
156
}
 
157
 
 
158
void
 
159
IonSpewer::spewPass(const char *pass)
 
160
{
 
161
    if (!isSpewingFunction())
 
162
        return;
 
163
 
 
164
    c1Spewer.spewPass(pass);
 
165
    jsonSpewer.beginPass(pass);
 
166
    jsonSpewer.spewMIR(graph);
 
167
    jsonSpewer.spewLIR(graph);
 
168
    jsonSpewer.endPass();
 
169
}
 
170
 
 
171
void
 
172
IonSpewer::spewPass(const char *pass, LinearScanAllocator *ra)
 
173
{
 
174
    if (!isSpewingFunction())
 
175
        return;
 
176
 
 
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();
 
184
}
 
185
 
 
186
void
 
187
IonSpewer::endFunction()
 
188
{
 
189
    if (!isSpewingFunction()) {
 
190
        filteredOutCompilations--;
 
191
        return;
 
192
    }
 
193
 
 
194
    c1Spewer.endFunction();
 
195
    jsonSpewer.endFunction();
 
196
 
 
197
    this->graph = NULL;
 
198
}
 
199
 
 
200
 
 
201
FILE *jit::IonSpewFile = NULL;
 
202
 
 
203
static bool
 
204
ContainsFlag(const char *str, const char *flag)
 
205
{
 
206
    size_t flaglen = strlen(flag);
 
207
    const char *index = strstr(str, flag);
 
208
    while (index) {
 
209
        if ((index == str || index[-1] == ',') && (index[flaglen] == 0 || index[flaglen] == ','))
 
210
            return true;
 
211
        index = strstr(index + flaglen, flag);
 
212
    }
 
213
    return false;
 
214
}
 
215
 
 
216
void
 
217
jit::CheckLogging()
 
218
{
 
219
    if (LoggingChecked)
 
220
        return;
 
221
    LoggingChecked = true;
 
222
    const char *env = getenv("IONFLAGS");
 
223
    if (!env)
 
224
        return;
 
225
    if (strstr(env, "help")) {
 
226
        fflush(NULL);
 
227
        printf(
 
228
            "\n"
 
229
            "usage: IONFLAGS=option,option,option,... where options can be:\n"
 
230
            "\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"
 
238
            "  inline     Inlining\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"
 
249
            "  all        Everything\n"
 
250
            "\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"
 
259
            "\n"
 
260
        );
 
261
        exit(0);
 
262
        /*NOTREACHED*/
 
263
    }
 
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);
 
304
 
 
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);
 
327
    }
 
328
 
 
329
    if (LoggingBits != 0)
 
330
        EnableIonDebugLogging();
 
331
 
 
332
    IonSpewFile = stderr;
 
333
}
 
334
 
 
335
void
 
336
jit::IonSpewStartVA(IonSpewChannel channel, const char *fmt, va_list ap)
 
337
{
 
338
    if (!IonSpewEnabled(channel))
 
339
        return;
 
340
 
 
341
    IonSpewHeader(channel);
 
342
    vfprintf(stderr, fmt, ap);
 
343
}
 
344
 
 
345
void
 
346
jit::IonSpewContVA(IonSpewChannel channel, const char *fmt, va_list ap)
 
347
{
 
348
    if (!IonSpewEnabled(channel))
 
349
        return;
 
350
 
 
351
    vfprintf(stderr, fmt, ap);
 
352
}
 
353
 
 
354
void
 
355
jit::IonSpewFin(IonSpewChannel channel)
 
356
{
 
357
    if (!IonSpewEnabled(channel))
 
358
        return;
 
359
 
 
360
    fprintf(stderr, "\n");
 
361
}
 
362
 
 
363
void
 
364
jit::IonSpewVA(IonSpewChannel channel, const char *fmt, va_list ap)
 
365
{
 
366
    IonSpewStartVA(channel, fmt, ap);
 
367
    IonSpewFin(channel);
 
368
}
 
369
 
 
370
void
 
371
jit::IonSpew(IonSpewChannel channel, const char *fmt, ...)
 
372
{
 
373
    va_list ap;
 
374
    va_start(ap, fmt);
 
375
    IonSpewVA(channel, fmt, ap);
 
376
    va_end(ap);
 
377
}
 
378
 
 
379
void
 
380
jit::IonSpewStart(IonSpewChannel channel, const char *fmt, ...)
 
381
{
 
382
    va_list ap;
 
383
    va_start(ap, fmt);
 
384
    IonSpewStartVA(channel, fmt, ap);
 
385
    va_end(ap);
 
386
}
 
387
void
 
388
jit::IonSpewCont(IonSpewChannel channel, const char *fmt, ...)
 
389
{
 
390
    va_list ap;
 
391
    va_start(ap, fmt);
 
392
    IonSpewContVA(channel, fmt, ap);
 
393
    va_end(ap);
 
394
}
 
395
 
 
396
void
 
397
jit::IonSpewHeader(IonSpewChannel channel)
 
398
{
 
399
    if (!IonSpewEnabled(channel))
 
400
        return;
 
401
 
 
402
    fprintf(stderr, "[%s] ", ChannelNames[channel]);
 
403
}
 
404
 
 
405
bool
 
406
jit::IonSpewEnabled(IonSpewChannel channel)
 
407
{
 
408
    JS_ASSERT(LoggingChecked);
 
409
    return (LoggingBits & (1 << uint32_t(channel))) && !filteredOutCompilations;
 
410
}
 
411
 
 
412
void
 
413
jit::EnableChannel(IonSpewChannel channel)
 
414
{
 
415
    JS_ASSERT(LoggingChecked);
 
416
    LoggingBits |= (1 << uint32_t(channel));
 
417
}
 
418
 
 
419
void
 
420
jit::DisableChannel(IonSpewChannel channel)
 
421
{
 
422
    JS_ASSERT(LoggingChecked);
 
423
    LoggingBits &= ~(1 << uint32_t(channel));
 
424
}
 
425
 
 
426
#endif /* DEBUG */
 
427