Home | History | Annotate | Download | only in tracing
      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 "include/libplatform/v8-tracing.h"
      6 
      7 #include "base/trace_event/common/trace_event_common.h"
      8 #include "include/v8-platform.h"
      9 #include "src/base/platform/platform.h"
     10 #include "src/base/platform/time.h"
     11 
     12 namespace v8 {
     13 namespace platform {
     14 namespace tracing {
     15 
     16 // We perform checks for NULL strings since it is possible that a string arg
     17 // value is NULL.
     18 V8_INLINE static size_t GetAllocLength(const char* str) {
     19   return str ? strlen(str) + 1 : 0;
     20 }
     21 
     22 // Copies |*member| into |*buffer|, sets |*member| to point to this new
     23 // location, and then advances |*buffer| by the amount written.
     24 V8_INLINE static void CopyTraceObjectParameter(char** buffer,
     25                                                const char** member) {
     26   if (*member) {
     27     size_t length = strlen(*member) + 1;
     28     strncpy(*buffer, *member, length);
     29     *member = *buffer;
     30     *buffer += length;
     31   }
     32 }
     33 
     34 void TraceObject::Initialize(
     35     char phase, const uint8_t* category_enabled_flag, const char* name,
     36     const char* scope, uint64_t id, uint64_t bind_id, int num_args,
     37     const char** arg_names, const uint8_t* arg_types,
     38     const uint64_t* arg_values,
     39     std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
     40     unsigned int flags) {
     41   pid_ = base::OS::GetCurrentProcessId();
     42   tid_ = base::OS::GetCurrentThreadId();
     43   phase_ = phase;
     44   category_enabled_flag_ = category_enabled_flag;
     45   name_ = name;
     46   scope_ = scope;
     47   id_ = id;
     48   bind_id_ = bind_id;
     49   flags_ = flags;
     50   ts_ = base::TimeTicks::HighResolutionNow().ToInternalValue();
     51   tts_ = base::ThreadTicks::Now().ToInternalValue();
     52   duration_ = 0;
     53   cpu_duration_ = 0;
     54 
     55   // Clamp num_args since it may have been set by a third-party library.
     56   num_args_ = (num_args > kTraceMaxNumArgs) ? kTraceMaxNumArgs : num_args;
     57   for (int i = 0; i < num_args_; ++i) {
     58     arg_names_[i] = arg_names[i];
     59     arg_values_[i].as_uint = arg_values[i];
     60     arg_types_[i] = arg_types[i];
     61     if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE)
     62       arg_convertables_[i] = std::move(arg_convertables[i]);
     63   }
     64 
     65   bool copy = !!(flags & TRACE_EVENT_FLAG_COPY);
     66   // Allocate a long string to fit all string copies.
     67   size_t alloc_size = 0;
     68   if (copy) {
     69     alloc_size += GetAllocLength(name) + GetAllocLength(scope);
     70     for (int i = 0; i < num_args_; ++i) {
     71       alloc_size += GetAllocLength(arg_names_[i]);
     72       if (arg_types_[i] == TRACE_VALUE_TYPE_STRING)
     73         arg_types_[i] = TRACE_VALUE_TYPE_COPY_STRING;
     74     }
     75   }
     76 
     77   bool arg_is_copy[kTraceMaxNumArgs];
     78   for (int i = 0; i < num_args_; ++i) {
     79     // We only take a copy of arg_vals if they are of type COPY_STRING.
     80     arg_is_copy[i] = (arg_types_[i] == TRACE_VALUE_TYPE_COPY_STRING);
     81     if (arg_is_copy[i]) alloc_size += GetAllocLength(arg_values_[i].as_string);
     82   }
     83 
     84   if (alloc_size) {
     85     // Since TraceObject can be initialized multiple times, we might need
     86     // to free old memory.
     87     delete[] parameter_copy_storage_;
     88     char* ptr = parameter_copy_storage_ = new char[alloc_size];
     89     if (copy) {
     90       CopyTraceObjectParameter(&ptr, &name_);
     91       CopyTraceObjectParameter(&ptr, &scope_);
     92       for (int i = 0; i < num_args_; ++i) {
     93         CopyTraceObjectParameter(&ptr, &arg_names_[i]);
     94       }
     95     }
     96     for (int i = 0; i < num_args_; ++i) {
     97       if (arg_is_copy[i]) {
     98         CopyTraceObjectParameter(&ptr, &arg_values_[i].as_string);
     99       }
    100     }
    101   }
    102 }
    103 
    104 TraceObject::~TraceObject() { delete[] parameter_copy_storage_; }
    105 
    106 void TraceObject::UpdateDuration() {
    107   duration_ = base::TimeTicks::HighResolutionNow().ToInternalValue() - ts_;
    108   cpu_duration_ = base::ThreadTicks::Now().ToInternalValue() - tts_;
    109 }
    110 
    111 void TraceObject::InitializeForTesting(
    112     char phase, const uint8_t* category_enabled_flag, const char* name,
    113     const char* scope, uint64_t id, uint64_t bind_id, int num_args,
    114     const char** arg_names, const uint8_t* arg_types,
    115     const uint64_t* arg_values,
    116     std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
    117     unsigned int flags, int pid, int tid, int64_t ts, int64_t tts,
    118     uint64_t duration, uint64_t cpu_duration) {
    119   pid_ = pid;
    120   tid_ = tid;
    121   phase_ = phase;
    122   category_enabled_flag_ = category_enabled_flag;
    123   name_ = name;
    124   scope_ = scope;
    125   id_ = id;
    126   bind_id_ = bind_id;
    127   num_args_ = num_args;
    128   flags_ = flags;
    129   ts_ = ts;
    130   tts_ = tts;
    131   duration_ = duration;
    132   cpu_duration_ = cpu_duration;
    133 }
    134 
    135 }  // namespace tracing
    136 }  // namespace platform
    137 }  // namespace v8
    138