v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
traced-value.cc
Go to the documentation of this file.
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
6
8#include "src/base/vector.h"
10
11#ifdef V8_USE_PERFETTO
12#include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
13#endif
14
15namespace v8 {
16namespace tracing {
17
18namespace {
19
20#define DCHECK_CURRENT_CONTAINER_IS(x) DCHECK_EQ(x, nesting_stack_.back())
21#define DCHECK_CONTAINER_STACK_DEPTH_EQ(x) DCHECK_EQ(x, nesting_stack_.size())
22#ifdef DEBUG
23const bool kStackTypeDict = false;
24const bool kStackTypeArray = true;
25#define DEBUG_PUSH_CONTAINER(x) nesting_stack_.push_back(x)
26#define DEBUG_POP_CONTAINER() nesting_stack_.pop_back()
27#else
28#define DEBUG_PUSH_CONTAINER(x) ((void)0)
29#define DEBUG_POP_CONTAINER() ((void)0)
30#endif
31
32void EscapeAndAppendString(const char* value, std::string* result) {
33 *result += '"';
34 while (*value) {
35 unsigned char c = *value++;
36 switch (c) {
37 case '\b':
38 *result += "\\b";
39 break;
40 case '\f':
41 *result += "\\f";
42 break;
43 case '\n':
44 *result += "\\n";
45 break;
46 case '\r':
47 *result += "\\r";
48 break;
49 case '\t':
50 *result += "\\t";
51 break;
52 case '\"':
53 *result += "\\\"";
54 break;
55 case '\\':
56 *result += "\\\\";
57 break;
58 default:
59 if (c < '\x20' || c == '\x7F') {
60 char number_buffer[8];
61 base::OS::SNPrintF(number_buffer, arraysize(number_buffer), "\\u%04X",
62 static_cast<unsigned>(c));
63 *result += number_buffer;
64 } else {
65 *result += c;
66 }
67 }
68 }
69 *result += '"';
70}
71
72} // namespace
73
74// static
75std::unique_ptr<TracedValue> TracedValue::Create() {
76 return std::unique_ptr<TracedValue>(new TracedValue());
77}
78
79TracedValue::TracedValue() : first_item_(true) {
80 DEBUG_PUSH_CONTAINER(kStackTypeDict);
81}
82
88
89void TracedValue::SetInteger(const char* name, int value) {
90 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
91 WriteName(name);
92 data_ += std::to_string(value);
93}
94
95void TracedValue::SetUnsignedInteger(const char* name, uint64_t value) {
96 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
97 WriteName(name);
98 data_ += std::to_string(value);
99}
100
101void TracedValue::SetDouble(const char* name, double value) {
102 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
103 WriteName(name);
105 data_ += internal::DoubleToStringView(value, buffer);
106}
107
108void TracedValue::SetBoolean(const char* name, bool value) {
109 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
110 WriteName(name);
111 data_ += value ? "true" : "false";
112}
113
114void TracedValue::SetString(const char* name, const char* value) {
115 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
116 WriteName(name);
117 EscapeAndAppendString(value, &data_);
118}
119
120void TracedValue::SetValue(const char* name, TracedValue* value) {
121 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
122 WriteName(name);
123 std::string tmp;
124 value->AppendAsTraceFormat(&tmp);
125 data_ += tmp;
126}
127
128void TracedValue::BeginDictionary(const char* name) {
129 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
130 DEBUG_PUSH_CONTAINER(kStackTypeDict);
131 WriteName(name);
132 data_ += '{';
133 first_item_ = true;
134}
135
136void TracedValue::BeginArray(const char* name) {
137 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
138 DEBUG_PUSH_CONTAINER(kStackTypeArray);
139 WriteName(name);
140 data_ += '[';
141 first_item_ = true;
142}
143
145 DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
146 WriteComma();
147 data_ += std::to_string(value);
148}
149
150void TracedValue::AppendDouble(double value) {
151 DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
152 WriteComma();
154 data_ += internal::DoubleToStringView(value, buffer);
155}
156
158 DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
159 WriteComma();
160 data_ += value ? "true" : "false";
161}
162
163void TracedValue::AppendString(const char* value) {
164 DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
165 WriteComma();
166 EscapeAndAppendString(value, &data_);
167}
168
170 DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
171 DEBUG_PUSH_CONTAINER(kStackTypeDict);
172 WriteComma();
173 data_ += '{';
174 first_item_ = true;
175}
176
178 DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
179 DEBUG_PUSH_CONTAINER(kStackTypeArray);
180 WriteComma();
181 data_ += '[';
182 first_item_ = true;
183}
184
186 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
188 data_ += '}';
189 first_item_ = false;
190}
191
193 DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
195 data_ += ']';
196 first_item_ = false;
197}
198
200 if (first_item_) {
201 first_item_ = false;
202 } else {
203 data_ += ',';
204 }
205}
206
207void TracedValue::WriteName(const char* name) {
208 WriteComma();
209 data_ += '"';
210 data_ += name;
211 data_ += "\":";
212}
213
214void TracedValue::AppendAsTraceFormat(std::string* out) const {
215 *out += '{';
216 *out += data_;
217 *out += '}';
218}
219
220#ifdef V8_USE_PERFETTO
221void TracedValue::Add(
222 perfetto::protos::pbzero::DebugAnnotation* annotation) const {
223 std::string json;
224 json += "{";
225 json += data_;
226 json += "}";
227 annotation->set_legacy_json_value(json);
228}
229#endif // V8_USE_PERFETTO
230
231} // namespace tracing
232} // namespace v8
const char * name
Definition builtins.cc:39
void SetInteger(const char *name, int value)
void SetValue(const char *name, TracedValue *value)
void AppendString(const char *)
void SetUnsignedInteger(const char *name, uint64_t value)
void WriteName(const char *name)
void SetBoolean(const char *name, bool value)
void AppendAsTraceFormat(std::string *out) const override
void SetString(const char *name, const char *value)
void SetDouble(const char *name, double value)
static std::unique_ptr< TracedValue > Create()
ZoneVector< RpoNumber > & result
Register tmp
std::string_view DoubleToStringView(double v, base::Vector< char > buffer)
#define arraysize(array)
Definition macros.h:67
Symbol annotation
#define DEBUG_PUSH_CONTAINER(x)
#define DEBUG_POP_CONTAINER()
#define DCHECK_CONTAINER_STACK_DEPTH_EQ(x)
#define DCHECK_CURRENT_CONTAINER_IS(x)