LCOV - code coverage report
Current view: top level - js/src/jit - CacheIRSpewer.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 4 81 4.9 %
Date: 2017-07-14 16:53:18 Functions: 1 10 10.0 %
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_CACHEIR_SPEW
       8             : 
       9             : #include "jit/CacheIRSpewer.h"
      10             : 
      11             : #include "mozilla/SizePrintfMacros.h"
      12             : #include "mozilla/Sprintf.h"
      13             : 
      14             : #ifdef XP_WIN
      15             : #include <process.h>
      16             : #define getpid _getpid
      17             : #else
      18             : #include <unistd.h>
      19             : #endif
      20             : 
      21             : #include <stdarg.h>
      22             : 
      23             : #include "jsfun.h"
      24             : #include "jsobj.h"
      25             : #include "jsscript.h"
      26             : 
      27             : #include "jscompartmentinlines.h"
      28             : #include "jsobjinlines.h"
      29             : 
      30             : using namespace js;
      31             : using namespace js::jit;
      32             : 
      33           3 : CacheIRSpewer CacheIRSpewer::cacheIRspewer;
      34             : 
      35           3 : CacheIRSpewer::CacheIRSpewer()
      36           3 :   : outputLock(mutexid::CacheIRSpewer)
      37           3 : { }
      38             : 
      39           0 : CacheIRSpewer::~CacheIRSpewer()
      40             : {
      41           0 :     if (!enabled())
      42           0 :         return;
      43             : 
      44           0 :     json.ref().endList();
      45           0 :     output.flush();
      46           0 :     output.finish();
      47           0 : }
      48             : 
      49             : #ifndef JIT_SPEW_DIR
      50             : # if defined(_WIN32)
      51             : #  define JIT_SPEW_DIR "."
      52             : # elif defined(__ANDROID__)
      53             : #  define JIT_SPEW_DIR "/data/local/tmp"
      54             : # else
      55             : #  define JIT_SPEW_DIR "/tmp"
      56             : # endif
      57             : #endif
      58             : 
      59             : bool
      60           0 : CacheIRSpewer::init()
      61             : {
      62           0 :     if (enabled())
      63           0 :         return true;
      64             : 
      65             :     char name[256];
      66           0 :     uint32_t pid = getpid();
      67           0 :     SprintfLiteral(name, JIT_SPEW_DIR "/cacheir%" PRIu32 ".json", pid);
      68             : 
      69           0 :     if (!output.init(name))
      70           0 :         return false;
      71           0 :     output.put("[");
      72             : 
      73           0 :     json.emplace(output);
      74           0 :     return true;
      75             : }
      76             : 
      77             : void
      78           0 : CacheIRSpewer::beginCache(LockGuard<Mutex>&, const IRGenerator& gen)
      79             : {
      80           0 :     MOZ_ASSERT(enabled());
      81           0 :     JSONPrinter& j = json.ref();
      82             : 
      83           0 :     j.beginObject();
      84           0 :     j.property("name", CacheKindNames[uint8_t(gen.cacheKind_)]);
      85           0 :     j.property("file", gen.script_->filename());
      86           0 :     j.property("mode", int(gen.mode_));
      87           0 :     if (jsbytecode* pc = gen.pc_) {
      88             :         unsigned column;
      89           0 :         j.property("line", PCToLineNumber(gen.script_, pc, &column));
      90           0 :         j.property("column", column);
      91           0 :         j.formatProperty("pc", "%p", pc);
      92             :     }
      93           0 : }
      94             : 
      95             : template <typename CharT>
      96             : static void
      97           0 : QuoteString(GenericPrinter& out, const CharT* s, size_t length)
      98             : {
      99           0 :     const CharT* end = s + length;
     100           0 :     for (const CharT* t = s; t < end; s = ++t) {
     101             :         // This quote implementation is probably correct,
     102             :         // but uses \u even when not strictly necessary.
     103           0 :         char16_t c = *t;
     104           0 :         if (c == '"' || c == '\\') {
     105           0 :             out.printf("\\");
     106           0 :             out.printf("%c", char(c));
     107           0 :         } else if (c < ' ' || c >= 127 || !isprint(c)) {
     108           0 :             out.printf("\\u%04x", c);
     109             :         } else {
     110           0 :             out.printf("%c", char(c));
     111             :         }
     112             :     }
     113           0 : }
     114             : 
     115             : static void
     116           0 : QuoteString(GenericPrinter& out, JSLinearString* str)
     117             : {
     118           0 :     JS::AutoCheckCannotGC nogc;
     119           0 :     if (str->hasLatin1Chars())
     120           0 :         QuoteString(out, str->latin1Chars(nogc), str->length());
     121             :     else
     122           0 :         QuoteString(out, str->twoByteChars(nogc), str->length());
     123           0 : }
     124             : 
     125             : void
     126           0 : CacheIRSpewer::valueProperty(LockGuard<Mutex>&, const char* name, const Value& v)
     127             : {
     128           0 :     MOZ_ASSERT(enabled());
     129           0 :     JSONPrinter& j = json.ref();
     130             : 
     131           0 :     j.beginObjectProperty(name);
     132             : 
     133           0 :     const char* type = InformalValueTypeName(v);
     134           0 :     if (v.isInt32())
     135           0 :         type = "int32";
     136           0 :     j.property("type", type);
     137             : 
     138           0 :     if (v.isInt32()) {
     139           0 :         j.property("value", v.toInt32());
     140           0 :     } else if (v.isDouble()) {
     141           0 :         j.floatProperty("value", v.toDouble(), 3);
     142           0 :     } else if (v.isString() || v.isSymbol()) {
     143           0 :         JSString* str = v.isString() ? v.toString() : v.toSymbol()->description();
     144           0 :         if (str && str->isLinear()) {
     145           0 :             j.beginStringProperty("value");
     146           0 :             QuoteString(output, &str->asLinear());
     147           0 :             j.endStringProperty();
     148             :         }
     149           0 :     } else if (v.isObject()) {
     150           0 :         j.formatProperty("value", "%p (shape: %p)", &v.toObject(),
     151           0 :                          v.toObject().maybeShape());
     152             :     }
     153             : 
     154           0 :     j.endObject();
     155           0 : }
     156             : 
     157             : void
     158           0 : CacheIRSpewer::attached(LockGuard<Mutex>&, const char* name)
     159             : {
     160           0 :     MOZ_ASSERT(enabled());
     161           0 :     json.ref().property("attached", name);
     162           0 : }
     163             : 
     164             : void
     165           0 : CacheIRSpewer::endCache(LockGuard<Mutex>&)
     166             : {
     167           0 :     MOZ_ASSERT(enabled());
     168           0 :     json.ref().endObject();
     169           0 : }
     170             : 
     171             : #endif /* JS_CACHEIR_SPEW */

Generated by: LCOV version 1.13