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