11cb0ef41Sopenharmony_ci// Copyright 2016 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include "base/trace_event/common/trace_event_common.h" 61cb0ef41Sopenharmony_ci#include "include/libplatform/v8-tracing.h" 71cb0ef41Sopenharmony_ci#include "include/v8-platform.h" 81cb0ef41Sopenharmony_ci#include "src/base/platform/platform.h" 91cb0ef41Sopenharmony_ci#include "src/base/platform/time.h" 101cb0ef41Sopenharmony_ci#include "src/base/platform/wrappers.h" 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_cinamespace v8 { 131cb0ef41Sopenharmony_cinamespace platform { 141cb0ef41Sopenharmony_cinamespace tracing { 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci// We perform checks for nullptr strings since it is possible that a string arg 171cb0ef41Sopenharmony_ci// value is nullptr. 181cb0ef41Sopenharmony_ciV8_INLINE static size_t GetAllocLength(const char* str) { 191cb0ef41Sopenharmony_ci return str ? strlen(str) + 1 : 0; 201cb0ef41Sopenharmony_ci} 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci// Copies |*member| into |*buffer|, sets |*member| to point to this new 231cb0ef41Sopenharmony_ci// location, and then advances |*buffer| by the amount written. 241cb0ef41Sopenharmony_ciV8_INLINE static void CopyTraceObjectParameter(char** buffer, 251cb0ef41Sopenharmony_ci const char** member) { 261cb0ef41Sopenharmony_ci if (*member == nullptr) return; 271cb0ef41Sopenharmony_ci size_t length = strlen(*member) + 1; 281cb0ef41Sopenharmony_ci memcpy(*buffer, *member, length); 291cb0ef41Sopenharmony_ci *member = *buffer; 301cb0ef41Sopenharmony_ci *buffer += length; 311cb0ef41Sopenharmony_ci} 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_civoid TraceObject::Initialize( 341cb0ef41Sopenharmony_ci char phase, const uint8_t* category_enabled_flag, const char* name, 351cb0ef41Sopenharmony_ci const char* scope, uint64_t id, uint64_t bind_id, int num_args, 361cb0ef41Sopenharmony_ci const char** arg_names, const uint8_t* arg_types, 371cb0ef41Sopenharmony_ci const uint64_t* arg_values, 381cb0ef41Sopenharmony_ci std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables, 391cb0ef41Sopenharmony_ci unsigned int flags, int64_t timestamp, int64_t cpu_timestamp) { 401cb0ef41Sopenharmony_ci pid_ = base::OS::GetCurrentProcessId(); 411cb0ef41Sopenharmony_ci tid_ = base::OS::GetCurrentThreadId(); 421cb0ef41Sopenharmony_ci phase_ = phase; 431cb0ef41Sopenharmony_ci category_enabled_flag_ = category_enabled_flag; 441cb0ef41Sopenharmony_ci name_ = name; 451cb0ef41Sopenharmony_ci scope_ = scope; 461cb0ef41Sopenharmony_ci id_ = id; 471cb0ef41Sopenharmony_ci bind_id_ = bind_id; 481cb0ef41Sopenharmony_ci flags_ = flags; 491cb0ef41Sopenharmony_ci ts_ = timestamp; 501cb0ef41Sopenharmony_ci tts_ = cpu_timestamp; 511cb0ef41Sopenharmony_ci duration_ = 0; 521cb0ef41Sopenharmony_ci cpu_duration_ = 0; 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci // Clamp num_args since it may have been set by a third-party library. 551cb0ef41Sopenharmony_ci num_args_ = (num_args > kTraceMaxNumArgs) ? kTraceMaxNumArgs : num_args; 561cb0ef41Sopenharmony_ci for (int i = 0; i < num_args_; ++i) { 571cb0ef41Sopenharmony_ci arg_names_[i] = arg_names[i]; 581cb0ef41Sopenharmony_ci arg_values_[i].as_uint = arg_values[i]; 591cb0ef41Sopenharmony_ci arg_types_[i] = arg_types[i]; 601cb0ef41Sopenharmony_ci if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE) 611cb0ef41Sopenharmony_ci arg_convertables_[i] = std::move(arg_convertables[i]); 621cb0ef41Sopenharmony_ci } 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci bool copy = !!(flags & TRACE_EVENT_FLAG_COPY); 651cb0ef41Sopenharmony_ci // Allocate a long string to fit all string copies. 661cb0ef41Sopenharmony_ci size_t alloc_size = 0; 671cb0ef41Sopenharmony_ci if (copy) { 681cb0ef41Sopenharmony_ci alloc_size += GetAllocLength(name) + GetAllocLength(scope); 691cb0ef41Sopenharmony_ci for (int i = 0; i < num_args_; ++i) { 701cb0ef41Sopenharmony_ci alloc_size += GetAllocLength(arg_names_[i]); 711cb0ef41Sopenharmony_ci if (arg_types_[i] == TRACE_VALUE_TYPE_STRING) 721cb0ef41Sopenharmony_ci arg_types_[i] = TRACE_VALUE_TYPE_COPY_STRING; 731cb0ef41Sopenharmony_ci } 741cb0ef41Sopenharmony_ci } 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci bool arg_is_copy[kTraceMaxNumArgs]; 771cb0ef41Sopenharmony_ci for (int i = 0; i < num_args_; ++i) { 781cb0ef41Sopenharmony_ci // We only take a copy of arg_vals if they are of type COPY_STRING. 791cb0ef41Sopenharmony_ci arg_is_copy[i] = (arg_types_[i] == TRACE_VALUE_TYPE_COPY_STRING); 801cb0ef41Sopenharmony_ci if (arg_is_copy[i]) alloc_size += GetAllocLength(arg_values_[i].as_string); 811cb0ef41Sopenharmony_ci } 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci if (alloc_size) { 841cb0ef41Sopenharmony_ci // Since TraceObject can be initialized multiple times, we might need 851cb0ef41Sopenharmony_ci // to free old memory. 861cb0ef41Sopenharmony_ci delete[] parameter_copy_storage_; 871cb0ef41Sopenharmony_ci char* ptr = parameter_copy_storage_ = new char[alloc_size]; 881cb0ef41Sopenharmony_ci if (copy) { 891cb0ef41Sopenharmony_ci CopyTraceObjectParameter(&ptr, &name_); 901cb0ef41Sopenharmony_ci CopyTraceObjectParameter(&ptr, &scope_); 911cb0ef41Sopenharmony_ci for (int i = 0; i < num_args_; ++i) { 921cb0ef41Sopenharmony_ci CopyTraceObjectParameter(&ptr, &arg_names_[i]); 931cb0ef41Sopenharmony_ci } 941cb0ef41Sopenharmony_ci } 951cb0ef41Sopenharmony_ci for (int i = 0; i < num_args_; ++i) { 961cb0ef41Sopenharmony_ci if (arg_is_copy[i]) { 971cb0ef41Sopenharmony_ci CopyTraceObjectParameter(&ptr, &arg_values_[i].as_string); 981cb0ef41Sopenharmony_ci } 991cb0ef41Sopenharmony_ci } 1001cb0ef41Sopenharmony_ci } 1011cb0ef41Sopenharmony_ci} 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ciTraceObject::~TraceObject() { delete[] parameter_copy_storage_; } 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_civoid TraceObject::UpdateDuration(int64_t timestamp, int64_t cpu_timestamp) { 1061cb0ef41Sopenharmony_ci duration_ = timestamp - ts_; 1071cb0ef41Sopenharmony_ci cpu_duration_ = cpu_timestamp - tts_; 1081cb0ef41Sopenharmony_ci} 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_civoid TraceObject::InitializeForTesting( 1111cb0ef41Sopenharmony_ci char phase, const uint8_t* category_enabled_flag, const char* name, 1121cb0ef41Sopenharmony_ci const char* scope, uint64_t id, uint64_t bind_id, int num_args, 1131cb0ef41Sopenharmony_ci const char** arg_names, const uint8_t* arg_types, 1141cb0ef41Sopenharmony_ci const uint64_t* arg_values, 1151cb0ef41Sopenharmony_ci std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables, 1161cb0ef41Sopenharmony_ci unsigned int flags, int pid, int tid, int64_t ts, int64_t tts, 1171cb0ef41Sopenharmony_ci uint64_t duration, uint64_t cpu_duration) { 1181cb0ef41Sopenharmony_ci pid_ = pid; 1191cb0ef41Sopenharmony_ci tid_ = tid; 1201cb0ef41Sopenharmony_ci phase_ = phase; 1211cb0ef41Sopenharmony_ci category_enabled_flag_ = category_enabled_flag; 1221cb0ef41Sopenharmony_ci name_ = name; 1231cb0ef41Sopenharmony_ci scope_ = scope; 1241cb0ef41Sopenharmony_ci id_ = id; 1251cb0ef41Sopenharmony_ci bind_id_ = bind_id; 1261cb0ef41Sopenharmony_ci num_args_ = num_args; 1271cb0ef41Sopenharmony_ci flags_ = flags; 1281cb0ef41Sopenharmony_ci ts_ = ts; 1291cb0ef41Sopenharmony_ci tts_ = tts; 1301cb0ef41Sopenharmony_ci duration_ = duration; 1311cb0ef41Sopenharmony_ci cpu_duration_ = cpu_duration; 1321cb0ef41Sopenharmony_ci} 1331cb0ef41Sopenharmony_ci 1341cb0ef41Sopenharmony_ci} // namespace tracing 1351cb0ef41Sopenharmony_ci} // namespace platform 1361cb0ef41Sopenharmony_ci} // namespace v8 137