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