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

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: Added pickle unit test, cleaned up traced value's unit tests. 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 // Used to keep track of the opening opcode.
21 std::stack<Opcode> begin_opcode_stack;
22 // This is needed in case of nested structures.
23 std::stack<int> element_count_stack;
24 PickleIterator iter(pickle_);
25
26 int opcode;
27 bool read_succeeded = pickle_.ReadInt(&iter, &opcode);
28 while (read_succeeded) {
29 // Append comma if necessary.
30 if (!begin_opcode_stack.empty()) {
31 DCHECK(!element_count_stack.empty());
32 AppendComma(out, begin_opcode_stack.top(),
33 static_cast<Opcode>(opcode), &element_count_stack.top());
34 }
35
36 switch (opcode) {
37 case BEGIN_ARRAY:
38 case BEGIN_DICTIONARY:
39 {
40 // Initialize the count for the current datastructure.
41 element_count_stack.push(0);
42 begin_opcode_stack.push(static_cast<Opcode>(opcode));
43 StringAppendF(out, opcode == BEGIN_DICTIONARY ? "{" : "[");
44 break;
45 }
46 case END_DICTIONARY:
47 case END_ARRAY:
48 {
49 begin_opcode_stack.pop();
50 element_count_stack.pop();
51 StringAppendF(out, opcode == END_DICTIONARY ? "}" : "]");
52 break;
53 }
54 case KEY_AS_RAW_POINTER:
55 {
56 AppendKeyAsRawPointer(out, &iter);
57 break;
58 }
59 case VALUE_AS_RAW_POINTER:
60 {
61 AppendValueAsRawPointer(out, &iter);
62 break;
63 }
64 case VALUE_AS_STRING:
65 {
66 AppendValueAsString(out, &iter);
67 break;
68 }
69 case INT32_VALUE:
70 {
71 AppendValueAsInt32(out, &iter);
72 break;
73 }
74 case INT64_VALUE:
75 {
76 AppendValueAsInt64(out, &iter);
77 break;
78 }
79 case UINT32_VALUE:
80 {
81 AppendValueAsUInt32(out, &iter);
82 break;
83 }
84 case UINT64_VALUE:
85 {
86 AppendValueAsUInt64(out, &iter);
87 break;
88 }
89 case FLOAT_VALUE:
90 {
91 AppendValueAsFloat(out, &iter);
92 break;
93 }
94 case BOOL_VALUE:
95 {
96 AppendValueAsBool(out, &iter);
97 break;
98 }
99 default:
100 NOTREACHED() << "Don't know what to read, opcode=" << opcode;
dsinclair 2013/08/07 15:40:20 nit: s/read/write
rterrazas 2013/08/08 06:21:30 Done.
101 }
102 read_succeeded = pickle_.ReadInt(&iter, &opcode);
103 }
104 DCHECK(begin_opcode_stack.empty());
105 }
106
107 void TracedValue::BeginDictionary(const char* key_in_parent_dict) {
108 // Named dictionaries are properties of dictionaries, the name is the key.
109 DCHECK_EQ(BEGIN_DICTIONARY, begin_opcodes_.top());
110 PushKeyToPickle(key_in_parent_dict);
111 begin_opcodes_.push(BEGIN_DICTIONARY);
112 pickle_.WriteInt(BEGIN_DICTIONARY);
113 }
114
115 void TracedValue::BeginDictionary() {
116 begin_opcodes_.push(BEGIN_DICTIONARY);
dsinclair 2013/08/07 15:40:20 DCHECK_NEQ(BEGIN_DICTIONARY, begin_opcodes_.top())
rterrazas 2013/08/08 06:21:30 This would harm implementations of TracedObject, f
dsinclair 2013/08/08 14:07:28 I think you're going to need a third type on your
117 pickle_.WriteInt(BEGIN_DICTIONARY);
118 }
119
120 void TracedValue::EndDictionary() {
121 DCHECK_EQ(BEGIN_DICTIONARY, begin_opcodes_.top());
122 begin_opcodes_.pop();
123 pickle_.WriteInt(END_DICTIONARY);
124 }
125
126 void TracedValue::BeginArray(const char* key_in_parent_dict) {
127 // Named arrays are properties of dictionaries, and the key of such property
128 // is key_in_parent_dict.
129 DCHECK_EQ(BEGIN_DICTIONARY, begin_opcodes_.top());
130 PushKeyToPickle(key_in_parent_dict);
131 begin_opcodes_.push(BEGIN_ARRAY);
132 pickle_.WriteInt(BEGIN_ARRAY);
133 }
134
135 void TracedValue::BeginArray() {
136 begin_opcodes_.push(BEGIN_ARRAY);
dsinclair 2013/08/07 15:40:20 DCHECK_NEQ(BEGIN_DICTIONARY, begin_opcodes_.top()?
rterrazas 2013/08/08 06:21:30 Similarly to the dictionary case above, except the
137 pickle_.WriteInt(BEGIN_ARRAY);
138 }
139
140 void TracedValue::EndArray() {
141 DCHECK_EQ(BEGIN_ARRAY, begin_opcodes_.top());
142 begin_opcodes_.pop();
143
144 pickle_.WriteInt(END_ARRAY);
145 }
146
147 // These methods push stuff in the pickle either in dictionary or array
148 // blocks, it's the up to the publicly exposed caller to check the state.
dsinclair 2013/08/07 15:40:20 nit: s/publicly/publically
rterrazas 2013/08/08 06:21:30 Done.
149 void TracedValue::PushKeyToPickle(const char* key) {
150 // Check that we're writing a dictionary.
151 DCHECK_EQ(BEGIN_DICTIONARY, begin_opcodes_.top());
dsinclair 2013/08/07 15:40:20 The comment above says the caller checks the state
rterrazas 2013/08/08 06:21:30 Done.
152
153 pickle_.WriteInt(KEY_AS_RAW_POINTER);
154 uintptr_t key_ptr = reinterpret_cast<uintptr_t>(key);
155 pickle_.WriteUIntPtr(key_ptr);
156 }
157
158 void TracedValue::PushValueToPickle(const char* value) {
159 pickle_.WriteInt(VALUE_AS_RAW_POINTER);
160 uintptr_t value_ptr = reinterpret_cast<uintptr_t>(value);
161 pickle_.WriteUIntPtr(value_ptr);
162 }
163
164 void TracedValue::PushValueToPickle(const std::string& value) {
165 pickle_.WriteInt(VALUE_AS_STRING);
166 pickle_.WriteString(value);
167 }
168
169 void TracedValue::PushValueToPickle(int value) {
170 pickle_.WriteInt(INT32_VALUE);
171 pickle_.WriteInt(value);
172 }
173
174 void TracedValue::PushValueToPickle(int64 value) {
175 pickle_.WriteInt(INT64_VALUE);
176 pickle_.WriteInt64(value);
177 }
178
179 void TracedValue::PushValueToPickle(uint32 value) {
180 pickle_.WriteInt(UINT32_VALUE);
181 pickle_.WriteUInt32(value);
182 }
183
184 void TracedValue::PushValueToPickle(uint64 value) {
185 pickle_.WriteInt(UINT64_VALUE);
186 pickle_.WriteUInt64(value);
187 }
188
189 void TracedValue::PushValueToPickle(float value) {
190 pickle_.WriteInt(FLOAT_VALUE);
191 pickle_.WriteFloat(value);
192 }
193
194 void TracedValue::PushValueToPickle(bool value) {
195 pickle_.WriteInt(BOOL_VALUE);
196 pickle_.WriteBool(value);
197 }
198
199 void TracedValue::PushValueToPickle(const TracedObject& value) {
200 // The definition of what gets pushed is in the implementation of
201 // TracedObject::PushInto().
202 value.PushInto(this);
203 }
204
205 // Helper methods used in AppendAsTraceFormat()
206 void TracedValue::AppendKeyAsRawPointer(std::string* out,
207 PickleIterator* iter) const {
208 uintptr_t out_ptr;
209 pickle_.ReadUIntPtr(iter, &out_ptr);
210 const char* key = reinterpret_cast<char*>(out_ptr);
211 StringAppendF(out, "\"%s\":", key);
dsinclair 2013/08/07 15:40:20 Is it possible for key to have a " in it? If so, i
rterrazas 2013/08/08 06:21:30 Done.
212 }
213
214 void TracedValue::AppendKeyAsString(std::string* out,
215 PickleIterator* iter) const {
216 std::string out_string;
217 pickle_.ReadString(iter, &out_string);
218 StringAppendF(out, "\"%s\":", out_string.c_str());
dsinclair 2013/08/07 15:40:20 out_string.c_str() needs to escape any " character
rterrazas 2013/08/08 06:21:30 Done, actually, I removed this one, wasn't being u
219 }
220
221 void TracedValue::AppendValueAsRawPointer(std::string* out,
222 PickleIterator* iter) const {
223 uintptr_t out_ptr;
224 pickle_.ReadUIntPtr(iter, &out_ptr);
225 const char* value = reinterpret_cast<char*>(out_ptr);
226 JsonDoubleQuote(std::string(value), true, out);
227 }
228
229 void TracedValue::AppendValueAsString(std::string* out,
230 PickleIterator* iter) const {
231 std::string out_string;
232 pickle_.ReadString(iter, &out_string);
233 JsonDoubleQuote(out_string, true, out);
234 }
235
236 void TracedValue::AppendValueAsInt32(std::string* out,
237 PickleIterator* iter) const {
238 int out_int;
239 pickle_.ReadInt(iter, &out_int);
240 StringAppendF(out, "%d", out_int);
241 }
242
243 void TracedValue::AppendValueAsInt64(std::string* out,
244 PickleIterator* iter) const {
245 int64 out_int64;
246 pickle_.ReadInt64(iter, &out_int64);
247 StringAppendF(out, "%" PRId64, out_int64);
248 }
249
250
251 void TracedValue::AppendValueAsUInt32(std::string* out,
252 PickleIterator* iter) const {
253 uint32 out_uint32;
254 pickle_.ReadUInt32(iter, &out_uint32);
255 StringAppendF(out, "%u", out_uint32);
256 }
257
258 void TracedValue::AppendValueAsUInt64(std::string* out,
259 PickleIterator* iter) const {
260 uint64 out_uint64;
261 pickle_.ReadUInt64(iter, &out_uint64);
262 StringAppendF(out, "%" PRIu64, out_uint64);
263 }
264
265 void TracedValue::AppendValueAsFloat(std::string* out,
266 PickleIterator* iter) const {
267 float out_float;
268 pickle_.ReadFloat(iter, &out_float);
269 out->append(base::JSONWriter::DoubleToFormattedString(out_float,
270 false));
dsinclair 2013/08/07 15:40:20 nit: fits above.
rterrazas 2013/08/08 06:21:30 Done.
271 }
272
273 void TracedValue::AppendValueAsBool(std::string* out,
274 PickleIterator* iter) const {
275 bool out_bool;
276 pickle_.ReadBool(iter, &out_bool);
277 StringAppendF(out, "%s", out_bool ? "true" : "false");
278 }
279
280 // Static.
281 void TracedValue::AppendComma(std::string* out, Opcode begin_opcode,
282 Opcode current_opcode, int* element_count) {
283 // For arrays, we want to append a comma when the element count within
284 // the array is greater than zero and we are not about to close the array.
285 if (begin_opcode == BEGIN_ARRAY && current_opcode != END_ARRAY &&
286 (*element_count)++ > 0) {
287 StringAppendF(out, ",");
288 return;
289 }
290 // For dictionaries, we want to append a comma when the element count within
291 // the dictionary is greater than zero AND we're about to append is a key.
292 if (begin_opcode == BEGIN_DICTIONARY &&
293 current_opcode == KEY_AS_RAW_POINTER &&
294 (*element_count)++ > 0) {
295 StringAppendF(out, ",");
296 }
297 }
298
299 } // namespace debug
300 } // namespace base
301
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698