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

Side by Side Diff: base/trace_event_value.cc

Issue 19642005: Make TracedValue lower overhead. Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fixed lint errors. Created 7 years, 5 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/strings/stringprintf.h"
6 #include "base/trace_event_value.h"
7
8 namespace base {
9
10 // Public
dsinclair 2013/07/23 14:56:29 nit: remove comment.
rterrazas 2013/08/01 08:01:26 Done.
11 TracedValue::TracedValue() {
12 }
13
14 TracedValue::~TracedValue() {
15 }
16
17 void TracedValue::AppendAsTraceFormat(std::string* out) const {
18 // Used to keep track of the opening opcode.
19 std::stack<Opcode> op_stack;
dsinclair 2013/07/23 14:56:29 I think this needs a different name, it's the curr
rterrazas 2013/08/01 08:01:26 Done.
20 // This is needed in case of nested structures.
21 std::stack<int> element_count_stack;
22 PickleIterator iter(pickle_);
23
24 int op_code;
25 bool read_succeeded = pickle_.ReadInt(&iter, &op_code);
26 while (read_succeeded) {
27 switch (op_code) {
28 case BEGIN_ARRAY:
29 case BEGIN_DICTIONARY:
30 {
31 // If this is a nested structure and not the first element, we need
32 // to prepend a comma.
dsinclair 2013/07/23 14:56:29 This is only for the array case? If so, can we mov
rterrazas 2013/08/01 08:01:26 This is really for the case when we are within an
33 if (!op_stack.empty() && op_stack.top() == BEGIN_ARRAY &&
34 element_count_stack.top() > 0)
35 StringAppendF(out, ", ");
dsinclair 2013/07/23 14:56:29 Isn't this, essentially AppendCommaInsideArray(out
rterrazas 2013/08/01 08:01:26 Done.
36
37 // Initialize the count for the current datastructure.
38 element_count_stack.push(0);
39 op_stack.push(static_cast<Opcode>(op_code));
40 StringAppendF(out, "{");
dsinclair 2013/07/23 14:56:29 An array in JSON is [] not {}. This would start a
rterrazas 2013/08/01 08:01:26 Done.
41 break;
42 }
43 case END_DICTIONARY:
44 case END_ARRAY:
45 {
46 op_stack.pop();
dsinclair 2013/07/23 14:56:29 nit: Move this down one line to keep with the elem
rterrazas 2013/08/01 08:01:26 Done.
47 StringAppendF(out, "}");
48 element_count_stack.pop();
49 break;
50 }
51 case KEY_AS_RAW_POINTER:
52 {
53 AppendCommaInsideDictionary(out, element_count_stack.top()++);
dsinclair 2013/07/23 14:56:29 Can we pull the AppendCommand methods outside of t
rterrazas 2013/08/01 08:01:26 Done.
54 AppendKeyAsRawPointer(out, &iter);
55 break;
56 }
57 case VALUE_AS_RAW_POINTER:
58 {
59 AppendCommaInsideArray(out, op_stack.top(),
60 element_count_stack.top()++);
61 AppendValueAsRawPointer(out, &iter);
62 break;
63 }
64 case VALUE_AS_STRING:
65 {
66 AppendCommaInsideArray(out, op_stack.top(),
67 element_count_stack.top()++);
68 AppendValueAsString(out, &iter);
69 break;
70 }
71 case INT32_VALUE:
72 {
73 AppendCommaInsideArray(out, op_stack.top(),
74 element_count_stack.top()++);
75 AppendValueAsInt32(out, &iter);
76 break;
77 }
78 case INT64_VALUE:
79 {
80 AppendCommaInsideArray(out, op_stack.top(),
81 element_count_stack.top()++);
82 AppendValueAsInt64(out, &iter);
83 break;
84 }
85 case UINT32_VALUE:
86 {
87 AppendCommaInsideArray(out, op_stack.top(),
88 element_count_stack.top()++);
89 AppendValueAsUInt32(out, &iter);
90 break;
91 }
92 case UINT64_VALUE:
93 {
94 AppendCommaInsideArray(out, op_stack.top(),
95 element_count_stack.top()++);
96 AppendValueAsUInt64(out, &iter);
97 break;
98 }
99 case FLOAT_VALUE:
100 {
101 AppendCommaInsideArray(out, op_stack.top(),
102 element_count_stack.top()++);
103 AppendValueAsFloat(out, &iter);
104 break;
105 }
106 case BOOL_VALUE:
107 {
108 AppendCommaInsideArray(out, op_stack.top(),
109 element_count_stack.top()++);
110 AppendValueAsBool(out, &iter);
111 break;
112 }
113 default:
114 NOTREACHED() << "Don't know what to read, opcode=" << op_code;
115 }
116 read_succeeded = pickle_.ReadInt(&iter, &op_code);
117 }
118 DCHECK(op_stack.empty());
119 }
120
121 void TracedValue::BeginDictionary(const char* key_in_parent_dict,
122 int size_of_key) {
123 // Named dictionaries are properties of dictionaries, the name is the key.
124 DCHECK_EQ(BEGIN_DICTIONARY, op_codes_.top());
125 PushKey(key_in_parent_dict, size_of_key);
126 op_codes_.push(BEGIN_DICTIONARY);
127 pickle_.WriteInt(BEGIN_DICTIONARY);
128 }
129
130 void TracedValue::BeginDictionary() {
131 op_codes_.push(BEGIN_DICTIONARY);
132 pickle_.WriteInt(BEGIN_DICTIONARY);
133 }
134
135 void TracedValue::EndDictionary() {
136 DCHECK_EQ(BEGIN_DICTIONARY, op_codes_.top());
137 op_codes_.pop();
138 pickle_.WriteInt(END_DICTIONARY);
139 }
140
141 void TracedValue::BeginArray(const char* key_in_parent_dict, int size_of_key) {
142 // Named arrays are properties of dictionaries, and the key of such property
143 // is key_in_parent_dict.
144 DCHECK_EQ(BEGIN_DICTIONARY, op_codes_.top());
145 PushKey(key_in_parent_dict, size_of_key);
146 op_codes_.push(BEGIN_ARRAY);
147 pickle_.WriteInt(BEGIN_ARRAY);
148 }
149
150 void TracedValue::BeginArray() {
151 op_codes_.push(BEGIN_ARRAY);
152 pickle_.WriteInt(BEGIN_ARRAY);
153 }
154
155 void TracedValue::EndArray() {
156 DCHECK_EQ(BEGIN_ARRAY, op_codes_.top());
157 op_codes_.pop();
158
159 pickle_.WriteInt(END_ARRAY);
160 }
161
162 // Dictionary push methods.
163 void TracedValue::Push(const char* key, int size_of_key,
164 const char* value, int size_of_value) {
165 PushKey(key, size_of_key);
166 PushValueToPickle(value, size_of_value);
167 }
dsinclair 2013/07/23 14:56:29 These are all the same and could be done with a ma
rterrazas 2013/08/01 08:01:26 Done.
168
169 void TracedValue::Push(const char* key, int size_of_key,
170 const std::string& value) {
171 PushKey(key, size_of_key);
172 PushValueToPickle(value);
173 }
174
175 void TracedValue::Push(const char* key, int size_of_key, int value) {
176 PushKey(key, size_of_key);
177 PushValueToPickle(value);
178 }
179
180 void TracedValue::Push(const char* key, int size_of_key, int64 value) {
181 PushKey(key, size_of_key);
182 PushValueToPickle(value);
183 }
184
185 void TracedValue::Push(const char* key, int size_of_key, uint32 value) {
186 PushKey(key, size_of_key);
187 PushValueToPickle(value);
188 }
189
190 void TracedValue::Push(const char* key, int size_of_key, uint64 value) {
191 PushKey(key, size_of_key);
192 PushValueToPickle(value);
193 }
194
195 void TracedValue::Push(const char* key, int size_of_key, double value) {
196 PushKey(key, size_of_key);
197 PushValueToPickle(value);
198 }
199
200 void TracedValue::Push(const char* key, int size_of_key, bool value) {
201 PushKey(key, size_of_key);
202 PushValueToPickle(value);
203 }
204
205 void TracedValue::Push(const char* key, int size_of_key,
206 const TracedObject& value) {
207 PushKey(key, size_of_key);
208 PushValueToPickle(value);
209 }
210
211 // Array Push methods.
212 void TracedValue::Push(const char* value, int size_of_value) {
213 DCHECK_EQ(BEGIN_ARRAY, op_codes_.top());
dsinclair 2013/07/23 14:56:29 Can be macro'ized same as dictionary ones.
rterrazas 2013/08/01 08:01:26 Done.
214 PushValueToPickle(value, size_of_value);
215 }
216
217 void TracedValue::Push(const std::string& value) {
218 DCHECK_EQ(BEGIN_ARRAY, op_codes_.top());
219 PushValueToPickle(value);
220 }
221
222 void TracedValue::Push(int value) {
223 DCHECK_EQ(BEGIN_ARRAY, op_codes_.top());
224 PushValueToPickle(value);
225 }
226
227 void TracedValue::Push(int64 value) {
228 DCHECK_EQ(BEGIN_ARRAY, op_codes_.top());
229 PushValueToPickle(value);
230 }
231
232 void TracedValue::Push(uint32 value) {
233 DCHECK_EQ(BEGIN_ARRAY, op_codes_.top());
234 PushValueToPickle(value);
235 }
236
237 void TracedValue::Push(uint64 value) {
238 DCHECK_EQ(BEGIN_ARRAY, op_codes_.top());
239 PushValueToPickle(value);
240 }
241
242 void TracedValue::Push(double value) {
243 DCHECK_EQ(BEGIN_ARRAY, op_codes_.top());
244 PushValueToPickle(value);
245 }
246
247 void TracedValue::Push(bool value) {
248 DCHECK_EQ(BEGIN_ARRAY, op_codes_.top());
249 PushValueToPickle(value);
250 }
251
252 void TracedValue::Push(const TracedObject& value) {
253 DCHECK_EQ(BEGIN_ARRAY, op_codes_.top());
254 PushValueToPickle(value);
255 }
256
257 // Private
dsinclair 2013/07/23 14:56:29 nit: remove.
rterrazas 2013/08/01 08:01:26 Done.
258
259 // These methods push stuff in the pickle either in dictionary or array
260 // blocks, it's the up to the publicly exposed caller to check the state.
261 void TracedValue::PushKey(const char* key, int size_of_key) {
262 // Check that we're writing a dictionary.
263 DCHECK_EQ(BEGIN_DICTIONARY, op_codes_.top());
264
265 pickle_.WriteInt(KEY_AS_RAW_POINTER);
266 pickle_.WriteData(key, size_of_key);
267 }
268
269 void TracedValue::PushValueToPickle(const char* value, int size_of_value) {
270 pickle_.WriteInt(VALUE_AS_RAW_POINTER);
271 pickle_.WriteData(value, size_of_value);
272 }
273
274 void TracedValue::PushValueToPickle(const std::string& value) {
275 pickle_.WriteInt(VALUE_AS_STRING);
276 pickle_.WriteString(value);
dsinclair 2013/07/23 14:56:29 The single param versions could be macro'ized.
rterrazas 2013/08/01 08:01:26 I actually think doing this would decrease readabi
277 }
278
279 void TracedValue::PushValueToPickle(int value) {
280 pickle_.WriteInt(INT32_VALUE);
281 pickle_.WriteInt(value);
282 }
283
284 void TracedValue::PushValueToPickle(int64 value) {
285 pickle_.WriteInt(INT64_VALUE);
286 pickle_.WriteInt64(value);
287 }
288
289 void TracedValue::PushValueToPickle(uint32 value) {
290 pickle_.WriteInt(UINT32_VALUE);
291 pickle_.WriteUInt32(value);
292 }
293
294 void TracedValue::PushValueToPickle(uint64 value) {
295 pickle_.WriteInt(UINT64_VALUE);
296 pickle_.WriteUInt64(value);
297 }
298
299 void TracedValue::PushValueToPickle(double value) {
300 pickle_.WriteInt(FLOAT_VALUE);
301 pickle_.WriteFloat(value);
302 }
303
304 void TracedValue::PushValueToPickle(bool value) {
305 pickle_.WriteInt(BOOL_VALUE);
306 pickle_.WriteBool(value);
307 }
308
309 void TracedValue::PushValueToPickle(const TracedObject& value) {
310 // The definition of what gets pushed is in the implementation of
311 // TracedObject::PushInto().
312 value.PushInto(this);
dsinclair 2013/07/23 14:56:29 I feel like TracedObject shouldn't be needed. Wha
rterrazas 2013/08/01 08:01:26 I was thinking that this could probably be used to
313 }
314
315 // Helper methods used in AppendAsTraceFormat()
316 void TracedValue::AppendKeyAsRawPointer(std::string* out,
317 PickleIterator* iter) const {
318 const char* out_data;
319 int out_length;
320 pickle_.ReadData(iter, &out_data, &out_length);
321 StringAppendF(out, "\"%s\": ", out_data);
322 }
323
324 void TracedValue::AppendKeyAsString(std::string* out,
325 PickleIterator* iter) const {
326 std::string out_string;
327 pickle_.ReadString(iter, &out_string);
328 StringAppendF(out, "\"%s\": ", out_string.c_str());
329 }
330
331 void TracedValue::AppendValueAsRawPointer(std::string* out,
332 PickleIterator* iter) const {
333 const char* out_data;
334 int out_length;
335 pickle_.ReadData(iter, &out_data, &out_length);
336 StringAppendF(out, "\"%s\"", out_data);
dsinclair 2013/07/23 14:56:29 This needs to handle strings with "'s in them.
rterrazas 2013/08/01 08:01:26 Done.
337 }
338
339 void TracedValue::AppendValueAsString(std::string* out,
340 PickleIterator* iter) const {
341 std::string out_string;
342 pickle_.ReadString(iter, &out_string);
343 StringAppendF(out, "\"%s\"", out_string.c_str());
dsinclair 2013/07/23 14:56:29 This needs to deal with strings with "'s in them.
rterrazas 2013/08/01 08:01:26 Done.
344 }
345
346 void TracedValue::AppendValueAsInt32(std::string* out,
347 PickleIterator* iter) const {
348 int out_int;
349 pickle_.ReadInt(iter, &out_int);
350 StringAppendF(out, "%d", out_int);
351 }
352
353 void TracedValue::AppendValueAsInt64(std::string* out,
354 PickleIterator* iter) const {
355 int64 out_int64;
356 pickle_.ReadInt64(iter, &out_int64);
357 StringAppendF(out, "%" PRId64, out_int64);
358 }
359
360
361 void TracedValue::AppendValueAsUInt32(std::string* out,
362 PickleIterator* iter) const {
363 uint32 out_uint32;
364 pickle_.ReadUInt32(iter, &out_uint32);
365 StringAppendF(out, "%u", out_uint32);
366 }
367
368 void TracedValue::AppendValueAsUInt64(std::string* out,
369 PickleIterator* iter) const {
370 uint64 out_uint64;
371 pickle_.ReadUInt64(iter, &out_uint64);
372 StringAppendF(out, "%" PRIu64, out_uint64);
373 }
374
375 void TracedValue::AppendValueAsFloat(std::string* out,
376 PickleIterator* iter) const {
377 float out_float;
378 pickle_.ReadFloat(iter, &out_float);
379 StringAppendF(out, "%f", out_float);
380 }
381
382 void TracedValue::AppendValueAsBool(std::string* out,
383 PickleIterator* iter) const {
384 bool out_bool;
385 pickle_.ReadBool(iter, &out_bool);
386 StringAppendF(out, "%s", out_bool ? "true" : "false");
387 }
388
389 // Static.
390 void TracedValue::AppendCommaInsideDictionary(std::string* out,
391 int element_index) {
392 if (element_index > 0)
393 StringAppendF(out, ", ");
394 }
395
396 // Static.
397 void TracedValue::AppendCommaInsideArray(std::string* out, Opcode past_opcode,
398 int element_index) {
399 if (past_opcode == BEGIN_ARRAY && element_index > 0)
400 StringAppendF(out, ", ");
401 }
402
403 } // namespace
dsinclair 2013/07/23 14:56:29 nit: // namespace base
rterrazas 2013/08/01 08:01:26 Done.
404
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698