js/src/jit/IonSpewer.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
michael@0 2 * vim: set ts=8 sts=4 et sw=4 tw=99:
michael@0 3 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #ifdef DEBUG
michael@0 8
michael@0 9 #include "jit/IonSpewer.h"
michael@0 10
michael@0 11 #include "jsworkers.h"
michael@0 12
michael@0 13 #include "jit/Ion.h"
michael@0 14
michael@0 15 #ifndef ION_SPEW_DIR
michael@0 16 # if defined(_WIN32)
michael@0 17 # define ION_SPEW_DIR ""
michael@0 18 # elif defined(__ANDROID__)
michael@0 19 # define ION_SPEW_DIR "/data/local/tmp/"
michael@0 20 # else
michael@0 21 # define ION_SPEW_DIR "/tmp/"
michael@0 22 # endif
michael@0 23 #endif
michael@0 24
michael@0 25 using namespace js;
michael@0 26 using namespace js::jit;
michael@0 27
michael@0 28 // IonSpewer singleton.
michael@0 29 static IonSpewer ionspewer;
michael@0 30
michael@0 31 static bool LoggingChecked = false;
michael@0 32 static uint32_t LoggingBits = 0;
michael@0 33 static uint32_t filteredOutCompilations = 0;
michael@0 34
michael@0 35 static const char * const ChannelNames[] =
michael@0 36 {
michael@0 37 #define IONSPEW_CHANNEL(name) #name,
michael@0 38 IONSPEW_CHANNEL_LIST(IONSPEW_CHANNEL)
michael@0 39 #undef IONSPEW_CHANNEL
michael@0 40 };
michael@0 41
michael@0 42 static bool
michael@0 43 FilterContainsLocation(HandleScript function)
michael@0 44 {
michael@0 45 static const char *filter = getenv("IONFILTER");
michael@0 46
michael@0 47 // If there is no filter we accept all outputs.
michael@0 48 if (!filter || !filter[0])
michael@0 49 return true;
michael@0 50
michael@0 51 // Disable asm.js output when filter is set.
michael@0 52 if (!function)
michael@0 53 return false;
michael@0 54
michael@0 55 const char *filename = function->filename();
michael@0 56 const size_t line = function->lineno();
michael@0 57 const size_t filelen = strlen(filename);
michael@0 58 const char *index = strstr(filter, filename);
michael@0 59 while (index) {
michael@0 60 if (index == filter || index[-1] == ',') {
michael@0 61 if (index[filelen] == 0 || index[filelen] == ',')
michael@0 62 return true;
michael@0 63 if (index[filelen] == ':' && line != size_t(-1)) {
michael@0 64 size_t read_line = strtoul(&index[filelen + 1], nullptr, 10);
michael@0 65 if (read_line == line)
michael@0 66 return true;
michael@0 67 }
michael@0 68 }
michael@0 69 index = strstr(index + filelen, filename);
michael@0 70 }
michael@0 71 return false;
michael@0 72 }
michael@0 73
michael@0 74 void
michael@0 75 jit::EnableIonDebugLogging()
michael@0 76 {
michael@0 77 EnableChannel(IonSpew_Logs);
michael@0 78 ionspewer.init();
michael@0 79 }
michael@0 80
michael@0 81 void
michael@0 82 jit::IonSpewNewFunction(MIRGraph *graph, HandleScript func)
michael@0 83 {
michael@0 84 if (GetIonContext()->runtime->onMainThread())
michael@0 85 ionspewer.beginFunction(graph, func);
michael@0 86 }
michael@0 87
michael@0 88 void
michael@0 89 jit::IonSpewPass(const char *pass)
michael@0 90 {
michael@0 91 if (GetIonContext()->runtime->onMainThread())
michael@0 92 ionspewer.spewPass(pass);
michael@0 93 }
michael@0 94
michael@0 95 void
michael@0 96 jit::IonSpewPass(const char *pass, LinearScanAllocator *ra)
michael@0 97 {
michael@0 98 if (GetIonContext()->runtime->onMainThread())
michael@0 99 ionspewer.spewPass(pass, ra);
michael@0 100 }
michael@0 101
michael@0 102 void
michael@0 103 jit::IonSpewEndFunction()
michael@0 104 {
michael@0 105 if (GetIonContext()->runtime->onMainThread())
michael@0 106 ionspewer.endFunction();
michael@0 107 }
michael@0 108
michael@0 109
michael@0 110 IonSpewer::~IonSpewer()
michael@0 111 {
michael@0 112 if (!inited_)
michael@0 113 return;
michael@0 114
michael@0 115 c1Spewer.finish();
michael@0 116 jsonSpewer.finish();
michael@0 117 }
michael@0 118
michael@0 119 bool
michael@0 120 IonSpewer::init()
michael@0 121 {
michael@0 122 if (inited_)
michael@0 123 return true;
michael@0 124
michael@0 125 if (!c1Spewer.init(ION_SPEW_DIR "ion.cfg"))
michael@0 126 return false;
michael@0 127 if (!jsonSpewer.init(ION_SPEW_DIR "ion.json"))
michael@0 128 return false;
michael@0 129
michael@0 130 inited_ = true;
michael@0 131 return true;
michael@0 132 }
michael@0 133
michael@0 134 bool
michael@0 135 IonSpewer::isSpewingFunction() const
michael@0 136 {
michael@0 137 return inited_ && graph;
michael@0 138 }
michael@0 139
michael@0 140 void
michael@0 141 IonSpewer::beginFunction(MIRGraph *graph, HandleScript function)
michael@0 142 {
michael@0 143 if (!inited_)
michael@0 144 return;
michael@0 145
michael@0 146 if (!FilterContainsLocation(function)) {
michael@0 147 JS_ASSERT(!this->graph);
michael@0 148 // filter out logs during the compilation.
michael@0 149 filteredOutCompilations++;
michael@0 150 return;
michael@0 151 }
michael@0 152
michael@0 153 this->graph = graph;
michael@0 154 this->function.repoint(function);
michael@0 155
michael@0 156 c1Spewer.beginFunction(graph, function);
michael@0 157 jsonSpewer.beginFunction(function);
michael@0 158 }
michael@0 159
michael@0 160 void
michael@0 161 IonSpewer::spewPass(const char *pass)
michael@0 162 {
michael@0 163 if (!isSpewingFunction())
michael@0 164 return;
michael@0 165
michael@0 166 c1Spewer.spewPass(pass);
michael@0 167 jsonSpewer.beginPass(pass);
michael@0 168 jsonSpewer.spewMIR(graph);
michael@0 169 jsonSpewer.spewLIR(graph);
michael@0 170 jsonSpewer.endPass();
michael@0 171 }
michael@0 172
michael@0 173 void
michael@0 174 IonSpewer::spewPass(const char *pass, LinearScanAllocator *ra)
michael@0 175 {
michael@0 176 if (!isSpewingFunction())
michael@0 177 return;
michael@0 178
michael@0 179 c1Spewer.spewPass(pass);
michael@0 180 c1Spewer.spewIntervals(pass, ra);
michael@0 181 jsonSpewer.beginPass(pass);
michael@0 182 jsonSpewer.spewMIR(graph);
michael@0 183 jsonSpewer.spewLIR(graph);
michael@0 184 jsonSpewer.spewIntervals(ra);
michael@0 185 jsonSpewer.endPass();
michael@0 186 }
michael@0 187
michael@0 188 void
michael@0 189 IonSpewer::endFunction()
michael@0 190 {
michael@0 191 if (!isSpewingFunction()) {
michael@0 192 if (inited_) {
michael@0 193 JS_ASSERT(filteredOutCompilations != 0);
michael@0 194 filteredOutCompilations--;
michael@0 195 }
michael@0 196 return;
michael@0 197 }
michael@0 198
michael@0 199 c1Spewer.endFunction();
michael@0 200 jsonSpewer.endFunction();
michael@0 201
michael@0 202 this->graph = nullptr;
michael@0 203 }
michael@0 204
michael@0 205
michael@0 206 FILE *jit::IonSpewFile = nullptr;
michael@0 207
michael@0 208 static bool
michael@0 209 ContainsFlag(const char *str, const char *flag)
michael@0 210 {
michael@0 211 size_t flaglen = strlen(flag);
michael@0 212 const char *index = strstr(str, flag);
michael@0 213 while (index) {
michael@0 214 if ((index == str || index[-1] == ',') && (index[flaglen] == 0 || index[flaglen] == ','))
michael@0 215 return true;
michael@0 216 index = strstr(index + flaglen, flag);
michael@0 217 }
michael@0 218 return false;
michael@0 219 }
michael@0 220
michael@0 221 void
michael@0 222 jit::CheckLogging()
michael@0 223 {
michael@0 224 if (LoggingChecked)
michael@0 225 return;
michael@0 226 LoggingChecked = true;
michael@0 227 const char *env = getenv("IONFLAGS");
michael@0 228 if (!env)
michael@0 229 return;
michael@0 230 if (strstr(env, "help")) {
michael@0 231 fflush(nullptr);
michael@0 232 printf(
michael@0 233 "\n"
michael@0 234 "usage: IONFLAGS=option,option,option,... where options can be:\n"
michael@0 235 "\n"
michael@0 236 " aborts Compilation abort messages\n"
michael@0 237 " scripts Compiled scripts\n"
michael@0 238 " mir MIR information\n"
michael@0 239 " alias Alias analysis\n"
michael@0 240 " gvn Global Value Numbering\n"
michael@0 241 " licm Loop invariant code motion\n"
michael@0 242 " regalloc Register allocation\n"
michael@0 243 " inline Inlining\n"
michael@0 244 " snapshots Snapshot information\n"
michael@0 245 " codegen Native code generation\n"
michael@0 246 " bailouts Bailouts\n"
michael@0 247 " caches Inline caches\n"
michael@0 248 " osi Invalidation\n"
michael@0 249 " safepoints Safepoints\n"
michael@0 250 " pools Literal Pools (ARM only for now)\n"
michael@0 251 " cacheflush Instruction Cache flushes (ARM only for now)\n"
michael@0 252 " range Range Analysis\n"
michael@0 253 " logs C1 and JSON visualization logging\n"
michael@0 254 " trace Generate calls to js::jit::Trace() for effectful instructions\n"
michael@0 255 " all Everything\n"
michael@0 256 "\n"
michael@0 257 " bl-aborts Baseline compiler abort messages\n"
michael@0 258 " bl-scripts Baseline script-compilation\n"
michael@0 259 " bl-op Baseline compiler detailed op-specific messages\n"
michael@0 260 " bl-ic Baseline inline-cache messages\n"
michael@0 261 " bl-ic-fb Baseline IC fallback stub messages\n"
michael@0 262 " bl-osr Baseline IC OSR messages\n"
michael@0 263 " bl-bails Baseline bailouts\n"
michael@0 264 " bl-dbg-osr Baseline debug mode on stack recompile messages\n"
michael@0 265 " bl-all All baseline spew\n"
michael@0 266 "\n"
michael@0 267 );
michael@0 268 exit(0);
michael@0 269 /*NOTREACHED*/
michael@0 270 }
michael@0 271 if (ContainsFlag(env, "aborts"))
michael@0 272 EnableChannel(IonSpew_Abort);
michael@0 273 if (ContainsFlag(env, "alias"))
michael@0 274 EnableChannel(IonSpew_Alias);
michael@0 275 if (ContainsFlag(env, "scripts"))
michael@0 276 EnableChannel(IonSpew_Scripts);
michael@0 277 if (ContainsFlag(env, "mir"))
michael@0 278 EnableChannel(IonSpew_MIR);
michael@0 279 if (ContainsFlag(env, "gvn"))
michael@0 280 EnableChannel(IonSpew_GVN);
michael@0 281 if (ContainsFlag(env, "range"))
michael@0 282 EnableChannel(IonSpew_Range);
michael@0 283 if (ContainsFlag(env, "licm"))
michael@0 284 EnableChannel(IonSpew_LICM);
michael@0 285 if (ContainsFlag(env, "regalloc"))
michael@0 286 EnableChannel(IonSpew_RegAlloc);
michael@0 287 if (ContainsFlag(env, "inline"))
michael@0 288 EnableChannel(IonSpew_Inlining);
michael@0 289 if (ContainsFlag(env, "snapshots"))
michael@0 290 EnableChannel(IonSpew_Snapshots);
michael@0 291 if (ContainsFlag(env, "codegen"))
michael@0 292 EnableChannel(IonSpew_Codegen);
michael@0 293 if (ContainsFlag(env, "bailouts"))
michael@0 294 EnableChannel(IonSpew_Bailouts);
michael@0 295 if (ContainsFlag(env, "osi"))
michael@0 296 EnableChannel(IonSpew_Invalidate);
michael@0 297 if (ContainsFlag(env, "caches"))
michael@0 298 EnableChannel(IonSpew_InlineCaches);
michael@0 299 if (ContainsFlag(env, "safepoints"))
michael@0 300 EnableChannel(IonSpew_Safepoints);
michael@0 301 if (ContainsFlag(env, "pools"))
michael@0 302 EnableChannel(IonSpew_Pools);
michael@0 303 if (ContainsFlag(env, "cacheflush"))
michael@0 304 EnableChannel(IonSpew_CacheFlush);
michael@0 305 if (ContainsFlag(env, "logs"))
michael@0 306 EnableIonDebugLogging();
michael@0 307 if (ContainsFlag(env, "trace"))
michael@0 308 EnableChannel(IonSpew_Trace);
michael@0 309 if (ContainsFlag(env, "all"))
michael@0 310 LoggingBits = uint32_t(-1);
michael@0 311
michael@0 312 if (ContainsFlag(env, "bl-aborts"))
michael@0 313 EnableChannel(IonSpew_BaselineAbort);
michael@0 314 if (ContainsFlag(env, "bl-scripts"))
michael@0 315 EnableChannel(IonSpew_BaselineScripts);
michael@0 316 if (ContainsFlag(env, "bl-op"))
michael@0 317 EnableChannel(IonSpew_BaselineOp);
michael@0 318 if (ContainsFlag(env, "bl-ic"))
michael@0 319 EnableChannel(IonSpew_BaselineIC);
michael@0 320 if (ContainsFlag(env, "bl-ic-fb"))
michael@0 321 EnableChannel(IonSpew_BaselineICFallback);
michael@0 322 if (ContainsFlag(env, "bl-osr"))
michael@0 323 EnableChannel(IonSpew_BaselineOSR);
michael@0 324 if (ContainsFlag(env, "bl-bails"))
michael@0 325 EnableChannel(IonSpew_BaselineBailouts);
michael@0 326 if (ContainsFlag(env, "bl-dbg-osr"))
michael@0 327 EnableChannel(IonSpew_BaselineDebugModeOSR);
michael@0 328 if (ContainsFlag(env, "bl-all")) {
michael@0 329 EnableChannel(IonSpew_BaselineAbort);
michael@0 330 EnableChannel(IonSpew_BaselineScripts);
michael@0 331 EnableChannel(IonSpew_BaselineOp);
michael@0 332 EnableChannel(IonSpew_BaselineIC);
michael@0 333 EnableChannel(IonSpew_BaselineICFallback);
michael@0 334 EnableChannel(IonSpew_BaselineOSR);
michael@0 335 EnableChannel(IonSpew_BaselineBailouts);
michael@0 336 EnableChannel(IonSpew_BaselineDebugModeOSR);
michael@0 337 }
michael@0 338
michael@0 339 IonSpewFile = stderr;
michael@0 340 }
michael@0 341
michael@0 342 void
michael@0 343 jit::IonSpewStartVA(IonSpewChannel channel, const char *fmt, va_list ap)
michael@0 344 {
michael@0 345 if (!IonSpewEnabled(channel))
michael@0 346 return;
michael@0 347
michael@0 348 IonSpewHeader(channel);
michael@0 349 vfprintf(stderr, fmt, ap);
michael@0 350 }
michael@0 351
michael@0 352 void
michael@0 353 jit::IonSpewContVA(IonSpewChannel channel, const char *fmt, va_list ap)
michael@0 354 {
michael@0 355 if (!IonSpewEnabled(channel))
michael@0 356 return;
michael@0 357
michael@0 358 vfprintf(stderr, fmt, ap);
michael@0 359 }
michael@0 360
michael@0 361 void
michael@0 362 jit::IonSpewFin(IonSpewChannel channel)
michael@0 363 {
michael@0 364 if (!IonSpewEnabled(channel))
michael@0 365 return;
michael@0 366
michael@0 367 fprintf(stderr, "\n");
michael@0 368 }
michael@0 369
michael@0 370 void
michael@0 371 jit::IonSpewVA(IonSpewChannel channel, const char *fmt, va_list ap)
michael@0 372 {
michael@0 373 IonSpewStartVA(channel, fmt, ap);
michael@0 374 IonSpewFin(channel);
michael@0 375 }
michael@0 376
michael@0 377 void
michael@0 378 jit::IonSpew(IonSpewChannel channel, const char *fmt, ...)
michael@0 379 {
michael@0 380 va_list ap;
michael@0 381 va_start(ap, fmt);
michael@0 382 IonSpewVA(channel, fmt, ap);
michael@0 383 va_end(ap);
michael@0 384 }
michael@0 385
michael@0 386 void
michael@0 387 jit::IonSpewStart(IonSpewChannel channel, const char *fmt, ...)
michael@0 388 {
michael@0 389 va_list ap;
michael@0 390 va_start(ap, fmt);
michael@0 391 IonSpewStartVA(channel, fmt, ap);
michael@0 392 va_end(ap);
michael@0 393 }
michael@0 394 void
michael@0 395 jit::IonSpewCont(IonSpewChannel channel, const char *fmt, ...)
michael@0 396 {
michael@0 397 va_list ap;
michael@0 398 va_start(ap, fmt);
michael@0 399 IonSpewContVA(channel, fmt, ap);
michael@0 400 va_end(ap);
michael@0 401 }
michael@0 402
michael@0 403 void
michael@0 404 jit::IonSpewHeader(IonSpewChannel channel)
michael@0 405 {
michael@0 406 if (!IonSpewEnabled(channel))
michael@0 407 return;
michael@0 408
michael@0 409 fprintf(stderr, "[%s] ", ChannelNames[channel]);
michael@0 410 }
michael@0 411
michael@0 412 bool
michael@0 413 jit::IonSpewEnabled(IonSpewChannel channel)
michael@0 414 {
michael@0 415 JS_ASSERT(LoggingChecked);
michael@0 416 return (LoggingBits & (1 << uint32_t(channel))) && !filteredOutCompilations;
michael@0 417 }
michael@0 418
michael@0 419 void
michael@0 420 jit::EnableChannel(IonSpewChannel channel)
michael@0 421 {
michael@0 422 JS_ASSERT(LoggingChecked);
michael@0 423 LoggingBits |= (1 << uint32_t(channel));
michael@0 424 }
michael@0 425
michael@0 426 void
michael@0 427 jit::DisableChannel(IonSpewChannel channel)
michael@0 428 {
michael@0 429 JS_ASSERT(LoggingChecked);
michael@0 430 LoggingBits &= ~(1 << uint32_t(channel));
michael@0 431 }
michael@0 432
michael@0 433 #endif /* DEBUG */
michael@0 434

mercurial