| // Copyright 2016 the V8 project authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "include/libplatform/v8-tracing.h" | |
| #include "base/trace_event/common/trace_event_common.h" | |
| #include "include/v8-platform.h" | |
| #include "src/base/platform/platform.h" | |
| #include "src/base/platform/time.h" | |
| namespace v8 { | |
| namespace platform { | |
| namespace tracing { | |
| // We perform checks for nullptr strings since it is possible that a string arg | |
| // value is nullptr. | |
| V8_INLINE static size_t GetAllocLength(const char* str) { | |
| return str ? strlen(str) + 1 : 0; | |
| } | |
| // Copies |*member| into |*buffer|, sets |*member| to point to this new | |
| // location, and then advances |*buffer| by the amount written. | |
| V8_INLINE static void CopyTraceObjectParameter(char** buffer, | |
| const char** member) { | |
| if (*member) { | |
| size_t length = strlen(*member) + 1; | |
| strncpy(*buffer, *member, length); | |
| *member = *buffer; | |
| *buffer += length; | |
| } | |
| } | |
| void TraceObject::Initialize( | |
| char phase, const uint8_t* category_enabled_flag, const char* name, | |
| const char* scope, uint64_t id, uint64_t bind_id, int num_args, | |
| const char** arg_names, const uint8_t* arg_types, | |
| const uint64_t* arg_values, | |
| std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables, | |
| unsigned int flags, int64_t timestamp, int64_t cpu_timestamp) { | |
| pid_ = base::OS::GetCurrentProcessId(); | |
| tid_ = base::OS::GetCurrentThreadId(); | |
| phase_ = phase; | |
| category_enabled_flag_ = category_enabled_flag; | |
| name_ = name; | |
| scope_ = scope; | |
| id_ = id; | |
| bind_id_ = bind_id; | |
| flags_ = flags; | |
| ts_ = timestamp; | |
| tts_ = cpu_timestamp; | |
| duration_ = 0; | |
| cpu_duration_ = 0; | |
| // Clamp num_args since it may have been set by a third-party library. | |
| num_args_ = (num_args > kTraceMaxNumArgs) ? kTraceMaxNumArgs : num_args; | |
| for (int i = 0; i < num_args_; ++i) { | |
| arg_names_[i] = arg_names[i]; | |
| arg_values_[i].as_uint = arg_values[i]; | |
| arg_types_[i] = arg_types[i]; | |
| if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE) | |
| arg_convertables_[i] = std::move(arg_convertables[i]); | |
| } | |
| bool copy = !!(flags & TRACE_EVENT_FLAG_COPY); | |
| // Allocate a long string to fit all string copies. | |
| size_t alloc_size = 0; | |
| if (copy) { | |
| alloc_size += GetAllocLength(name) + GetAllocLength(scope); | |
| for (int i = 0; i < num_args_; ++i) { | |
| alloc_size += GetAllocLength(arg_names_[i]); | |
| if (arg_types_[i] == TRACE_VALUE_TYPE_STRING) | |
| arg_types_[i] = TRACE_VALUE_TYPE_COPY_STRING; | |
| } | |
| } | |
| bool arg_is_copy[kTraceMaxNumArgs]; | |
| for (int i = 0; i < num_args_; ++i) { | |
| // We only take a copy of arg_vals if they are of type COPY_STRING. | |
| arg_is_copy[i] = (arg_types_[i] == TRACE_VALUE_TYPE_COPY_STRING); | |
| if (arg_is_copy[i]) alloc_size += GetAllocLength(arg_values_[i].as_string); | |
| } | |
| if (alloc_size) { | |
| // Since TraceObject can be initialized multiple times, we might need | |
| // to free old memory. | |
| delete[] parameter_copy_storage_; | |
| char* ptr = parameter_copy_storage_ = new char[alloc_size]; | |
| if (copy) { | |
| CopyTraceObjectParameter(&ptr, &name_); | |
| CopyTraceObjectParameter(&ptr, &scope_); | |
| for (int i = 0; i < num_args_; ++i) { | |
| CopyTraceObjectParameter(&ptr, &arg_names_[i]); | |
| } | |
| } | |
| for (int i = 0; i < num_args_; ++i) { | |
| if (arg_is_copy[i]) { | |
| CopyTraceObjectParameter(&ptr, &arg_values_[i].as_string); | |
| } | |
| } | |
| } | |
| } | |
| TraceObject::~TraceObject() { delete[] parameter_copy_storage_; } | |
| void TraceObject::UpdateDuration(int64_t timestamp, int64_t cpu_timestamp) { | |
| duration_ = timestamp - ts_; | |
| cpu_duration_ = cpu_timestamp - tts_; | |
| } | |
| void TraceObject::InitializeForTesting( | |
| char phase, const uint8_t* category_enabled_flag, const char* name, | |
| const char* scope, uint64_t id, uint64_t bind_id, int num_args, | |
| const char** arg_names, const uint8_t* arg_types, | |
| const uint64_t* arg_values, | |
| std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables, | |
| unsigned int flags, int pid, int tid, int64_t ts, int64_t tts, | |
| uint64_t duration, uint64_t cpu_duration) { | |
| pid_ = pid; | |
| tid_ = tid; | |
| phase_ = phase; | |
| category_enabled_flag_ = category_enabled_flag; | |
| name_ = name; | |
| scope_ = scope; | |
| id_ = id; | |
| bind_id_ = bind_id; | |
| num_args_ = num_args; | |
| flags_ = flags; | |
| ts_ = ts; | |
| tts_ = tts; | |
| duration_ = duration; | |
| cpu_duration_ = cpu_duration; | |
| } | |
| } // namespace tracing | |
| } // namespace platform | |
| } // namespace v8 |