LCOV - code coverage report
Current view: top level - src/libplatform/tracing - trace-writer.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 67 77 87.0 %
Date: 2017-04-26 Functions: 6 8 75.0 %

          Line data    Source code
       1             : // Copyright 2016 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/libplatform/tracing/trace-writer.h"
       6             : 
       7             : #include <cmath>
       8             : 
       9             : #include "base/trace_event/common/trace_event_common.h"
      10             : #include "include/v8-platform.h"
      11             : #include "src/base/platform/platform.h"
      12             : 
      13             : namespace v8 {
      14             : namespace platform {
      15             : namespace tracing {
      16             : 
      17             : // Writes the given string to a stream, taking care to escape characters
      18             : // when necessary.
      19             : V8_INLINE static void WriteJSONStringToStream(const char* str,
      20             :                                               std::ostream& stream) {
      21          49 :   size_t len = strlen(str);
      22          49 :   stream << "\"";
      23         224 :   for (size_t i = 0; i < len; ++i) {
      24             :     // All of the permitted escape sequences in JSON strings, as per
      25             :     // https://mathiasbynens.be/notes/javascript-escapes
      26         224 :     switch (str[i]) {
      27             :       case '\b':
      28           0 :         stream << "\\b";
      29             :         break;
      30             :       case '\f':
      31           0 :         stream << "\\f";
      32             :         break;
      33             :       case '\n':
      34           0 :         stream << "\\n";
      35             :         break;
      36             :       case '\r':
      37           0 :         stream << "\\r";
      38             :         break;
      39             :       case '\t':
      40           0 :         stream << "\\t";
      41             :         break;
      42             :       case '\"':
      43          42 :         stream << "\\\"";
      44             :         break;
      45             :       case '\\':
      46           0 :         stream << "\\\\";
      47             :         break;
      48             :       // Note that because we use double quotes for JSON strings,
      49             :       // we don't need to escape single quotes.
      50             :       default:
      51         182 :         stream << str[i];
      52             :         break;
      53             :     }
      54             :   }
      55          49 :   stream << "\"";
      56             : }
      57             : 
      58         168 : void JSONTraceWriter::AppendArgValue(uint8_t type,
      59             :                                      TraceObject::ArgValue value) {
      60         168 :   switch (type) {
      61             :     case TRACE_VALUE_TYPE_BOOL:
      62          14 :       stream_ << (value.as_bool ? "true" : "false");
      63          14 :       break;
      64             :     case TRACE_VALUE_TYPE_UINT:
      65          35 :       stream_ << value.as_uint;
      66             :       break;
      67             :     case TRACE_VALUE_TYPE_INT:
      68          28 :       stream_ << value.as_int;
      69             :       break;
      70             :     case TRACE_VALUE_TYPE_DOUBLE: {
      71             :       std::string real;
      72          35 :       double val = value.as_double;
      73          35 :       if (std::isfinite(val)) {
      74          14 :         std::ostringstream convert_stream;
      75             :         convert_stream << val;
      76          14 :         real = convert_stream.str();
      77             :         // Ensure that the number has a .0 if there's no decimal or 'e'.  This
      78             :         // makes sure that when we read the JSON back, it's interpreted as a
      79             :         // real rather than an int.
      80          42 :         if (real.find('.') == std::string::npos &&
      81          21 :             real.find('e') == std::string::npos &&
      82           7 :             real.find('E') == std::string::npos) {
      83             :           real += ".0";
      84          14 :         }
      85          21 :       } else if (std::isnan(val)) {
      86             :         // The JSON spec doesn't allow NaN and Infinity (since these are
      87             :         // objects in EcmaScript).  Use strings instead.
      88             :         real = "\"NaN\"";
      89          14 :       } else if (val < 0) {
      90             :         real = "\"-Infinity\"";
      91             :       } else {
      92             :         real = "\"Infinity\"";
      93             :       }
      94          35 :       stream_ << real;
      95             :       break;
      96             :     }
      97             :     case TRACE_VALUE_TYPE_POINTER:
      98             :       // JSON only supports double and int numbers.
      99             :       // So as not to lose bits from a 64-bit pointer, output as a hex string.
     100          14 :       stream_ << "\"" << value.as_pointer << "\"";
     101           7 :       break;
     102             :     case TRACE_VALUE_TYPE_STRING:
     103             :     case TRACE_VALUE_TYPE_COPY_STRING:
     104          49 :       if (value.as_string == nullptr) {
     105           0 :         stream_ << "\"NULL\"";
     106             :       } else {
     107          49 :         WriteJSONStringToStream(value.as_string, stream_);
     108             :       }
     109             :       break;
     110             :     default:
     111           0 :       UNREACHABLE();
     112             :       break;
     113             :   }
     114         168 : }
     115             : 
     116          21 : void JSONTraceWriter::AppendArgValue(ConvertableToTraceFormat* value) {
     117             :   std::string arg_stringified;
     118          21 :   value->AppendAsTraceFormat(&arg_stringified);
     119          21 :   stream_ << arg_stringified;
     120          21 : }
     121             : 
     122          14 : JSONTraceWriter::JSONTraceWriter(std::ostream& stream) : stream_(stream) {
     123          14 :   stream_ << "{\"traceEvents\":[";
     124           0 : }
     125             : 
     126          28 : JSONTraceWriter::~JSONTraceWriter() { stream_ << "]}"; }
     127             : 
     128        1113 : void JSONTraceWriter::AppendTraceEvent(TraceObject* trace_event) {
     129         182 :   if (append_comma_) stream_ << ",";
     130         182 :   append_comma_ = true;
     131         182 :   stream_ << "{\"pid\":" << trace_event->pid()
     132         182 :           << ",\"tid\":" << trace_event->tid()
     133         182 :           << ",\"ts\":" << trace_event->ts()
     134         364 :           << ",\"tts\":" << trace_event->tts() << ",\"ph\":\""
     135         182 :           << trace_event->phase() << "\",\"cat\":\""
     136             :           << TracingController::GetCategoryGroupName(
     137         364 :                  trace_event->category_enabled_flag())
     138         182 :           << "\",\"name\":\"" << trace_event->name()
     139         182 :           << "\",\"dur\":" << trace_event->duration()
     140         182 :           << ",\"tdur\":" << trace_event->cpu_duration();
     141         182 :   if (trace_event->flags() & TRACE_EVENT_FLAG_HAS_ID) {
     142           7 :     if (trace_event->scope() != nullptr) {
     143           0 :       stream_ << ",\"scope\":\"" << trace_event->scope() << "\"";
     144             :     }
     145             :     // So as not to lose bits from a 64-bit integer, output as a hex string.
     146          14 :     stream_ << ",\"id\":\"0x" << std::hex << trace_event->id() << "\""
     147             :             << std::dec;
     148             :   }
     149         182 :   stream_ << ",\"args\":{";
     150         182 :   const char** arg_names = trace_event->arg_names();
     151         182 :   const uint8_t* arg_types = trace_event->arg_types();
     152         182 :   TraceObject::ArgValue* arg_values = trace_event->arg_values();
     153             :   std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables =
     154         182 :       trace_event->arg_convertables();
     155         742 :   for (int i = 0; i < trace_event->num_args(); ++i) {
     156         189 :     if (i > 0) stream_ << ",";
     157         189 :     stream_ << "\"" << arg_names[i] << "\":";
     158         189 :     if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE) {
     159          42 :       AppendArgValue(arg_convertables[i].get());
     160             :     } else {
     161         168 :       AppendArgValue(arg_types[i], arg_values[i]);
     162             :     }
     163             :   }
     164         182 :   stream_ << "}}";
     165             :   // TODO(fmeawad): Add support for Flow Events.
     166         182 : }
     167             : 
     168          14 : void JSONTraceWriter::Flush() {}
     169             : 
     170          14 : TraceWriter* TraceWriter::CreateJSONTraceWriter(std::ostream& stream) {
     171          28 :   return new JSONTraceWriter(stream);
     172             : }
     173             : 
     174             : }  // namespace tracing
     175             : }  // namespace platform
     176             : }  // namespace v8

Generated by: LCOV version 1.10