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 "src/tracing/traced-value.h"
6 :
7 : #include "src/base/platform/platform.h"
8 : #include "src/conversions.h"
9 : #include "src/vector.h"
10 :
11 : namespace v8 {
12 : namespace tracing {
13 :
14 : namespace {
15 :
16 : #define DCHECK_CURRENT_CONTAINER_IS(x) DCHECK_EQ(x, nesting_stack_.back())
17 : #define DCHECK_CONTAINER_STACK_DEPTH_EQ(x) DCHECK_EQ(x, nesting_stack_.size())
18 : #ifdef DEBUG
19 : const bool kStackTypeDict = false;
20 : const bool kStackTypeArray = true;
21 : #define DEBUG_PUSH_CONTAINER(x) nesting_stack_.push_back(x)
22 : #define DEBUG_POP_CONTAINER() nesting_stack_.pop_back()
23 : #else
24 : #define DEBUG_PUSH_CONTAINER(x) ((void)0)
25 : #define DEBUG_POP_CONTAINER() ((void)0)
26 : #endif
27 :
28 5748 : void EscapeAndAppendString(const char* value, std::string* result) {
29 : *result += '"';
30 61623 : while (*value) {
31 55875 : unsigned char c = *value++;
32 55875 : switch (c) {
33 : case '\b':
34 : *result += "\\b";
35 : break;
36 : case '\f':
37 : *result += "\\f";
38 : break;
39 : case '\n':
40 : *result += "\\n";
41 : break;
42 : case '\r':
43 : *result += "\\r";
44 : break;
45 : case '\t':
46 : *result += "\\t";
47 : break;
48 : case '\"':
49 : *result += "\\\"";
50 : break;
51 : case '\\':
52 : *result += "\\\\";
53 : break;
54 : default:
55 55810 : if (c < '\x20' || c == '\x7F') {
56 : char number_buffer[8];
57 140 : base::OS::SNPrintF(number_buffer, arraysize(number_buffer), "\\u%04X",
58 140 : static_cast<unsigned>(c));
59 : *result += number_buffer;
60 : } else {
61 : *result += c;
62 : }
63 : }
64 : }
65 : *result += '"';
66 5748 : }
67 :
68 : } // namespace
69 :
70 : // static
71 3459 : std::unique_ptr<TracedValue> TracedValue::Create() {
72 6918 : return std::unique_ptr<TracedValue>(new TracedValue());
73 : }
74 :
75 6918 : TracedValue::TracedValue() : first_item_(true) {
76 : DEBUG_PUSH_CONTAINER(kStackTypeDict);
77 0 : }
78 :
79 6918 : TracedValue::~TracedValue() {
80 : DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
81 : DEBUG_POP_CONTAINER();
82 : DCHECK_CONTAINER_STACK_DEPTH_EQ(0u);
83 3459 : }
84 :
85 18291 : void TracedValue::SetInteger(const char* name, int value) {
86 : DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
87 18291 : WriteName(name);
88 36582 : data_ += std::to_string(value);
89 18291 : }
90 :
91 2384 : void TracedValue::SetDouble(const char* name, double value) {
92 : DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
93 2384 : WriteName(name);
94 : i::EmbeddedVector<char, 100> buffer;
95 2384 : data_ += DoubleToCString(value, buffer);
96 2384 : }
97 :
98 20 : void TracedValue::SetBoolean(const char* name, bool value) {
99 : DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
100 20 : WriteName(name);
101 20 : data_ += value ? "true" : "false";
102 20 : }
103 :
104 5738 : void TracedValue::SetString(const char* name, const char* value) {
105 : DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
106 5738 : WriteName(name);
107 5738 : EscapeAndAppendString(value, &data_);
108 5738 : }
109 :
110 10 : void TracedValue::SetValue(const char* name, TracedValue* value) {
111 : DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
112 10 : WriteName(name);
113 : std::string tmp;
114 10 : value->AppendAsTraceFormat(&tmp);
115 10 : data_ += tmp;
116 10 : }
117 :
118 6222 : void TracedValue::BeginDictionary(const char* name) {
119 : DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
120 : DEBUG_PUSH_CONTAINER(kStackTypeDict);
121 6222 : WriteName(name);
122 6222 : data_ += '{';
123 6222 : first_item_ = true;
124 6222 : }
125 :
126 1689 : void TracedValue::BeginArray(const char* name) {
127 : DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
128 : DEBUG_PUSH_CONTAINER(kStackTypeArray);
129 1689 : WriteName(name);
130 1689 : data_ += '[';
131 1689 : first_item_ = true;
132 1689 : }
133 :
134 34724 : void TracedValue::AppendInteger(int value) {
135 : DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
136 : WriteComma();
137 69448 : data_ += std::to_string(value);
138 34724 : }
139 :
140 0 : void TracedValue::AppendDouble(double value) {
141 : DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
142 : WriteComma();
143 : i::EmbeddedVector<char, 100> buffer;
144 0 : data_ += DoubleToCString(value, buffer);
145 0 : }
146 :
147 5 : void TracedValue::AppendBoolean(bool value) {
148 : DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
149 : WriteComma();
150 5 : data_ += value ? "true" : "false";
151 5 : }
152 :
153 10 : void TracedValue::AppendString(const char* value) {
154 : DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
155 : WriteComma();
156 10 : EscapeAndAppendString(value, &data_);
157 10 : }
158 :
159 5188 : void TracedValue::BeginDictionary() {
160 : DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
161 : DEBUG_PUSH_CONTAINER(kStackTypeDict);
162 : WriteComma();
163 5188 : data_ += '{';
164 5188 : first_item_ = true;
165 5188 : }
166 :
167 5 : void TracedValue::BeginArray() {
168 : DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
169 : DEBUG_PUSH_CONTAINER(kStackTypeArray);
170 : WriteComma();
171 5 : data_ += '[';
172 5 : first_item_ = true;
173 5 : }
174 :
175 11410 : void TracedValue::EndDictionary() {
176 : DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
177 : DEBUG_POP_CONTAINER();
178 11410 : data_ += '}';
179 11410 : first_item_ = false;
180 11410 : }
181 :
182 1694 : void TracedValue::EndArray() {
183 : DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
184 : DEBUG_POP_CONTAINER();
185 1694 : data_ += ']';
186 1694 : first_item_ = false;
187 1694 : }
188 :
189 0 : void TracedValue::WriteComma() {
190 74286 : if (first_item_) {
191 16542 : first_item_ = false;
192 : } else {
193 57744 : data_ += ',';
194 : }
195 0 : }
196 :
197 34354 : void TracedValue::WriteName(const char* name) {
198 : WriteComma();
199 34354 : data_ += '"';
200 : data_ += name;
201 : data_ += "\":";
202 34354 : }
203 :
204 63 : void TracedValue::AppendAsTraceFormat(std::string* out) const {
205 : *out += '{';
206 : *out += data_;
207 : *out += '}';
208 63 : }
209 :
210 : } // namespace tracing
211 122004 : } // namespace v8
|