| // 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 "v8/src/tracing/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 NULL strings since it is possible that a string arg |
| // value is NULL. |
| 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) { |
| 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_ = base::TimeTicks::HighResolutionNow().ToInternalValue(); |
| tts_ = base::ThreadTicks::Now().ToInternalValue(); |
| 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() { |
| duration_ = base::TimeTicks::HighResolutionNow().ToInternalValue() - ts_; |
| cpu_duration_ = base::ThreadTicks::Now().ToInternalValue() - 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 |