Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: base/debug/trace_event_value.cc

Issue 19642005: Make TracedValue lower overhead. Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Validations for dictionary entries, CR comments, and additional check before writting. Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium 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 "base/debug/trace_event_value.h"
6 #include "base/json/json_writer.h"
7 #include "base/json/string_escape.h"
8 #include "base/strings/stringprintf.h"
9
10 namespace base {
11 namespace debug {
12
13 TracedValue::TracedValue() {
14 }
15
16 TracedValue::~TracedValue() {
17 }
18
19 void TracedValue::AppendAsTraceFormat(std::string* out) const {
20 DCHECK(begin_opcodes_.empty()) << "This TracedValue is not ready to be \
rterrazas 2013/08/11 21:05:08 Also added this check, as I think it can be helpfu
21 written, everything that was opened must be closed.";
22
23 // Used to keep track of the opening opcode.
24 std::stack<Opcode> begin_opcode_stack;
25 // This is needed in case of nested structures.
26 std::stack<int> element_count_stack;
27 PickleIterator iter(pickle_);
28
29 int opcode;
30 bool read_succeeded = pickle_.ReadInt(&iter, &opcode);
31 while (read_succeeded) {
32 // Append comma if necessary.
33 if (!begin_opcode_stack.empty()) {
34 DCHECK(!element_count_stack.empty());
35 AppendComma(out, begin_opcode_stack.top(),
36 static_cast<Opcode>(opcode), &element_count_stack.top());
37 }
38
39 switch (opcode) {
40 case BEGIN_ARRAY:
41 case BEGIN_DICTIONARY:
42 {
43 // Initialize the count for the current datastructure.
44 element_count_stack.push(0);
45 begin_opcode_stack.push(static_cast<Opcode>(opcode));
46 StringAppendF(out, opcode == BEGIN_DICTIONARY ? "{" : "[");
47 break;
48 }
49 case END_DICTIONARY:
50 case END_ARRAY:
51 {
52 begin_opcode_stack.pop();
53 element_count_stack.pop();
54 StringAppendF(out, opcode == END_DICTIONARY ? "}" : "]");
55 break;
56 }
57 case KEY_AS_RAW_POINTER:
58 {
59 AppendKeyAsRawPointer(out, &iter);
60 break;
61 }
62 case VALUE_AS_RAW_POINTER:
63 {
64 AppendValueAsRawPointer(out, &iter);
65 break;
66 }
67 case VALUE_AS_STRING:
68 {
69 AppendValueAsString(out, &iter);
70 break;
71 }
72 case INT32_VALUE:
73 {
74 AppendValueAsInt32(out, &iter);
75 break;
76 }
77 case INT64_VALUE:
78 {
79 AppendValueAsInt64(out, &iter);
80 break;
81 }
82 case UINT32_VALUE:
83 {
84 AppendValueAsUInt32(out, &iter);
85 break;
86 }
87 case UINT64_VALUE:
88 {
89 AppendValueAsUInt64(out, &iter);
90 break;
91 }
92 case FLOAT_VALUE:
93 {
94 AppendValueAsFloat(out, &iter);
95 break;
96 }
97 case BOOL_VALUE:
98 {
99 AppendValueAsBool(out, &iter);
100 break;
101 }
102 default:
103 NOTREACHED() << "Don't know what to write, opcode=" << opcode;
104 }
105 read_succeeded = pickle_.ReadInt(&iter, &opcode);
106 }
107 DCHECK(begin_opcode_stack.empty());
108 }
109
110 void TracedValue::BeginDictionary() {
111 // Cannot begin a dictionary within a dictionary. It can be the value of an
112 // entry, for that, use PushDictionary().
113 CheckNotWithinDictionary();
114 begin_opcodes_.push(BEGIN_DICTIONARY);
115 pickle_.WriteInt(BEGIN_DICTIONARY);
116 }
117
118 void TracedValue::EndDictionary() {
119 DCHECK_EQ(BEGIN_DICTIONARY, begin_opcodes_.top());
120 begin_opcodes_.pop();
121 pickle_.WriteInt(END_DICTIONARY);
122 }
123
124 void TracedValue::BeginArray() {
125 // Cannot begin an array within a dictionary. It can be the value of an entry,
126 // for that, use PushArray().
127 CheckNotWithinDictionary();
128 begin_opcodes_.push(BEGIN_ARRAY);
129 pickle_.WriteInt(BEGIN_ARRAY);
130 }
131
132 void TracedValue::EndArray() {
133 DCHECK_EQ(BEGIN_ARRAY, begin_opcodes_.top());
134 begin_opcodes_.pop();
135 pickle_.WriteInt(END_ARRAY);
136 }
137
138 void TracedValue::PushDictionary(const char* key_in_parent_dict) {
139 // Named dictionaries are properties of dictionaries, the name is the key.
140 DCHECK_EQ(BEGIN_DICTIONARY, begin_opcodes_.top());
141 PushKeyToPickle(key_in_parent_dict);
142 begin_opcodes_.push(BEGIN_DICTIONARY);
143 pickle_.WriteInt(BEGIN_DICTIONARY);
144 }
145
146 void TracedValue::PushArray(const char* key_in_parent_dict) {
147 // Named arrays are properties of dictionaries, and the key of such property
148 // is key_in_parent_dict.
149 DCHECK_EQ(BEGIN_DICTIONARY, begin_opcodes_.top());
150 PushKeyToPickle(key_in_parent_dict);
151 begin_opcodes_.push(BEGIN_ARRAY);
152 pickle_.WriteInt(BEGIN_ARRAY);
153 }
154
155 void TracedValue::BeginDictionaryEntry() {
156 DCHECK_EQ(BEGIN_DICTIONARY, begin_opcodes_.top());
157 // Make a note that we've started a dictionary entry.
158 begin_opcodes_.push(BEGIN_DICTIONARY_ENTRY);
159 }
160
161 void TracedValue::EndDictionaryEntry() {
162 DCHECK_EQ(BEGIN_DICTIONARY_ENTRY, begin_opcodes_.top());
163 begin_opcodes_.pop();
164 }
165
166 // These methods push stuff in the pickle either in dictionary or array
167 // blocks, it's the up to the publicaly exposed caller to check the state.
168 void TracedValue::PushKeyToPickle(const char* key) {
169 pickle_.WriteInt(KEY_AS_RAW_POINTER);
170 uintptr_t key_ptr = reinterpret_cast<uintptr_t>(key);
171 pickle_.WriteUIntPtr(key_ptr);
172 }
173
174 void TracedValue::PushValueToPickle(const char* value) {
175 pickle_.WriteInt(VALUE_AS_RAW_POINTER);
176 uintptr_t value_ptr = reinterpret_cast<uintptr_t>(value);
177 pickle_.WriteUIntPtr(value_ptr);
178 }
179
180 void TracedValue::PushValueToPickle(const std::string& value) {
181 pickle_.WriteInt(VALUE_AS_STRING);
182 pickle_.WriteString(value);
183 }
184
185 void TracedValue::PushValueToPickle(int value) {
186 pickle_.WriteInt(INT32_VALUE);
187 pickle_.WriteInt(value);
188 }
189
190 void TracedValue::PushValueToPickle(int64 value) {
191 pickle_.WriteInt(INT64_VALUE);
192 pickle_.WriteInt64(value);
193 }
194
195 void TracedValue::PushValueToPickle(uint32 value) {
196 pickle_.WriteInt(UINT32_VALUE);
197 pickle_.WriteUInt32(value);
198 }
199
200 void TracedValue::PushValueToPickle(uint64 value) {
201 pickle_.WriteInt(UINT64_VALUE);
202 pickle_.WriteUInt64(value);
203 }
204
205 void TracedValue::PushValueToPickle(float value) {
206 pickle_.WriteInt(FLOAT_VALUE);
207 pickle_.WriteFloat(value);
208 }
209
210 void TracedValue::PushValueToPickle(bool value) {
211 pickle_.WriteInt(BOOL_VALUE);
212 pickle_.WriteBool(value);
213 }
214
215 void TracedValue::PushValueToPickle(const TracedObject& value) {
216 // The definition of what gets pushed is in the implementation of
217 // TracedObject::PushInto().
218 value.PushInto(this);
219 }
220
221 // Helper methods used in AppendAsTraceFormat()
222 void TracedValue::AppendKeyAsRawPointer(std::string* out,
223 PickleIterator* iter) const {
224 uintptr_t out_ptr;
225 pickle_.ReadUIntPtr(iter, &out_ptr);
226 const char* key = reinterpret_cast<char*>(out_ptr);
227 JsonDoubleQuote(std::string(key), true, out);
228 out->append(":");
229 }
230
231 void TracedValue::AppendValueAsRawPointer(std::string* out,
232 PickleIterator* iter) const {
233 uintptr_t out_ptr;
234 pickle_.ReadUIntPtr(iter, &out_ptr);
235 const char* value = reinterpret_cast<char*>(out_ptr);
236 JsonDoubleQuote(std::string(value), true, out);
237 }
238
239 void TracedValue::AppendValueAsString(std::string* out,
240 PickleIterator* iter) const {
241 std::string out_string;
242 pickle_.ReadString(iter, &out_string);
243 JsonDoubleQuote(out_string, true, out);
244 }
245
246 void TracedValue::AppendValueAsInt32(std::string* out,
247 PickleIterator* iter) const {
248 int out_int;
249 pickle_.ReadInt(iter, &out_int);
250 StringAppendF(out, "%d", out_int);
251 }
252
253 void TracedValue::AppendValueAsInt64(std::string* out,
254 PickleIterator* iter) const {
255 int64 out_int64;
256 pickle_.ReadInt64(iter, &out_int64);
257 StringAppendF(out, "%" PRId64, out_int64);
258 }
259
260
261 void TracedValue::AppendValueAsUInt32(std::string* out,
262 PickleIterator* iter) const {
263 uint32 out_uint32;
264 pickle_.ReadUInt32(iter, &out_uint32);
265 StringAppendF(out, "%u", out_uint32);
266 }
267
268 void TracedValue::AppendValueAsUInt64(std::string* out,
269 PickleIterator* iter) const {
270 uint64 out_uint64;
271 pickle_.ReadUInt64(iter, &out_uint64);
272 StringAppendF(out, "%" PRIu64, out_uint64);
273 }
274
275 void TracedValue::AppendValueAsFloat(std::string* out,
276 PickleIterator* iter) const {
277 float out_float;
278 pickle_.ReadFloat(iter, &out_float);
279 out->append(base::JSONWriter::DoubleToFormattedString(out_float, false));
280 }
281
282 void TracedValue::AppendValueAsBool(std::string* out,
283 PickleIterator* iter) const {
284 bool out_bool;
285 pickle_.ReadBool(iter, &out_bool);
286 StringAppendF(out, "%s", out_bool ? "true" : "false");
287 }
288
289 void TracedValue::CheckNotWithinDictionary() {
290 if (!begin_opcodes_.empty())
dsinclair 2013/08/12 13:34:40 if (begin_opcodes_.empty()) return; DCHECK_NE(B
291 DCHECK_NE(BEGIN_DICTIONARY, begin_opcodes_.top());
292 }
293
294 // Static.
295 void TracedValue::AppendComma(std::string* out, Opcode begin_opcode,
296 Opcode current_opcode, int* element_count) {
297 // For arrays, we want to append a comma when the element count within
298 // the array is greater than zero and we are not about to close the array.
299 if (begin_opcode == BEGIN_ARRAY && current_opcode != END_ARRAY &&
300 (*element_count)++ > 0) {
301 StringAppendF(out, ",");
302 return;
303 }
304 // For dictionaries, we want to append a comma when the element count within
305 // the dictionary is greater than zero AND we're about to append is a key.
306 if (begin_opcode == BEGIN_DICTIONARY &&
307 current_opcode == KEY_AS_RAW_POINTER &&
308 (*element_count)++ > 0) {
309 StringAppendF(out, ",");
310 }
311 }
312
313 } // namespace debug
314 } // namespace base
315
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698