Line data Source code
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 nullptr strings since it is possible that a string arg
17 : // value is nullptr.
18 : V8_INLINE static size_t GetAllocLength(const char* str) {
19 45 : 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 55 : if (*member) {
27 45 : size_t length = strlen(*member) + 1;
28 : strncpy(*buffer, *member, length);
29 45 : *member = *buffer;
30 45 : *buffer += length;
31 : }
32 : }
33 :
34 2076 : 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, int64_t timestamp, int64_t cpu_timestamp) {
41 2076 : pid_ = base::OS::GetCurrentProcessId();
42 2076 : tid_ = base::OS::GetCurrentThreadId();
43 2076 : phase_ = phase;
44 2076 : category_enabled_flag_ = category_enabled_flag;
45 2076 : name_ = name;
46 2076 : scope_ = scope;
47 2076 : id_ = id;
48 2076 : bind_id_ = bind_id;
49 2076 : flags_ = flags;
50 2076 : ts_ = timestamp;
51 2076 : tts_ = cpu_timestamp;
52 2076 : duration_ = 0;
53 2076 : cpu_duration_ = 0;
54 :
55 : // Clamp num_args since it may have been set by a third-party library.
56 2076 : num_args_ = (num_args > kTraceMaxNumArgs) ? kTraceMaxNumArgs : num_args;
57 2384 : for (int i = 0; i < num_args_; ++i) {
58 154 : arg_names_[i] = arg_names[i];
59 154 : arg_values_[i].as_uint = arg_values[i];
60 154 : arg_types_[i] = arg_types[i];
61 154 : if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE)
62 34 : arg_convertables_[i] = std::move(arg_convertables[i]);
63 : }
64 :
65 2076 : bool copy = !!(flags & TRACE_EVENT_FLAG_COPY);
66 : // Allocate a long string to fit all string copies.
67 : size_t alloc_size = 0;
68 2076 : if (copy) {
69 10 : alloc_size += GetAllocLength(name) + GetAllocLength(scope);
70 30 : for (int i = 0; i < num_args_; ++i) {
71 20 : alloc_size += GetAllocLength(arg_names_[i]);
72 10 : if (arg_types_[i] == TRACE_VALUE_TYPE_STRING)
73 10 : arg_types_[i] = TRACE_VALUE_TYPE_COPY_STRING;
74 : }
75 : }
76 :
77 : bool arg_is_copy[kTraceMaxNumArgs];
78 2384 : 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 154 : arg_is_copy[i] = (arg_types_[i] == TRACE_VALUE_TYPE_COPY_STRING);
81 179 : if (arg_is_copy[i]) alloc_size += GetAllocLength(arg_values_[i].as_string);
82 : }
83 :
84 2076 : if (alloc_size) {
85 : // Since TraceObject can be initialized multiple times, we might need
86 : // to free old memory.
87 20 : delete[] parameter_copy_storage_;
88 20 : char* ptr = parameter_copy_storage_ = new char[alloc_size];
89 20 : if (copy) {
90 : CopyTraceObjectParameter(&ptr, &name_);
91 : CopyTraceObjectParameter(&ptr, &scope_);
92 30 : for (int i = 0; i < num_args_; ++i) {
93 : CopyTraceObjectParameter(&ptr, &arg_names_[i]);
94 : }
95 : }
96 70 : for (int i = 0; i < num_args_; ++i) {
97 25 : if (arg_is_copy[i]) {
98 : CopyTraceObjectParameter(&ptr, &arg_values_[i].as_string);
99 : }
100 : }
101 : }
102 2076 : }
103 :
104 3998 : TraceObject::~TraceObject() { delete[] parameter_copy_storage_; }
105 :
106 405 : void TraceObject::UpdateDuration(int64_t timestamp, int64_t cpu_timestamp) {
107 405 : duration_ = timestamp - ts_;
108 405 : cpu_duration_ = cpu_timestamp - tts_;
109 405 : }
110 :
111 20 : 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 20 : pid_ = pid;
120 20 : tid_ = tid;
121 20 : phase_ = phase;
122 20 : category_enabled_flag_ = category_enabled_flag;
123 20 : name_ = name;
124 20 : scope_ = scope;
125 20 : id_ = id;
126 20 : bind_id_ = bind_id;
127 20 : num_args_ = num_args;
128 20 : flags_ = flags;
129 20 : ts_ = ts;
130 20 : tts_ = tts;
131 20 : duration_ = duration;
132 20 : cpu_duration_ = cpu_duration;
133 20 : }
134 :
135 : } // namespace tracing
136 : } // namespace platform
137 : } // namespace v8
|