LCOV - code coverage report
Current view: top level - js/src/jit - JitSpewer.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 78 353 22.1 %
Date: 2017-07-14 16:53:18 Functions: 21 39 53.8 %
Legend: Lines: hit not hit

          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             : #ifdef JS_JITSPEW
       8             : 
       9             : #include "jit/JitSpewer.h"
      10             : 
      11             : #include "mozilla/Atomics.h"
      12             : 
      13             : #ifdef XP_WIN
      14             : #include <process.h>
      15             : #define getpid _getpid
      16             : #else
      17             : #include <unistd.h>
      18             : #endif
      19             : 
      20             : #include "jsprf.h"
      21             : 
      22             : #include "jit/Ion.h"
      23             : #include "jit/MIR.h"
      24             : #include "jit/MIRGenerator.h"
      25             : #include "jit/MIRGraph.h"
      26             : 
      27             : #include "threading/LockGuard.h"
      28             : 
      29             : #include "vm/HelperThreads.h"
      30             : #include "vm/MutexIDs.h"
      31             : 
      32             : #include "jscompartmentinlines.h"
      33             : 
      34             : #ifndef JIT_SPEW_DIR
      35             : # if defined(_WIN32)
      36             : #  define JIT_SPEW_DIR "."
      37             : # elif defined(__ANDROID__)
      38             : #  define JIT_SPEW_DIR "/data/local/tmp"
      39             : # else
      40             : #  define JIT_SPEW_DIR "/tmp"
      41             : # endif
      42             : #endif
      43             : 
      44             : using namespace js;
      45             : using namespace js::jit;
      46             : 
      47             : class IonSpewer
      48             : {
      49             :   private:
      50             :     Mutex outputLock_;
      51             :     Fprinter c1Output_;
      52             :     Fprinter jsonOutput_;
      53             :     bool firstFunction_;
      54             :     bool asyncLogging_;
      55             :     bool inited_;
      56             : 
      57             :     void release();
      58             : 
      59             :   public:
      60           3 :     IonSpewer()
      61           3 :       : outputLock_(mutexid::IonSpewer),
      62             :         firstFunction_(false),
      63             :         asyncLogging_(false),
      64           3 :         inited_(false)
      65           3 :     { }
      66             : 
      67             :     // File output is terminated safely upon destruction.
      68             :     ~IonSpewer();
      69             : 
      70             :     bool init();
      71          20 :     bool isEnabled() {
      72          20 :         return inited_;
      73             :     }
      74           0 :     void setAsyncLogging(bool incremental) {
      75           0 :         asyncLogging_ = incremental;
      76           0 :     }
      77           0 :     bool getAsyncLogging() {
      78           0 :         return asyncLogging_;
      79             :     }
      80             : 
      81             :     void beginFunction();
      82             :     void spewPass(GraphSpewer* gs);
      83             :     void endFunction(GraphSpewer* gs);
      84             : };
      85             : 
      86             : // IonSpewer singleton.
      87           3 : static IonSpewer ionspewer;
      88             : 
      89             : static bool LoggingChecked = false;
      90             : static_assert(JitSpew_Terminator <= 64, "Increase the size of the LoggingBits global.");
      91             : static uint64_t LoggingBits = 0;
      92             : static mozilla::Atomic<uint32_t, mozilla::Relaxed> filteredOutCompilations(0);
      93             : 
      94             : static const char * const ChannelNames[] =
      95             : {
      96             : #define JITSPEW_CHANNEL(name) #name,
      97             :     JITSPEW_CHANNEL_LIST(JITSPEW_CHANNEL)
      98             : #undef JITSPEW_CHANNEL
      99             : };
     100             : 
     101             : static size_t ChannelIndentLevel[] =
     102             : {
     103             : #define JITSPEW_CHANNEL(name) 0,
     104             :     JITSPEW_CHANNEL_LIST(JITSPEW_CHANNEL)
     105             : #undef JITSPEW_CHANNEL
     106             : };
     107             : 
     108             : static bool
     109           0 : FilterContainsLocation(JSScript* function)
     110             : {
     111           0 :     static const char* filter = getenv("IONFILTER");
     112             : 
     113             :     // If there is no filter we accept all outputs.
     114           0 :     if (!filter || !filter[0])
     115           0 :         return true;
     116             : 
     117             :     // Disable wasm output when filter is set.
     118           0 :     if (!function)
     119           0 :         return false;
     120             : 
     121           0 :     const char* filename = function->filename();
     122           0 :     const size_t line = function->lineno();
     123           0 :     const size_t filelen = strlen(filename);
     124           0 :     const char* index = strstr(filter, filename);
     125           0 :     while (index) {
     126           0 :         if (index == filter || index[-1] == ',') {
     127           0 :             if (index[filelen] == 0 || index[filelen] == ',')
     128           0 :                 return true;
     129           0 :             if (index[filelen] == ':' && line != size_t(-1)) {
     130           0 :                 size_t read_line = strtoul(&index[filelen + 1], nullptr, 10);
     131           0 :                 if (read_line == line)
     132           0 :                     return true;
     133             :             }
     134             :         }
     135           0 :         index = strstr(index + filelen, filename);
     136             :     }
     137           0 :     return false;
     138             : }
     139             : 
     140             : void
     141           0 : jit::EnableIonDebugSyncLogging()
     142             : {
     143           0 :     ionspewer.init();
     144           0 :     ionspewer.setAsyncLogging(false);
     145           0 :     EnableChannel(JitSpew_IonSyncLogs);
     146           0 : }
     147             : 
     148             : void
     149           0 : jit::EnableIonDebugAsyncLogging()
     150             : {
     151           0 :     ionspewer.init();
     152           0 :     ionspewer.setAsyncLogging(true);
     153           0 : }
     154             : 
     155             : void
     156           0 : IonSpewer::release()
     157             : {
     158           0 :     if (c1Output_.isInitialized())
     159           0 :         c1Output_.finish();
     160           0 :     if (jsonOutput_.isInitialized())
     161           0 :         jsonOutput_.finish();
     162           0 :     inited_ = false;
     163           0 : }
     164             : 
     165             : bool
     166           0 : IonSpewer::init()
     167             : {
     168           0 :     if (inited_)
     169           0 :         return true;
     170             : 
     171           0 :     const size_t bufferLength = 256;
     172             :     char c1Buffer[bufferLength];
     173             :     char jsonBuffer[bufferLength];
     174           0 :     const char *c1Filename = JIT_SPEW_DIR "/ion.cfg";
     175           0 :     const char *jsonFilename = JIT_SPEW_DIR "/ion.json";
     176             : 
     177           0 :     const char* usePid = getenv("ION_SPEW_BY_PID");
     178           0 :     if (usePid && *usePid != 0) {
     179           0 :         uint32_t pid = getpid();
     180             :         size_t len;
     181           0 :         len = snprintf(jsonBuffer, bufferLength, JIT_SPEW_DIR "/ion%" PRIu32 ".json", pid);
     182           0 :         if (bufferLength <= len) {
     183           0 :             fprintf(stderr, "Warning: IonSpewer::init: Cannot serialize file name.");
     184           0 :             return false;
     185             :         }
     186           0 :         jsonFilename = jsonBuffer;
     187             : 
     188           0 :         len = snprintf(c1Buffer, bufferLength, JIT_SPEW_DIR "/ion%" PRIu32 ".cfg", pid);
     189           0 :         if (bufferLength <= len) {
     190           0 :             fprintf(stderr, "Warning: IonSpewer::init: Cannot serialize file name.");
     191           0 :             return false;
     192             :         }
     193           0 :         c1Filename = c1Buffer;
     194             :     }
     195             : 
     196           0 :     if (!c1Output_.init(c1Filename) ||
     197           0 :         !jsonOutput_.init(jsonFilename))
     198             :     {
     199           0 :         release();
     200           0 :         return false;
     201             :     }
     202             : 
     203           0 :     jsonOutput_.printf("{\n  \"functions\": [\n");
     204           0 :     firstFunction_ = true;
     205             : 
     206           0 :     inited_ = true;
     207           0 :     return true;
     208             : }
     209             : 
     210             : void
     211           0 : IonSpewer::beginFunction()
     212             : {
     213             :     // If we are doing a synchronous logging then we spew everything as we go,
     214             :     // as this is useful in case of failure during the compilation. On the other
     215             :     // hand, it is recommended to disable off thread compilation.
     216           0 :     if (!getAsyncLogging() && !firstFunction_) {
     217           0 :         LockGuard<Mutex> guard(outputLock_);
     218           0 :         jsonOutput_.put(","); // separate functions
     219             :     }
     220           0 : }
     221             : 
     222             : void
     223           0 : IonSpewer::spewPass(GraphSpewer* gs)
     224             : {
     225           0 :     if (!getAsyncLogging()) {
     226           0 :         LockGuard<Mutex> guard(outputLock_);
     227           0 :         gs->dump(c1Output_, jsonOutput_);
     228             :     }
     229           0 : }
     230             : 
     231             : void
     232           0 : IonSpewer::endFunction(GraphSpewer* gs)
     233             : {
     234           0 :     LockGuard<Mutex> guard(outputLock_);
     235           0 :     if (getAsyncLogging() && !firstFunction_)
     236           0 :         jsonOutput_.put(","); // separate functions
     237             : 
     238           0 :     gs->dump(c1Output_, jsonOutput_);
     239           0 :     firstFunction_ = false;
     240           0 : }
     241             : 
     242           0 : IonSpewer::~IonSpewer()
     243             : {
     244           0 :     if (!inited_)
     245           0 :         return;
     246             : 
     247           0 :     jsonOutput_.printf("\n]}\n");
     248           0 :     release();
     249           0 : }
     250             : 
     251         179 : GraphSpewer::GraphSpewer(TempAllocator *alloc)
     252             :   : graph_(nullptr),
     253             :     c1Printer_(alloc->lifoAlloc()),
     254             :     jsonPrinter_(alloc->lifoAlloc()),
     255             :     c1Spewer_(c1Printer_),
     256         179 :     jsonSpewer_(jsonPrinter_)
     257             : {
     258         179 : }
     259             : 
     260             : void
     261          10 : GraphSpewer::init(MIRGraph* graph, JSScript* function)
     262             : {
     263          10 :     MOZ_ASSERT(!isSpewing());
     264          10 :     if (!ionspewer.isEnabled())
     265          10 :         return;
     266             : 
     267           0 :     if (!FilterContainsLocation(function)) {
     268             :         // filter out logs during the compilation.
     269           0 :         filteredOutCompilations++;
     270           0 :         MOZ_ASSERT(!isSpewing());
     271           0 :         return;
     272             :     }
     273             : 
     274           0 :     graph_ = graph;
     275           0 :     MOZ_ASSERT(isSpewing());
     276             : }
     277             : 
     278             : void
     279          10 : GraphSpewer::beginFunction(JSScript* function)
     280             : {
     281          10 :     if (!isSpewing())
     282          10 :         return;
     283             : 
     284           0 :     c1Spewer_.beginFunction(graph_, function);
     285           0 :     jsonSpewer_.beginFunction(function);
     286             : 
     287           0 :     ionspewer.beginFunction();
     288             : }
     289             : 
     290             : void
     291         240 : GraphSpewer::spewPass(const char* pass)
     292             : {
     293         240 :     if (!isSpewing())
     294         240 :         return;
     295             : 
     296           0 :     c1Spewer_.spewPass(pass);
     297             : 
     298           0 :     jsonSpewer_.beginPass(pass);
     299           0 :     jsonSpewer_.spewMIR(graph_);
     300           0 :     jsonSpewer_.spewLIR(graph_);
     301           0 :     jsonSpewer_.endPass();
     302             : 
     303           0 :     ionspewer.spewPass(this);
     304             : 
     305             :     // As this function is used for debugging, we ignore any of the previous
     306             :     // failures and ensure there is enough ballast space, such that we do not
     307             :     // exhaust the ballast space before running the next phase.
     308           0 :     AutoEnterOOMUnsafeRegion oomUnsafe;
     309           0 :     if (!graph_->alloc().ensureBallast())
     310           0 :         oomUnsafe.crash("Could not ensure enough ballast space after spewing graph information.");
     311             : }
     312             : 
     313             : void
     314           0 : GraphSpewer::spewPass(const char* pass, BacktrackingAllocator* ra)
     315             : {
     316           0 :     if (!isSpewing())
     317           0 :         return;
     318             : 
     319           0 :     c1Spewer_.spewPass(pass);
     320           0 :     c1Spewer_.spewRanges(pass, ra);
     321             : 
     322           0 :     jsonSpewer_.beginPass(pass);
     323           0 :     jsonSpewer_.spewMIR(graph_);
     324           0 :     jsonSpewer_.spewLIR(graph_);
     325           0 :     jsonSpewer_.spewRanges(ra);
     326           0 :     jsonSpewer_.endPass();
     327             : 
     328           0 :     ionspewer.spewPass(this);
     329             : }
     330             : 
     331             : void
     332          10 : GraphSpewer::endFunction()
     333             : {
     334          10 :     if (!ionspewer.isEnabled())
     335          10 :         return;
     336             : 
     337           0 :     if (!isSpewing()) {
     338           0 :         MOZ_ASSERT(filteredOutCompilations != 0);
     339           0 :         filteredOutCompilations--;
     340           0 :         return;
     341             :     }
     342             : 
     343           0 :     c1Spewer_.endFunction();
     344           0 :     jsonSpewer_.endFunction();
     345             : 
     346           0 :     ionspewer.endFunction(this);
     347           0 :     graph_ = nullptr;
     348             : }
     349             : 
     350             : void
     351           0 : GraphSpewer::dump(Fprinter& c1Out, Fprinter& jsonOut)
     352             : {
     353           0 :     if (!c1Printer_.hadOutOfMemory()) {
     354           0 :         c1Printer_.exportInto(c1Out);
     355           0 :         c1Out.flush();
     356             :     }
     357           0 :     c1Printer_.clear();
     358             : 
     359           0 :     if (!jsonPrinter_.hadOutOfMemory())
     360           0 :         jsonPrinter_.exportInto(jsonOut);
     361             :     else
     362           0 :         jsonOut.put("{}");
     363           0 :     jsonOut.flush();
     364           0 :     jsonPrinter_.clear();
     365           0 : }
     366             : 
     367             : void
     368          10 : jit::SpewBeginFunction(MIRGenerator* mir, JSScript* function)
     369             : {
     370          10 :     MIRGraph* graph = &mir->graph();
     371          10 :     mir->graphSpewer().init(graph, function);
     372          10 :     mir->graphSpewer().beginFunction(function);
     373          10 : }
     374             : 
     375          16 : AutoSpewEndFunction::~AutoSpewEndFunction()
     376             : {
     377           8 :     mir_->graphSpewer().endFunction();
     378           8 : }
     379             : 
     380             : Fprinter&
     381           0 : jit::JitSpewPrinter()
     382             : {
     383           0 :     static Fprinter out;
     384           0 :     return out;
     385             : }
     386             : 
     387             : 
     388             : static bool
     389           0 : ContainsFlag(const char* str, const char* flag)
     390             : {
     391           0 :     size_t flaglen = strlen(flag);
     392           0 :     const char* index = strstr(str, flag);
     393           0 :     while (index) {
     394           0 :         if ((index == str || index[-1] == ',') && (index[flaglen] == 0 || index[flaglen] == ','))
     395           0 :             return true;
     396           0 :         index = strstr(index + flaglen, flag);
     397             :     }
     398           0 :     return false;
     399             : }
     400             : 
     401             : void
     402           3 : jit::CheckLogging()
     403             : {
     404           3 :     if (LoggingChecked)
     405           0 :         return;
     406           3 :     LoggingChecked = true;
     407           3 :     const char* env = getenv("IONFLAGS");
     408           3 :     if (!env)
     409           3 :         return;
     410           0 :     if (strstr(env, "help")) {
     411           0 :         fflush(nullptr);
     412             :         printf(
     413             :             "\n"
     414             :             "usage: IONFLAGS=option,option,option,... where options can be:\n"
     415             :             "\n"
     416             :             "  aborts        Compilation abort messages\n"
     417             :             "  scripts       Compiled scripts\n"
     418             :             "  mir           MIR information\n"
     419             :             "  prune         Prune unused branches\n"
     420             :             "  escape        Escape analysis\n"
     421             :             "  alias         Alias analysis\n"
     422             :             "  alias-sum     Alias analysis: shows summaries for every block\n"
     423             :             "  gvn           Global Value Numbering\n"
     424             :             "  licm          Loop invariant code motion\n"
     425             :             "  flac          Fold linear arithmetic constants\n"
     426             :             "  eaa           Effective address analysis\n"
     427             :             "  sincos        Replace sin/cos by sincos\n"
     428             :             "  sink          Sink transformation\n"
     429             :             "  regalloc      Register allocation\n"
     430             :             "  inline        Inlining\n"
     431             :             "  snapshots     Snapshot information\n"
     432             :             "  codegen       Native code generation\n"
     433             :             "  bailouts      Bailouts\n"
     434             :             "  caches        Inline caches\n"
     435             :             "  osi           Invalidation\n"
     436             :             "  safepoints    Safepoints\n"
     437             :             "  pools         Literal Pools (ARM only for now)\n"
     438             :             "  cacheflush    Instruction Cache flushes (ARM only for now)\n"
     439             :             "  range         Range Analysis\n"
     440             :             "  unroll        Loop unrolling\n"
     441             :             "  logs          C1 and JSON visualization logging\n"
     442             :             "  logs-sync     Same as logs, but flushes between each pass (sync. compiled functions only).\n"
     443             :             "  profiling     Profiling-related information\n"
     444             :             "  trackopts     Optimization tracking information gathered by the Gecko profiler. "
     445             :                             "(Note: call enableGeckoProfiling() in your script to enable it).\n"
     446             :             "  trackopts-ext Encoding information about optimization tracking\n"
     447             :             "  dump-mir-expr Dump the MIR expressions\n"
     448             :             "  cfg           Control flow graph generation\n"
     449             :             "  all           Everything\n"
     450             :             "\n"
     451             :             "  bl-aborts     Baseline compiler abort messages\n"
     452             :             "  bl-scripts    Baseline script-compilation\n"
     453             :             "  bl-op         Baseline compiler detailed op-specific messages\n"
     454             :             "  bl-ic         Baseline inline-cache messages\n"
     455             :             "  bl-ic-fb      Baseline IC fallback stub messages\n"
     456             :             "  bl-osr        Baseline IC OSR messages\n"
     457             :             "  bl-bails      Baseline bailouts\n"
     458             :             "  bl-dbg-osr    Baseline debug mode on stack recompile messages\n"
     459             :             "  bl-all        All baseline spew\n"
     460             :             "\n"
     461           0 :         );
     462           0 :         exit(0);
     463             :         /*NOTREACHED*/
     464             :     }
     465           0 :     if (ContainsFlag(env, "aborts"))
     466           0 :         EnableChannel(JitSpew_IonAbort);
     467           0 :     if (ContainsFlag(env, "prune"))
     468           0 :         EnableChannel(JitSpew_Prune);
     469           0 :     if (ContainsFlag(env, "escape"))
     470           0 :         EnableChannel(JitSpew_Escape);
     471           0 :     if (ContainsFlag(env, "alias"))
     472           0 :         EnableChannel(JitSpew_Alias);
     473           0 :     if (ContainsFlag(env, "alias-sum"))
     474           0 :         EnableChannel(JitSpew_AliasSummaries);
     475           0 :     if (ContainsFlag(env, "scripts"))
     476           0 :         EnableChannel(JitSpew_IonScripts);
     477           0 :     if (ContainsFlag(env, "mir"))
     478           0 :         EnableChannel(JitSpew_IonMIR);
     479           0 :     if (ContainsFlag(env, "gvn"))
     480           0 :         EnableChannel(JitSpew_GVN);
     481           0 :     if (ContainsFlag(env, "range"))
     482           0 :         EnableChannel(JitSpew_Range);
     483           0 :     if (ContainsFlag(env, "unroll"))
     484           0 :         EnableChannel(JitSpew_Unrolling);
     485           0 :     if (ContainsFlag(env, "licm"))
     486           0 :         EnableChannel(JitSpew_LICM);
     487           0 :     if (ContainsFlag(env, "flac"))
     488           0 :         EnableChannel(JitSpew_FLAC);
     489           0 :     if (ContainsFlag(env, "eaa"))
     490           0 :         EnableChannel(JitSpew_EAA);
     491           0 :     if (ContainsFlag(env, "sincos"))
     492           0 :         EnableChannel(JitSpew_Sincos);
     493           0 :     if (ContainsFlag(env, "sink"))
     494           0 :         EnableChannel(JitSpew_Sink);
     495           0 :     if (ContainsFlag(env, "regalloc"))
     496           0 :         EnableChannel(JitSpew_RegAlloc);
     497           0 :     if (ContainsFlag(env, "inline"))
     498           0 :         EnableChannel(JitSpew_Inlining);
     499           0 :     if (ContainsFlag(env, "snapshots"))
     500           0 :         EnableChannel(JitSpew_IonSnapshots);
     501           0 :     if (ContainsFlag(env, "codegen"))
     502           0 :         EnableChannel(JitSpew_Codegen);
     503           0 :     if (ContainsFlag(env, "bailouts"))
     504           0 :         EnableChannel(JitSpew_IonBailouts);
     505           0 :     if (ContainsFlag(env, "osi"))
     506           0 :         EnableChannel(JitSpew_IonInvalidate);
     507           0 :     if (ContainsFlag(env, "caches"))
     508           0 :         EnableChannel(JitSpew_IonIC);
     509           0 :     if (ContainsFlag(env, "safepoints"))
     510           0 :         EnableChannel(JitSpew_Safepoints);
     511           0 :     if (ContainsFlag(env, "pools"))
     512           0 :         EnableChannel(JitSpew_Pools);
     513           0 :     if (ContainsFlag(env, "cacheflush"))
     514           0 :         EnableChannel(JitSpew_CacheFlush);
     515           0 :     if (ContainsFlag(env, "logs"))
     516           0 :         EnableIonDebugAsyncLogging();
     517           0 :     if (ContainsFlag(env, "logs-sync"))
     518           0 :         EnableIonDebugSyncLogging();
     519           0 :     if (ContainsFlag(env, "profiling"))
     520           0 :         EnableChannel(JitSpew_Profiling);
     521           0 :     if (ContainsFlag(env, "trackopts")) {
     522           0 :         JitOptions.disableOptimizationTracking = false;
     523           0 :         EnableChannel(JitSpew_OptimizationTracking);
     524             :     }
     525           0 :     if (ContainsFlag(env, "trackopts-ext"))
     526           0 :         EnableChannel(JitSpew_OptimizationTrackingExtended);
     527           0 :     if (ContainsFlag(env, "dump-mir-expr"))
     528           0 :         EnableChannel(JitSpew_MIRExpressions);
     529           0 :     if (ContainsFlag(env, "cfg"))
     530           0 :         EnableChannel(JitSpew_CFG);
     531           0 :     if (ContainsFlag(env, "all"))
     532           0 :         LoggingBits = uint64_t(-1);
     533             : 
     534           0 :     if (ContainsFlag(env, "bl-aborts"))
     535           0 :         EnableChannel(JitSpew_BaselineAbort);
     536           0 :     if (ContainsFlag(env, "bl-scripts"))
     537           0 :         EnableChannel(JitSpew_BaselineScripts);
     538           0 :     if (ContainsFlag(env, "bl-op"))
     539           0 :         EnableChannel(JitSpew_BaselineOp);
     540           0 :     if (ContainsFlag(env, "bl-ic"))
     541           0 :         EnableChannel(JitSpew_BaselineIC);
     542           0 :     if (ContainsFlag(env, "bl-ic-fb"))
     543           0 :         EnableChannel(JitSpew_BaselineICFallback);
     544           0 :     if (ContainsFlag(env, "bl-osr"))
     545           0 :         EnableChannel(JitSpew_BaselineOSR);
     546           0 :     if (ContainsFlag(env, "bl-bails"))
     547           0 :         EnableChannel(JitSpew_BaselineBailouts);
     548           0 :     if (ContainsFlag(env, "bl-dbg-osr"))
     549           0 :         EnableChannel(JitSpew_BaselineDebugModeOSR);
     550           0 :     if (ContainsFlag(env, "bl-all")) {
     551           0 :         EnableChannel(JitSpew_BaselineAbort);
     552           0 :         EnableChannel(JitSpew_BaselineScripts);
     553           0 :         EnableChannel(JitSpew_BaselineOp);
     554           0 :         EnableChannel(JitSpew_BaselineIC);
     555           0 :         EnableChannel(JitSpew_BaselineICFallback);
     556           0 :         EnableChannel(JitSpew_BaselineOSR);
     557           0 :         EnableChannel(JitSpew_BaselineBailouts);
     558           0 :         EnableChannel(JitSpew_BaselineDebugModeOSR);
     559             :     }
     560             : 
     561           0 :     JitSpewPrinter().init(stderr);
     562             : }
     563             : 
     564         836 : JitSpewIndent::JitSpewIndent(JitSpewChannel channel)
     565         836 :   : channel_(channel)
     566             : {
     567         836 :     ChannelIndentLevel[channel]++;
     568         836 : }
     569             : 
     570        1672 : JitSpewIndent::~JitSpewIndent()
     571             : {
     572         836 :     ChannelIndentLevel[channel_]--;
     573         836 : }
     574             : 
     575             : void
     576      257176 : jit::JitSpewStartVA(JitSpewChannel channel, const char* fmt, va_list ap)
     577             : {
     578      257176 :     if (!JitSpewEnabled(channel))
     579      257176 :         return;
     580             : 
     581           0 :     JitSpewHeader(channel);
     582           0 :     Fprinter& out = JitSpewPrinter();
     583           0 :     out.vprintf(fmt, ap);
     584             : }
     585             : 
     586             : void
     587         535 : jit::JitSpewContVA(JitSpewChannel channel, const char* fmt, va_list ap)
     588             : {
     589         535 :     if (!JitSpewEnabled(channel))
     590         535 :         return;
     591             : 
     592           0 :     Fprinter& out = JitSpewPrinter();
     593           0 :     out.vprintf(fmt, ap);
     594             : }
     595             : 
     596             : void
     597      257169 : jit::JitSpewFin(JitSpewChannel channel)
     598             : {
     599      257169 :     if (!JitSpewEnabled(channel))
     600      257169 :         return;
     601             : 
     602           0 :     Fprinter& out = JitSpewPrinter();
     603           0 :     out.put("\n");
     604             : }
     605             : 
     606             : void
     607      255379 : jit::JitSpewVA(JitSpewChannel channel, const char* fmt, va_list ap)
     608             : {
     609      255379 :     JitSpewStartVA(channel, fmt, ap);
     610      255379 :     JitSpewFin(channel);
     611      255379 : }
     612             : 
     613             : void
     614      255375 : jit::JitSpew(JitSpewChannel channel, const char* fmt, ...)
     615             : {
     616             :     va_list ap;
     617      255375 :     va_start(ap, fmt);
     618      255375 :     JitSpewVA(channel, fmt, ap);
     619      255376 :     va_end(ap);
     620      255376 : }
     621             : 
     622             : void
     623          26 : jit::JitSpewDef(JitSpewChannel channel, const char* str, MDefinition* def)
     624             : {
     625          26 :     if (!JitSpewEnabled(channel))
     626          26 :         return;
     627             : 
     628           0 :     JitSpewHeader(channel);
     629           0 :     Fprinter& out = JitSpewPrinter();
     630           0 :     out.put(str);
     631           0 :     def->dump(out);
     632           0 :     def->dumpLocation(out);
     633             : }
     634             : 
     635             : void
     636        1800 : jit::JitSpewStart(JitSpewChannel channel, const char* fmt, ...)
     637             : {
     638             :     va_list ap;
     639        1800 :     va_start(ap, fmt);
     640        1800 :     JitSpewStartVA(channel, fmt, ap);
     641        1800 :     va_end(ap);
     642        1800 : }
     643             : void
     644         535 : jit::JitSpewCont(JitSpewChannel channel, const char* fmt, ...)
     645             : {
     646             :     va_list ap;
     647         535 :     va_start(ap, fmt);
     648         535 :     JitSpewContVA(channel, fmt, ap);
     649         535 :     va_end(ap);
     650         535 : }
     651             : 
     652             : void
     653           0 : jit::JitSpewHeader(JitSpewChannel channel)
     654             : {
     655           0 :     if (!JitSpewEnabled(channel))
     656           0 :         return;
     657             : 
     658           0 :     Fprinter& out = JitSpewPrinter();
     659           0 :     out.printf("[%s] ", ChannelNames[channel]);
     660           0 :     for (size_t i = ChannelIndentLevel[channel]; i != 0; i--)
     661           0 :         out.put("  ");
     662             : }
     663             : 
     664             : bool
     665     1921579 : jit::JitSpewEnabled(JitSpewChannel channel)
     666             : {
     667     1921579 :     MOZ_ASSERT(LoggingChecked);
     668     1921579 :     return (LoggingBits & (uint64_t(1) << uint32_t(channel))) && !filteredOutCompilations;
     669             : }
     670             : 
     671             : void
     672           0 : jit::EnableChannel(JitSpewChannel channel)
     673             : {
     674           0 :     MOZ_ASSERT(LoggingChecked);
     675           0 :     LoggingBits |= uint64_t(1) << uint32_t(channel);
     676           0 : }
     677             : 
     678             : void
     679           0 : jit::DisableChannel(JitSpewChannel channel)
     680             : {
     681           0 :     MOZ_ASSERT(LoggingChecked);
     682           0 :     LoggingBits &= ~(uint64_t(1) << uint32_t(channel));
     683           0 : }
     684             : 
     685             : #endif /* JS_JITSPEW */
     686             : 

Generated by: LCOV version 1.13