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

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: 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 write, opcode=" << opcode;
101 }
102 read_succeeded = pickle_.ReadInt(&iter, &opcode);
103 }
104 DCHECK(begin_opcode_stack.empty());
105 }
106
107 void TracedValue::BeginDictionary() {
108 begin_opcodes_.push(BEGIN_DICTIONARY);
109 pickle_.WriteInt(BEGIN_DICTIONARY);
110 }
111
112 void TracedValue::PushDictionary(const char* key_in_parent_dict) {
113 // Named dictionaries are properties of dictionaries, the name is the key.
dsinclair 2013/08/08 14:07:28 The DCHECK_EQ(BEGIN_DICTIONARY, begin_opcodes_.to
rterrazas 2013/08/11 21:05:08 Done.
114 PushKeyToPickle(key_in_parent_dict);
115 begin_opcodes_.push(BEGIN_DICTIONARY);
116 pickle_.WriteInt(BEGIN_DICTIONARY);
117 }
118
119 void TracedValue::EndDictionary() {
120 DCHECK_EQ(BEGIN_DICTIONARY, begin_opcodes_.top());
121 begin_opcodes_.pop();
122 pickle_.WriteInt(END_DICTIONARY);
123 }
124
125 void TracedValue::BeginArray() {
126 begin_opcodes_.push(BEGIN_ARRAY);
127 pickle_.WriteInt(BEGIN_ARRAY);
128 }
129
130 void TracedValue::PushArray(const char* key_in_parent_dict) {
131 // Named arrays are properties of dictionaries, and the key of such property
132 // is key_in_parent_dict.
133 DCHECK_EQ(BEGIN_DICTIONARY, begin_opcodes_.top());
134 PushKeyToPickle(key_in_parent_dict);
135 begin_opcodes_.push(BEGIN_ARRAY);
136 pickle_.WriteInt(BEGIN_ARRAY);
137 }
138
139 void TracedValue::EndArray() {
140 DCHECK_EQ(BEGIN_ARRAY, begin_opcodes_.top());
141 begin_opcodes_.pop();
142
143 pickle_.WriteInt(END_ARRAY);
144 }
145
146 // These methods push stuff in the pickle either in dictionary or array
147 // blocks, it's the up to the publicaly exposed caller to check the state.
148 void TracedValue::PushKeyToPickle(const char* key) {
149 pickle_.WriteInt(KEY_AS_RAW_POINTER);
150 uintptr_t key_ptr = reinterpret_cast<uintptr_t>(key);
151 pickle_.WriteUIntPtr(key_ptr);
152 }
153
154 void TracedValue::PushValueToPickle(const char* value) {
155 pickle_.WriteInt(VALUE_AS_RAW_POINTER);
156 uintptr_t value_ptr = reinterpret_cast<uintptr_t>(value);
157 pickle_.WriteUIntPtr(value_ptr);
158 }
159
160 void TracedValue::PushValueToPickle(const std::string& value) {
161 pickle_.WriteInt(VALUE_AS_STRING);
162 pickle_.WriteString(value);
163 }
164
165 void TracedValue::PushValueToPickle(int value) {
166 pickle_.WriteInt(INT32_VALUE);
167 pickle_.WriteInt(value);
168 }
169
170 void TracedValue::PushValueToPickle(int64 value) {
171 pickle_.WriteInt(INT64_VALUE);
172 pickle_.WriteInt64(value);
173 }
174
175 void TracedValue::PushValueToPickle(uint32 value) {
176 pickle_.WriteInt(UINT32_VALUE);
177 pickle_.WriteUInt32(value);
178 }
179
180 void TracedValue::PushValueToPickle(uint64 value) {
181 pickle_.WriteInt(UINT64_VALUE);
182 pickle_.WriteUInt64(value);
183 }
184
185 void TracedValue::PushValueToPickle(float value) {
186 pickle_.WriteInt(FLOAT_VALUE);
187 pickle_.WriteFloat(value);
188 }
189
190 void TracedValue::PushValueToPickle(bool value) {
191 pickle_.WriteInt(BOOL_VALUE);
192 pickle_.WriteBool(value);
193 }
194
195 void TracedValue::PushValueToPickle(const TracedObject& value) {
196 // The definition of what gets pushed is in the implementation of
197 // TracedObject::PushInto().
198 value.PushInto(this);
199 }
200
201 // Helper methods used in AppendAsTraceFormat()
202 void TracedValue::AppendKeyAsRawPointer(std::string* out,
203 PickleIterator* iter) const {
204 uintptr_t out_ptr;
205 pickle_.ReadUIntPtr(iter, &out_ptr);
206 const char* key = reinterpret_cast<char*>(out_ptr);
207 JsonDoubleQuote(std::string(key), true, out);
208 out->append(":");
209 }
210
211 void TracedValue::AppendValueAsRawPointer(std::string* out,
212 PickleIterator* iter) const {
213 uintptr_t out_ptr;
214 pickle_.ReadUIntPtr(iter, &out_ptr);
215 const char* value = reinterpret_cast<char*>(out_ptr);
216 JsonDoubleQuote(std::string(value), true, out);
217 }
218
219 void TracedValue::AppendValueAsString(std::string* out,
220 PickleIterator* iter) const {
221 std::string out_string;
222 pickle_.ReadString(iter, &out_string);
223 JsonDoubleQuote(out_string, true, out);
224 }
225
226 void TracedValue::AppendValueAsInt32(std::string* out,
227 PickleIterator* iter) const {
228 int out_int;
229 pickle_.ReadInt(iter, &out_int);
230 StringAppendF(out, "%d", out_int);
231 }
232
233 void TracedValue::AppendValueAsInt64(std::string* out,
234 PickleIterator* iter) const {
235 int64 out_int64;
236 pickle_.ReadInt64(iter, &out_int64);
237 StringAppendF(out, "%" PRId64, out_int64);
238 }
239
240
241 void TracedValue::AppendValueAsUInt32(std::string* out,
242 PickleIterator* iter) const {
243 uint32 out_uint32;
244 pickle_.ReadUInt32(iter, &out_uint32);
245 StringAppendF(out, "%u", out_uint32);
246 }
247
248 void TracedValue::AppendValueAsUInt64(std::string* out,
249 PickleIterator* iter) const {
250 uint64 out_uint64;
251 pickle_.ReadUInt64(iter, &out_uint64);
252 StringAppendF(out, "%" PRIu64, out_uint64);
253 }
254
255 void TracedValue::AppendValueAsFloat(std::string* out,
256 PickleIterator* iter) const {
257 float out_float;
258 pickle_.ReadFloat(iter, &out_float);
259 out->append(base::JSONWriter::DoubleToFormattedString(out_float, false));
260 }
261
262 void TracedValue::AppendValueAsBool(std::string* out,
263 PickleIterator* iter) const {
264 bool out_bool;
265 pickle_.ReadBool(iter, &out_bool);
266 StringAppendF(out, "%s", out_bool ? "true" : "false");
267 }
268
269 // Static.
270 void TracedValue::AppendComma(std::string* out, Opcode begin_opcode,
271 Opcode current_opcode, int* element_count) {
272 // For arrays, we want to append a comma when the element count within
273 // the array is greater than zero and we are not about to close the array.
274 if (begin_opcode == BEGIN_ARRAY && current_opcode != END_ARRAY &&
275 (*element_count)++ > 0) {
276 StringAppendF(out, ",");
277 return;
278 }
279 // For dictionaries, we want to append a comma when the element count within
280 // the dictionary is greater than zero AND we're about to append is a key.
281 if (begin_opcode == BEGIN_DICTIONARY &&
282 current_opcode == KEY_AS_RAW_POINTER &&
283 (*element_count)++ > 0) {
284 StringAppendF(out, ",");
285 }
286 }
287
288 } // namespace debug
289 } // namespace base
290
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698