OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/debug/trace_event.h" | 5 #include "base/debug/trace_event.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #if defined(OS_WIN) | 9 #if defined(OS_WIN) |
10 #include "base/debug/trace_event_win.h" | 10 #include "base/debug/trace_event_win.h" |
11 #endif | 11 #endif |
12 #include "base/format_macros.h" | 12 #include "base/format_macros.h" |
| 13 #include "base/json/json_reader.h" |
13 #include "base/memory/ref_counted_memory.h" | 14 #include "base/memory/ref_counted_memory.h" |
| 15 #include "base/memory/scoped_ptr.h" |
14 #include "base/process_util.h" | 16 #include "base/process_util.h" |
15 #include "base/stringprintf.h" | 17 #include "base/stringprintf.h" |
16 #include "base/threading/thread_local.h" | 18 #include "base/threading/thread_local.h" |
17 #include "base/utf_string_conversions.h" | 19 #include "base/utf_string_conversions.h" |
18 #include "base/stl_util.h" | 20 #include "base/stl_util.h" |
19 #include "base/time.h" | 21 #include "base/time.h" |
| 22 #include "base/values.h" |
20 | 23 |
21 #define USE_UNRELIABLE_NOW | 24 #define USE_UNRELIABLE_NOW |
22 | 25 |
23 namespace base { | 26 namespace base { |
24 namespace debug { | 27 namespace debug { |
25 | 28 |
26 // Controls the number of trace events we will buffer in-memory | 29 // Controls the number of trace events we will buffer in-memory |
27 // before throwing them away. | 30 // before throwing them away. |
28 const size_t kTraceEventBufferSize = 500000; | 31 const size_t kTraceEventBufferSize = 500000; |
29 const size_t kTraceEventBatchSize = 1000; | 32 const size_t kTraceEventBatchSize = 1000; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 case TRACE_EVENT_PHASE_END: | 122 case TRACE_EVENT_PHASE_END: |
120 return "E"; | 123 return "E"; |
121 case TRACE_EVENT_PHASE_METADATA: | 124 case TRACE_EVENT_PHASE_METADATA: |
122 return "M"; | 125 return "M"; |
123 default: | 126 default: |
124 NOTREACHED() << "Invalid phase argument"; | 127 NOTREACHED() << "Invalid phase argument"; |
125 return "?"; | 128 return "?"; |
126 } | 129 } |
127 } | 130 } |
128 | 131 |
| 132 TraceEventPhase GetPhaseFromStr(const char* phase) { |
| 133 switch(*phase) { |
| 134 case 'B': |
| 135 return TRACE_EVENT_PHASE_BEGIN; |
| 136 case 'I': |
| 137 return TRACE_EVENT_PHASE_INSTANT; |
| 138 case 'E': |
| 139 return TRACE_EVENT_PHASE_END; |
| 140 case 'M': |
| 141 return TRACE_EVENT_PHASE_METADATA; |
| 142 default: |
| 143 return TRACE_EVENT_PHASE_BEGIN; |
| 144 } |
| 145 } |
| 146 |
129 size_t GetAllocLength(const char* str) { return str ? strlen(str) + 1 : 0; } | 147 size_t GetAllocLength(const char* str) { return str ? strlen(str) + 1 : 0; } |
130 | 148 |
131 // Copies |*member| into |*buffer|, sets |*member| to point to this new | 149 // Copies |*member| into |*buffer|, sets |*member| to point to this new |
132 // location, and then advances |*buffer| by the amount written. | 150 // location, and then advances |*buffer| by the amount written. |
133 void CopyTraceEventParameter(char** buffer, | 151 void CopyTraceEventParameter(char** buffer, |
134 const char** member, | 152 const char** member, |
135 const char* end) { | 153 const char* end) { |
136 if (*member) { | 154 if (*member) { |
137 size_t written = strlcpy(*buffer, *member, end - *buffer) + 1; | 155 size_t written = strlcpy(*buffer, *member, end - *buffer) + 1; |
138 DCHECK_LE(static_cast<int>(written), end - *buffer); | 156 DCHECK_LE(static_cast<int>(written), end - *buffer); |
139 *member = *buffer; | 157 *member = *buffer; |
140 *buffer += written; | 158 *buffer += written; |
141 } | 159 } |
142 } | 160 } |
143 | 161 |
144 } // namespace | 162 } // namespace |
145 | 163 |
| 164 TestTraceEvent::TestTraceEvent() |
| 165 : pid_tid(0, 0), |
| 166 timestamp(0), |
| 167 phase(TRACE_EVENT_PHASE_BEGIN), |
| 168 associated_event(NULL) { |
| 169 } |
| 170 |
| 171 TestTraceEvent::TestTraceEvent(const base::Value* event_value) |
| 172 : pid_tid(0, 0), |
| 173 timestamp(0), |
| 174 phase(TRACE_EVENT_PHASE_BEGIN), |
| 175 associated_event(NULL) { |
| 176 if (event_value->GetType() != base::Value::TYPE_DICTIONARY) |
| 177 return; |
| 178 const base::DictionaryValue* dictionary = |
| 179 static_cast<const base::DictionaryValue*>(event_value); |
| 180 |
| 181 std::string phase_str; |
| 182 base::DictionaryValue* args = NULL; |
| 183 |
| 184 if (dictionary->GetInteger("pid", &pid_tid.pid) && |
| 185 dictionary->GetInteger("tid", &pid_tid.tid) && |
| 186 dictionary->GetDouble("ts", ×tamp) && |
| 187 dictionary->GetString("cat", &category) && |
| 188 dictionary->GetString("name", &name) && |
| 189 dictionary->GetString("ph", &phase_str) && |
| 190 dictionary->GetDictionary("args", &args)) { |
| 191 |
| 192 phase = GetPhaseFromStr(phase_str.c_str()); |
| 193 |
| 194 // For each argument, copy the type and create a TraceValue. |
| 195 base::DictionaryValue::key_iterator keyi = args->begin_keys(); |
| 196 for (; keyi != args->end_keys(); ++keyi) { |
| 197 std::string str; |
| 198 bool boolean = false; |
| 199 int int_num = 0; |
| 200 double double_num = 0.0; |
| 201 Value* value = NULL; |
| 202 if (args->GetWithoutPathExpansion(*keyi, &value)) { |
| 203 if (value->GetAsString(&str)) |
| 204 arg_strings[*keyi] = str; |
| 205 else if (value->GetAsInteger(&int_num)) |
| 206 arg_numbers[*keyi] = static_cast<double>(int_num); |
| 207 else if (value->GetAsBoolean(&boolean)) |
| 208 arg_numbers[*keyi] = static_cast<double>(boolean ? 1 : 0); |
| 209 else if (value->GetAsDouble(&double_num)) |
| 210 arg_numbers[*keyi] = double_num; |
| 211 } |
| 212 } |
| 213 } |
| 214 } |
| 215 |
| 216 TestTraceEvent::~TestTraceEvent() { |
| 217 } |
| 218 |
| 219 bool TestTraceEvent::ParseEventsFromJson(const std::string& json, |
| 220 std::vector<TestTraceEvent>* output) { |
| 221 scoped_ptr<base::Value> root; |
| 222 root.reset(base::JSONReader::Read(json, false)); |
| 223 |
| 224 ListValue* root_list = NULL; |
| 225 if (!root.get() || !root->GetAsList(&root_list)) |
| 226 return false; |
| 227 |
| 228 for (size_t i = 0; i < root_list->GetSize(); ++i) { |
| 229 Value* item = NULL; |
| 230 if (root_list->Get(i, &item)) |
| 231 output->push_back(TestTraceEvent(item)); |
| 232 } |
| 233 |
| 234 return true; |
| 235 } |
| 236 |
| 237 bool TestTraceEvent::GetDuration(double* duration) const { |
| 238 if (!associated_event) |
| 239 return false; |
| 240 |
| 241 if (phase == TRACE_EVENT_PHASE_BEGIN) { |
| 242 DCHECK(associated_event->phase == TRACE_EVENT_PHASE_END); |
| 243 *duration = associated_event->timestamp - timestamp; |
| 244 } else { |
| 245 DCHECK(phase == TRACE_EVENT_PHASE_END); |
| 246 DCHECK(associated_event->phase == TRACE_EVENT_PHASE_BEGIN); |
| 247 *duration = timestamp - associated_event->timestamp; |
| 248 } |
| 249 return true; |
| 250 } |
| 251 |
| 252 bool TestTraceEvent::IsArg(const std::string& name) const { |
| 253 return arg_numbers.find(name) != arg_numbers.end() || |
| 254 arg_strings.find(name) != arg_strings.end(); |
| 255 } |
| 256 |
| 257 bool TestTraceEvent::GetArgAsString(const std::string& name, |
| 258 std::string* arg) const { |
| 259 std::map<std::string, std::string>::const_iterator i = arg_strings.find(name); |
| 260 if (i != arg_strings.end()) { |
| 261 *arg = i->second; |
| 262 return true; |
| 263 } |
| 264 return false; |
| 265 } |
| 266 |
| 267 bool TestTraceEvent::GetArgAsNumber(const std::string& name, |
| 268 double* arg) const { |
| 269 std::map<std::string, double>::const_iterator i = arg_numbers.find(name); |
| 270 if (i != arg_numbers.end()) { |
| 271 *arg = i->second; |
| 272 return true; |
| 273 } |
| 274 return false; |
| 275 } |
| 276 |
| 277 void TestTraceEvent::SetAssociatedEvent(TestTraceEvent* event) { |
| 278 associated_event = event; |
| 279 event->associated_event = this; |
| 280 } |
| 281 |
146 TraceEvent::TraceEvent() | 282 TraceEvent::TraceEvent() |
147 : process_id_(0), | 283 : process_id_(0), |
148 thread_id_(0), | 284 thread_id_(0), |
149 phase_(TRACE_EVENT_PHASE_BEGIN), | 285 phase_(TRACE_EVENT_PHASE_BEGIN), |
150 category_(NULL), | 286 category_(NULL), |
151 name_(NULL) { | 287 name_(NULL) { |
152 arg_names_[0] = NULL; | 288 arg_names_[0] = NULL; |
153 arg_names_[1] = NULL; | 289 arg_names_[1] = NULL; |
154 } | 290 } |
155 | 291 |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 NULL, 0, NULL, 0, | 729 NULL, 0, NULL, 0, |
594 p_data_->threshold_begin_id, p_data_->threshold, | 730 p_data_->threshold_begin_id, p_data_->threshold, |
595 TraceLog::EVENT_FLAG_NONE); | 731 TraceLog::EVENT_FLAG_NONE); |
596 } | 732 } |
597 } | 733 } |
598 | 734 |
599 } // namespace internal | 735 } // namespace internal |
600 | 736 |
601 } // namespace debug | 737 } // namespace debug |
602 } // namespace base | 738 } // namespace base |
OLD | NEW |