| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/globals.h" | 5 #include "platform/globals.h" |
| 6 #ifndef PRODUCT | 6 #ifndef PRODUCT |
| 7 | 7 |
| 8 #include <errno.h> | 8 #include <errno.h> |
| 9 #include <fcntl.h> | 9 #include <fcntl.h> |
| 10 #include <cstdlib> | 10 #include <cstdlib> |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 // cached block is being operated on. | 93 // cached block is being operated on. |
| 94 // - |Thread::thread_list_lock_| This lock is held when iterating over | 94 // - |Thread::thread_list_lock_| This lock is held when iterating over |
| 95 // |Thread|s. | 95 // |Thread|s. |
| 96 // | 96 // |
| 97 // Locks must always be taken in the following order: | 97 // Locks must always be taken in the following order: |
| 98 // |Thread::thread_list_lock_| | 98 // |Thread::thread_list_lock_| |
| 99 // |Thread::timeline_block_lock_| | 99 // |Thread::timeline_block_lock_| |
| 100 // |TimelineEventRecorder::lock_| | 100 // |TimelineEventRecorder::lock_| |
| 101 // | 101 // |
| 102 | 102 |
| 103 | |
| 104 static TimelineEventRecorder* CreateTimelineRecorder() { | 103 static TimelineEventRecorder* CreateTimelineRecorder() { |
| 105 // Some flags require that we use the endless recorder. | 104 // Some flags require that we use the endless recorder. |
| 106 const bool use_endless_recorder = | 105 const bool use_endless_recorder = |
| 107 (FLAG_timeline_dir != NULL) || FLAG_timing || FLAG_complete_timeline; | 106 (FLAG_timeline_dir != NULL) || FLAG_timing || FLAG_complete_timeline; |
| 108 | 107 |
| 109 const bool use_startup_recorder = FLAG_startup_timeline; | 108 const bool use_startup_recorder = FLAG_startup_timeline; |
| 110 const bool use_systrace_recorder = FLAG_systrace_timeline; | 109 const bool use_systrace_recorder = FLAG_systrace_timeline; |
| 111 | 110 |
| 112 const char* flag = FLAG_timeline_recorder; | 111 const char* flag = FLAG_timeline_recorder; |
| 113 | 112 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 143 } | 142 } |
| 144 | 143 |
| 145 if (FLAG_trace_timeline) { | 144 if (FLAG_trace_timeline) { |
| 146 THR_Print("Using the ring timeline recorder.\n"); | 145 THR_Print("Using the ring timeline recorder.\n"); |
| 147 } | 146 } |
| 148 | 147 |
| 149 // Always fall back to the ring recorder. | 148 // Always fall back to the ring recorder. |
| 150 return new TimelineEventRingRecorder(); | 149 return new TimelineEventRingRecorder(); |
| 151 } | 150 } |
| 152 | 151 |
| 153 | |
| 154 // Returns a caller freed array of stream names in FLAG_timeline_streams. | 152 // Returns a caller freed array of stream names in FLAG_timeline_streams. |
| 155 static MallocGrowableArray<char*>* GetEnabledByDefaultTimelineStreams() { | 153 static MallocGrowableArray<char*>* GetEnabledByDefaultTimelineStreams() { |
| 156 MallocGrowableArray<char*>* result = new MallocGrowableArray<char*>(); | 154 MallocGrowableArray<char*>* result = new MallocGrowableArray<char*>(); |
| 157 if (FLAG_timeline_streams == NULL) { | 155 if (FLAG_timeline_streams == NULL) { |
| 158 // Nothing set. | 156 // Nothing set. |
| 159 return result; | 157 return result; |
| 160 } | 158 } |
| 161 char* save_ptr; // Needed for strtok_r. | 159 char* save_ptr; // Needed for strtok_r. |
| 162 // strtok modifies arg 1 so we make a copy of it. | 160 // strtok modifies arg 1 so we make a copy of it. |
| 163 char* streams = strdup(FLAG_timeline_streams); | 161 char* streams = strdup(FLAG_timeline_streams); |
| 164 char* token = strtok_r(streams, ",", &save_ptr); | 162 char* token = strtok_r(streams, ",", &save_ptr); |
| 165 while (token != NULL) { | 163 while (token != NULL) { |
| 166 result->Add(strdup(token)); | 164 result->Add(strdup(token)); |
| 167 token = strtok_r(NULL, ",", &save_ptr); | 165 token = strtok_r(NULL, ",", &save_ptr); |
| 168 } | 166 } |
| 169 free(streams); | 167 free(streams); |
| 170 return result; | 168 return result; |
| 171 } | 169 } |
| 172 | 170 |
| 173 | |
| 174 // Frees the result of |GetEnabledByDefaultTimelineStreams|. | 171 // Frees the result of |GetEnabledByDefaultTimelineStreams|. |
| 175 static void FreeEnabledByDefaultTimelineStreams( | 172 static void FreeEnabledByDefaultTimelineStreams( |
| 176 MallocGrowableArray<char*>* streams) { | 173 MallocGrowableArray<char*>* streams) { |
| 177 if (streams == NULL) { | 174 if (streams == NULL) { |
| 178 return; | 175 return; |
| 179 } | 176 } |
| 180 for (intptr_t i = 0; i < streams->length(); i++) { | 177 for (intptr_t i = 0; i < streams->length(); i++) { |
| 181 free((*streams)[i]); | 178 free((*streams)[i]); |
| 182 } | 179 } |
| 183 delete streams; | 180 delete streams; |
| 184 } | 181 } |
| 185 | 182 |
| 186 | |
| 187 // Returns true if |streams| contains |stream| or "all". Not case sensitive. | 183 // Returns true if |streams| contains |stream| or "all". Not case sensitive. |
| 188 static bool HasStream(MallocGrowableArray<char*>* streams, const char* stream) { | 184 static bool HasStream(MallocGrowableArray<char*>* streams, const char* stream) { |
| 189 if ((FLAG_timeline_dir != NULL) || FLAG_timing || FLAG_complete_timeline || | 185 if ((FLAG_timeline_dir != NULL) || FLAG_timing || FLAG_complete_timeline || |
| 190 FLAG_startup_timeline) { | 186 FLAG_startup_timeline) { |
| 191 return true; | 187 return true; |
| 192 } | 188 } |
| 193 for (intptr_t i = 0; i < streams->length(); i++) { | 189 for (intptr_t i = 0; i < streams->length(); i++) { |
| 194 const char* checked_stream = (*streams)[i]; | 190 const char* checked_stream = (*streams)[i]; |
| 195 if ((strstr(checked_stream, "all") != NULL) || | 191 if ((strstr(checked_stream, "all") != NULL) || |
| 196 (strstr(checked_stream, stream) != NULL)) { | 192 (strstr(checked_stream, stream) != NULL)) { |
| 197 return true; | 193 return true; |
| 198 } | 194 } |
| 199 } | 195 } |
| 200 return false; | 196 return false; |
| 201 } | 197 } |
| 202 | 198 |
| 203 | |
| 204 void Timeline::InitOnce() { | 199 void Timeline::InitOnce() { |
| 205 ASSERT(recorder_ == NULL); | 200 ASSERT(recorder_ == NULL); |
| 206 recorder_ = CreateTimelineRecorder(); | 201 recorder_ = CreateTimelineRecorder(); |
| 207 ASSERT(recorder_ != NULL); | 202 ASSERT(recorder_ != NULL); |
| 208 enabled_streams_ = GetEnabledByDefaultTimelineStreams(); | 203 enabled_streams_ = GetEnabledByDefaultTimelineStreams(); |
| 209 // Global overrides. | 204 // Global overrides. |
| 210 #define TIMELINE_STREAM_FLAG_DEFAULT(name, not_used) \ | 205 #define TIMELINE_STREAM_FLAG_DEFAULT(name, not_used) \ |
| 211 stream_##name##_.Init(#name, HasStream(enabled_streams_, #name)); | 206 stream_##name##_.Init(#name, HasStream(enabled_streams_, #name)); |
| 212 TIMELINE_STREAM_LIST(TIMELINE_STREAM_FLAG_DEFAULT) | 207 TIMELINE_STREAM_LIST(TIMELINE_STREAM_FLAG_DEFAULT) |
| 213 #undef TIMELINE_STREAM_FLAG_DEFAULT | 208 #undef TIMELINE_STREAM_FLAG_DEFAULT |
| 214 | 209 |
| 215 if (Timeline::stream_Embedder_.enabled() && | 210 if (Timeline::stream_Embedder_.enabled() && |
| 216 (Timeline::get_start_recording_cb() != NULL)) { | 211 (Timeline::get_start_recording_cb() != NULL)) { |
| 217 Timeline::get_start_recording_cb()(); | 212 Timeline::get_start_recording_cb()(); |
| 218 } | 213 } |
| 219 } | 214 } |
| 220 | 215 |
| 221 | |
| 222 void Timeline::StreamStateChange(const char* stream_name, | 216 void Timeline::StreamStateChange(const char* stream_name, |
| 223 bool prev, | 217 bool prev, |
| 224 bool curr) { | 218 bool curr) { |
| 225 if (prev == curr) { | 219 if (prev == curr) { |
| 226 return; | 220 return; |
| 227 } | 221 } |
| 228 if (strcmp(stream_name, "Embedder") == 0) { | 222 if (strcmp(stream_name, "Embedder") == 0) { |
| 229 if (curr && (Timeline::get_start_recording_cb() != NULL)) { | 223 if (curr && (Timeline::get_start_recording_cb() != NULL)) { |
| 230 Timeline::get_start_recording_cb()(); | 224 Timeline::get_start_recording_cb()(); |
| 231 } else if (!curr && (Timeline::get_stop_recording_cb() != NULL)) { | 225 } else if (!curr && (Timeline::get_stop_recording_cb() != NULL)) { |
| 232 Timeline::get_stop_recording_cb()(); | 226 Timeline::get_stop_recording_cb()(); |
| 233 } | 227 } |
| 234 } | 228 } |
| 235 } | 229 } |
| 236 | 230 |
| 237 | |
| 238 void Timeline::Shutdown() { | 231 void Timeline::Shutdown() { |
| 239 ASSERT(recorder_ != NULL); | 232 ASSERT(recorder_ != NULL); |
| 240 | 233 |
| 241 if (Timeline::stream_Embedder_.enabled() && | 234 if (Timeline::stream_Embedder_.enabled() && |
| 242 (Timeline::get_stop_recording_cb() != NULL)) { | 235 (Timeline::get_stop_recording_cb() != NULL)) { |
| 243 Timeline::get_stop_recording_cb()(); | 236 Timeline::get_stop_recording_cb()(); |
| 244 } | 237 } |
| 245 | 238 |
| 246 if (FLAG_timeline_dir != NULL) { | 239 if (FLAG_timeline_dir != NULL) { |
| 247 recorder_->WriteTo(FLAG_timeline_dir); | 240 recorder_->WriteTo(FLAG_timeline_dir); |
| 248 } | 241 } |
| 249 | 242 |
| 250 // Disable global streams. | 243 // Disable global streams. |
| 251 #define TIMELINE_STREAM_DISABLE(name, not_used) \ | 244 #define TIMELINE_STREAM_DISABLE(name, not_used) \ |
| 252 Timeline::stream_##name##_.set_enabled(false); | 245 Timeline::stream_##name##_.set_enabled(false); |
| 253 TIMELINE_STREAM_LIST(TIMELINE_STREAM_DISABLE) | 246 TIMELINE_STREAM_LIST(TIMELINE_STREAM_DISABLE) |
| 254 #undef TIMELINE_STREAM_DISABLE | 247 #undef TIMELINE_STREAM_DISABLE |
| 255 delete recorder_; | 248 delete recorder_; |
| 256 recorder_ = NULL; | 249 recorder_ = NULL; |
| 257 if (enabled_streams_ != NULL) { | 250 if (enabled_streams_ != NULL) { |
| 258 FreeEnabledByDefaultTimelineStreams(enabled_streams_); | 251 FreeEnabledByDefaultTimelineStreams(enabled_streams_); |
| 259 enabled_streams_ = NULL; | 252 enabled_streams_ = NULL; |
| 260 } | 253 } |
| 261 } | 254 } |
| 262 | 255 |
| 263 | |
| 264 TimelineEventRecorder* Timeline::recorder() { | 256 TimelineEventRecorder* Timeline::recorder() { |
| 265 return recorder_; | 257 return recorder_; |
| 266 } | 258 } |
| 267 | 259 |
| 268 | |
| 269 void Timeline::ReclaimCachedBlocksFromThreads() { | 260 void Timeline::ReclaimCachedBlocksFromThreads() { |
| 270 TimelineEventRecorder* recorder = Timeline::recorder(); | 261 TimelineEventRecorder* recorder = Timeline::recorder(); |
| 271 if (recorder == NULL) { | 262 if (recorder == NULL) { |
| 272 return; | 263 return; |
| 273 } | 264 } |
| 274 | 265 |
| 275 // Iterate over threads. | 266 // Iterate over threads. |
| 276 OSThreadIterator it; | 267 OSThreadIterator it; |
| 277 while (it.HasNext()) { | 268 while (it.HasNext()) { |
| 278 OSThread* thread = it.Next(); | 269 OSThread* thread = it.Next(); |
| 279 MutexLocker ml(thread->timeline_block_lock()); | 270 MutexLocker ml(thread->timeline_block_lock()); |
| 280 // Grab block and clear it. | 271 // Grab block and clear it. |
| 281 TimelineEventBlock* block = thread->timeline_block(); | 272 TimelineEventBlock* block = thread->timeline_block(); |
| 282 thread->set_timeline_block(NULL); | 273 thread->set_timeline_block(NULL); |
| 283 // TODO(johnmccutchan): Consider dropping the timeline_block_lock here | 274 // TODO(johnmccutchan): Consider dropping the timeline_block_lock here |
| 284 // if we can do it everywhere. This would simplify the lock ordering | 275 // if we can do it everywhere. This would simplify the lock ordering |
| 285 // requirements. | 276 // requirements. |
| 286 recorder->FinishBlock(block); | 277 recorder->FinishBlock(block); |
| 287 } | 278 } |
| 288 } | 279 } |
| 289 | 280 |
| 290 | |
| 291 void Timeline::PrintFlagsToJSON(JSONStream* js) { | 281 void Timeline::PrintFlagsToJSON(JSONStream* js) { |
| 292 JSONObject obj(js); | 282 JSONObject obj(js); |
| 293 obj.AddProperty("type", "TimelineFlags"); | 283 obj.AddProperty("type", "TimelineFlags"); |
| 294 TimelineEventRecorder* recorder = Timeline::recorder(); | 284 TimelineEventRecorder* recorder = Timeline::recorder(); |
| 295 if (recorder == NULL) { | 285 if (recorder == NULL) { |
| 296 obj.AddProperty("recorderName", "null"); | 286 obj.AddProperty("recorderName", "null"); |
| 297 } else { | 287 } else { |
| 298 obj.AddProperty("recorderName", recorder->name()); | 288 obj.AddProperty("recorderName", recorder->name()); |
| 299 } | 289 } |
| 300 { | 290 { |
| 301 JSONArray availableStreams(&obj, "availableStreams"); | 291 JSONArray availableStreams(&obj, "availableStreams"); |
| 302 #define ADD_STREAM_NAME(name, not_used) availableStreams.AddValue(#name); | 292 #define ADD_STREAM_NAME(name, not_used) availableStreams.AddValue(#name); |
| 303 TIMELINE_STREAM_LIST(ADD_STREAM_NAME); | 293 TIMELINE_STREAM_LIST(ADD_STREAM_NAME); |
| 304 #undef ADD_STREAM_NAME | 294 #undef ADD_STREAM_NAME |
| 305 } | 295 } |
| 306 { | 296 { |
| 307 JSONArray recordedStreams(&obj, "recordedStreams"); | 297 JSONArray recordedStreams(&obj, "recordedStreams"); |
| 308 #define ADD_RECORDED_STREAM_NAME(name, not_used) \ | 298 #define ADD_RECORDED_STREAM_NAME(name, not_used) \ |
| 309 if (stream_##name##_.enabled()) { \ | 299 if (stream_##name##_.enabled()) { \ |
| 310 recordedStreams.AddValue(#name); \ | 300 recordedStreams.AddValue(#name); \ |
| 311 } | 301 } |
| 312 TIMELINE_STREAM_LIST(ADD_RECORDED_STREAM_NAME); | 302 TIMELINE_STREAM_LIST(ADD_RECORDED_STREAM_NAME); |
| 313 #undef ADD_RECORDED_STREAM_NAME | 303 #undef ADD_RECORDED_STREAM_NAME |
| 314 } | 304 } |
| 315 } | 305 } |
| 316 | 306 |
| 317 | |
| 318 void Timeline::Clear() { | 307 void Timeline::Clear() { |
| 319 TimelineEventRecorder* recorder = Timeline::recorder(); | 308 TimelineEventRecorder* recorder = Timeline::recorder(); |
| 320 if (recorder == NULL) { | 309 if (recorder == NULL) { |
| 321 return; | 310 return; |
| 322 } | 311 } |
| 323 ReclaimCachedBlocksFromThreads(); | 312 ReclaimCachedBlocksFromThreads(); |
| 324 recorder->Clear(); | 313 recorder->Clear(); |
| 325 } | 314 } |
| 326 | 315 |
| 327 | |
| 328 TimelineEventRecorder* Timeline::recorder_ = NULL; | 316 TimelineEventRecorder* Timeline::recorder_ = NULL; |
| 329 MallocGrowableArray<char*>* Timeline::enabled_streams_ = NULL; | 317 MallocGrowableArray<char*>* Timeline::enabled_streams_ = NULL; |
| 330 Dart_EmbedderTimelineStartRecording Timeline::start_recording_cb_ = NULL; | 318 Dart_EmbedderTimelineStartRecording Timeline::start_recording_cb_ = NULL; |
| 331 Dart_EmbedderTimelineStopRecording Timeline::stop_recording_cb_ = NULL; | 319 Dart_EmbedderTimelineStopRecording Timeline::stop_recording_cb_ = NULL; |
| 332 | 320 |
| 333 #define TIMELINE_STREAM_DEFINE(name, enabled_by_default) \ | 321 #define TIMELINE_STREAM_DEFINE(name, enabled_by_default) \ |
| 334 TimelineStream Timeline::stream_##name##_; | 322 TimelineStream Timeline::stream_##name##_; |
| 335 TIMELINE_STREAM_LIST(TIMELINE_STREAM_DEFINE) | 323 TIMELINE_STREAM_LIST(TIMELINE_STREAM_DEFINE) |
| 336 #undef TIMELINE_STREAM_DEFINE | 324 #undef TIMELINE_STREAM_DEFINE |
| 337 | 325 |
| 338 TimelineEvent::TimelineEvent() | 326 TimelineEvent::TimelineEvent() |
| 339 : timestamp0_(0), | 327 : timestamp0_(0), |
| 340 timestamp1_(0), | 328 timestamp1_(0), |
| 341 thread_timestamp0_(-1), | 329 thread_timestamp0_(-1), |
| 342 thread_timestamp1_(-1), | 330 thread_timestamp1_(-1), |
| 343 arguments_(NULL), | 331 arguments_(NULL), |
| 344 arguments_length_(0), | 332 arguments_length_(0), |
| 345 state_(0), | 333 state_(0), |
| 346 label_(NULL), | 334 label_(NULL), |
| 347 category_(""), | 335 category_(""), |
| 348 thread_(OSThread::kInvalidThreadId), | 336 thread_(OSThread::kInvalidThreadId), |
| 349 isolate_id_(ILLEGAL_PORT) {} | 337 isolate_id_(ILLEGAL_PORT) {} |
| 350 | 338 |
| 351 | |
| 352 TimelineEvent::~TimelineEvent() { | 339 TimelineEvent::~TimelineEvent() { |
| 353 Reset(); | 340 Reset(); |
| 354 } | 341 } |
| 355 | 342 |
| 356 | |
| 357 void TimelineEvent::Reset() { | 343 void TimelineEvent::Reset() { |
| 358 if (owns_label() && label_ != NULL) { | 344 if (owns_label() && label_ != NULL) { |
| 359 free(const_cast<char*>(label_)); | 345 free(const_cast<char*>(label_)); |
| 360 } | 346 } |
| 361 state_ = 0; | 347 state_ = 0; |
| 362 thread_ = OSThread::kInvalidThreadId; | 348 thread_ = OSThread::kInvalidThreadId; |
| 363 isolate_id_ = ILLEGAL_PORT; | 349 isolate_id_ = ILLEGAL_PORT; |
| 364 category_ = ""; | 350 category_ = ""; |
| 365 label_ = NULL; | 351 label_ = NULL; |
| 366 FreeArguments(); | 352 FreeArguments(); |
| 367 set_pre_serialized_json(false); | 353 set_pre_serialized_json(false); |
| 368 set_event_type(kNone); | 354 set_event_type(kNone); |
| 369 set_owns_label(false); | 355 set_owns_label(false); |
| 370 } | 356 } |
| 371 | 357 |
| 372 | |
| 373 void TimelineEvent::AsyncBegin(const char* label, | 358 void TimelineEvent::AsyncBegin(const char* label, |
| 374 int64_t async_id, | 359 int64_t async_id, |
| 375 int64_t micros) { | 360 int64_t micros) { |
| 376 Init(kAsyncBegin, label); | 361 Init(kAsyncBegin, label); |
| 377 set_timestamp0(micros); | 362 set_timestamp0(micros); |
| 378 // Overload timestamp1_ with the async_id. | 363 // Overload timestamp1_ with the async_id. |
| 379 set_timestamp1(async_id); | 364 set_timestamp1(async_id); |
| 380 } | 365 } |
| 381 | 366 |
| 382 | |
| 383 void TimelineEvent::AsyncInstant(const char* label, | 367 void TimelineEvent::AsyncInstant(const char* label, |
| 384 int64_t async_id, | 368 int64_t async_id, |
| 385 int64_t micros) { | 369 int64_t micros) { |
| 386 Init(kAsyncInstant, label); | 370 Init(kAsyncInstant, label); |
| 387 set_timestamp0(micros); | 371 set_timestamp0(micros); |
| 388 // Overload timestamp1_ with the async_id. | 372 // Overload timestamp1_ with the async_id. |
| 389 set_timestamp1(async_id); | 373 set_timestamp1(async_id); |
| 390 } | 374 } |
| 391 | 375 |
| 392 | |
| 393 void TimelineEvent::AsyncEnd(const char* label, | 376 void TimelineEvent::AsyncEnd(const char* label, |
| 394 int64_t async_id, | 377 int64_t async_id, |
| 395 int64_t micros) { | 378 int64_t micros) { |
| 396 Init(kAsyncEnd, label); | 379 Init(kAsyncEnd, label); |
| 397 set_timestamp0(micros); | 380 set_timestamp0(micros); |
| 398 // Overload timestamp1_ with the async_id. | 381 // Overload timestamp1_ with the async_id. |
| 399 set_timestamp1(async_id); | 382 set_timestamp1(async_id); |
| 400 } | 383 } |
| 401 | 384 |
| 402 | |
| 403 void TimelineEvent::DurationBegin(const char* label, | 385 void TimelineEvent::DurationBegin(const char* label, |
| 404 int64_t micros, | 386 int64_t micros, |
| 405 int64_t thread_micros) { | 387 int64_t thread_micros) { |
| 406 Init(kDuration, label); | 388 Init(kDuration, label); |
| 407 set_timestamp0(micros); | 389 set_timestamp0(micros); |
| 408 set_thread_timestamp0(thread_micros); | 390 set_thread_timestamp0(thread_micros); |
| 409 } | 391 } |
| 410 | 392 |
| 411 | |
| 412 void TimelineEvent::DurationEnd(int64_t micros, int64_t thread_micros) { | 393 void TimelineEvent::DurationEnd(int64_t micros, int64_t thread_micros) { |
| 413 ASSERT(timestamp1_ == 0); | 394 ASSERT(timestamp1_ == 0); |
| 414 set_timestamp1(micros); | 395 set_timestamp1(micros); |
| 415 set_thread_timestamp1(thread_micros); | 396 set_thread_timestamp1(thread_micros); |
| 416 } | 397 } |
| 417 | 398 |
| 418 | |
| 419 void TimelineEvent::Instant(const char* label, int64_t micros) { | 399 void TimelineEvent::Instant(const char* label, int64_t micros) { |
| 420 Init(kInstant, label); | 400 Init(kInstant, label); |
| 421 set_timestamp0(micros); | 401 set_timestamp0(micros); |
| 422 } | 402 } |
| 423 | 403 |
| 424 | |
| 425 void TimelineEvent::Duration(const char* label, | 404 void TimelineEvent::Duration(const char* label, |
| 426 int64_t start_micros, | 405 int64_t start_micros, |
| 427 int64_t end_micros, | 406 int64_t end_micros, |
| 428 int64_t thread_start_micros, | 407 int64_t thread_start_micros, |
| 429 int64_t thread_end_micros) { | 408 int64_t thread_end_micros) { |
| 430 Init(kDuration, label); | 409 Init(kDuration, label); |
| 431 set_timestamp0(start_micros); | 410 set_timestamp0(start_micros); |
| 432 set_timestamp1(end_micros); | 411 set_timestamp1(end_micros); |
| 433 set_thread_timestamp0(thread_start_micros); | 412 set_thread_timestamp0(thread_start_micros); |
| 434 set_thread_timestamp1(thread_end_micros); | 413 set_thread_timestamp1(thread_end_micros); |
| 435 } | 414 } |
| 436 | 415 |
| 437 | |
| 438 void TimelineEvent::Begin(const char* label, | 416 void TimelineEvent::Begin(const char* label, |
| 439 int64_t micros, | 417 int64_t micros, |
| 440 int64_t thread_micros) { | 418 int64_t thread_micros) { |
| 441 Init(kBegin, label); | 419 Init(kBegin, label); |
| 442 set_timestamp0(micros); | 420 set_timestamp0(micros); |
| 443 set_thread_timestamp0(thread_micros); | 421 set_thread_timestamp0(thread_micros); |
| 444 } | 422 } |
| 445 | 423 |
| 446 | |
| 447 void TimelineEvent::End(const char* label, | 424 void TimelineEvent::End(const char* label, |
| 448 int64_t micros, | 425 int64_t micros, |
| 449 int64_t thread_micros) { | 426 int64_t thread_micros) { |
| 450 Init(kEnd, label); | 427 Init(kEnd, label); |
| 451 set_timestamp0(micros); | 428 set_timestamp0(micros); |
| 452 set_thread_timestamp0(thread_micros); | 429 set_thread_timestamp0(thread_micros); |
| 453 } | 430 } |
| 454 | 431 |
| 455 | |
| 456 void TimelineEvent::Counter(const char* label, int64_t micros) { | 432 void TimelineEvent::Counter(const char* label, int64_t micros) { |
| 457 Init(kCounter, label); | 433 Init(kCounter, label); |
| 458 set_timestamp0(micros); | 434 set_timestamp0(micros); |
| 459 } | 435 } |
| 460 | 436 |
| 461 | |
| 462 void TimelineEvent::Metadata(const char* label, int64_t micros) { | 437 void TimelineEvent::Metadata(const char* label, int64_t micros) { |
| 463 Init(kMetadata, label); | 438 Init(kMetadata, label); |
| 464 set_timestamp0(micros); | 439 set_timestamp0(micros); |
| 465 } | 440 } |
| 466 | 441 |
| 467 | |
| 468 void TimelineEvent::CompleteWithPreSerializedJSON(const char* json) { | 442 void TimelineEvent::CompleteWithPreSerializedJSON(const char* json) { |
| 469 set_pre_serialized_json(true); | 443 set_pre_serialized_json(true); |
| 470 SetNumArguments(1); | 444 SetNumArguments(1); |
| 471 CopyArgument(0, "Dart", json); | 445 CopyArgument(0, "Dart", json); |
| 472 Complete(); | 446 Complete(); |
| 473 } | 447 } |
| 474 | 448 |
| 475 | |
| 476 void TimelineEvent::SetNumArguments(intptr_t length) { | 449 void TimelineEvent::SetNumArguments(intptr_t length) { |
| 477 // Cannot call this twice. | 450 // Cannot call this twice. |
| 478 ASSERT(arguments_ == NULL); | 451 ASSERT(arguments_ == NULL); |
| 479 ASSERT(arguments_length_ == 0); | 452 ASSERT(arguments_length_ == 0); |
| 480 if (length == 0) { | 453 if (length == 0) { |
| 481 return; | 454 return; |
| 482 } | 455 } |
| 483 arguments_length_ = length; | 456 arguments_length_ = length; |
| 484 arguments_ = reinterpret_cast<TimelineEventArgument*>( | 457 arguments_ = reinterpret_cast<TimelineEventArgument*>( |
| 485 calloc(sizeof(TimelineEventArgument), length)); | 458 calloc(sizeof(TimelineEventArgument), length)); |
| 486 } | 459 } |
| 487 | 460 |
| 488 | |
| 489 void TimelineEvent::SetArgument(intptr_t i, const char* name, char* argument) { | 461 void TimelineEvent::SetArgument(intptr_t i, const char* name, char* argument) { |
| 490 ASSERT(i >= 0); | 462 ASSERT(i >= 0); |
| 491 ASSERT(i < arguments_length_); | 463 ASSERT(i < arguments_length_); |
| 492 arguments_[i].name = name; | 464 arguments_[i].name = name; |
| 493 arguments_[i].value = argument; | 465 arguments_[i].value = argument; |
| 494 } | 466 } |
| 495 | 467 |
| 496 | |
| 497 void TimelineEvent::FormatArgument(intptr_t i, | 468 void TimelineEvent::FormatArgument(intptr_t i, |
| 498 const char* name, | 469 const char* name, |
| 499 const char* fmt, | 470 const char* fmt, |
| 500 ...) { | 471 ...) { |
| 501 ASSERT(i >= 0); | 472 ASSERT(i >= 0); |
| 502 ASSERT(i < arguments_length_); | 473 ASSERT(i < arguments_length_); |
| 503 va_list args; | 474 va_list args; |
| 504 va_start(args, fmt); | 475 va_start(args, fmt); |
| 505 intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); | 476 intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); |
| 506 va_end(args); | 477 va_end(args); |
| 507 | 478 |
| 508 char* buffer = reinterpret_cast<char*>(malloc(len + 1)); | 479 char* buffer = reinterpret_cast<char*>(malloc(len + 1)); |
| 509 va_list args2; | 480 va_list args2; |
| 510 va_start(args2, fmt); | 481 va_start(args2, fmt); |
| 511 OS::VSNPrint(buffer, (len + 1), fmt, args2); | 482 OS::VSNPrint(buffer, (len + 1), fmt, args2); |
| 512 va_end(args2); | 483 va_end(args2); |
| 513 | 484 |
| 514 SetArgument(i, name, buffer); | 485 SetArgument(i, name, buffer); |
| 515 } | 486 } |
| 516 | 487 |
| 517 | |
| 518 void TimelineEvent::CopyArgument(intptr_t i, | 488 void TimelineEvent::CopyArgument(intptr_t i, |
| 519 const char* name, | 489 const char* name, |
| 520 const char* argument) { | 490 const char* argument) { |
| 521 SetArgument(i, name, strdup(argument)); | 491 SetArgument(i, name, strdup(argument)); |
| 522 } | 492 } |
| 523 | 493 |
| 524 | |
| 525 void TimelineEvent::StealArguments(intptr_t arguments_length, | 494 void TimelineEvent::StealArguments(intptr_t arguments_length, |
| 526 TimelineEventArgument* arguments) { | 495 TimelineEventArgument* arguments) { |
| 527 arguments_length_ = arguments_length; | 496 arguments_length_ = arguments_length; |
| 528 arguments_ = arguments; | 497 arguments_ = arguments; |
| 529 } | 498 } |
| 530 | 499 |
| 531 | |
| 532 #if defined(HOST_OS_FUCHSIA) | 500 #if defined(HOST_OS_FUCHSIA) |
| 533 | |
| 534 // TODO(zra): The functions below emit Dart's timeline events all as category | 501 // TODO(zra): The functions below emit Dart's timeline events all as category |
| 535 // "dart". Instead, we could have finer-grained categories that make use of | 502 // "dart". Instead, we could have finer-grained categories that make use of |
| 536 // the name of the timeline stream, e.g. "VM", "GC", etc. | 503 // the name of the timeline stream, e.g. "VM", "GC", etc. |
| 537 | 504 |
| 538 #define FUCHSIA_EVENT_ARGS_LIST(V) \ | 505 #define FUCHSIA_EVENT_ARGS_LIST(V) \ |
| 539 V(Begin, TRACE_DURATION_BEGIN) \ | 506 V(Begin, TRACE_DURATION_BEGIN) \ |
| 540 V(End, TRACE_DURATION_END) | 507 V(End, TRACE_DURATION_END) |
| 541 | 508 |
| 542 #define EMIT_FUCHSIA_EVENT(__name, __macro) \ | 509 #define EMIT_FUCHSIA_EVENT(__name, __macro) \ |
| 543 static void EmitFuchsia##__name##Event(const char* label, \ | 510 static void EmitFuchsia##__name##Event(const char* label, \ |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 } else { \ | 543 } else { \ |
| 577 __macro("dart", label, id, arguments[0].name, \ | 544 __macro("dart", label, id, arguments[0].name, \ |
| 578 const_cast<const char*>(arguments[0].value), arguments[1].name, \ | 545 const_cast<const char*>(arguments[0].value), arguments[1].name, \ |
| 579 const_cast<const char*>(arguments[1].value)); \ | 546 const_cast<const char*>(arguments[1].value)); \ |
| 580 } \ | 547 } \ |
| 581 } | 548 } |
| 582 | 549 |
| 583 FUCHSIA_EVENT_ID_ARGS_LIST(EMIT_FUCHSIA_EVENT) | 550 FUCHSIA_EVENT_ID_ARGS_LIST(EMIT_FUCHSIA_EVENT) |
| 584 #undef EMIT_FUCHSIA_EVENT | 551 #undef EMIT_FUCHSIA_EVENT |
| 585 | 552 |
| 586 | |
| 587 void TimelineEvent::EmitFuchsiaEvent() { | 553 void TimelineEvent::EmitFuchsiaEvent() { |
| 588 switch (event_type()) { | 554 switch (event_type()) { |
| 589 case kBegin: | 555 case kBegin: |
| 590 EmitFuchsiaBeginEvent(label_, arguments_, arguments_length_); | 556 EmitFuchsiaBeginEvent(label_, arguments_, arguments_length_); |
| 591 break; | 557 break; |
| 592 case kEnd: | 558 case kEnd: |
| 593 EmitFuchsiaEndEvent(label_, arguments_, arguments_length_); | 559 EmitFuchsiaEndEvent(label_, arguments_, arguments_length_); |
| 594 break; | 560 break; |
| 595 case kInstant: | 561 case kInstant: |
| 596 EmitFuchsiaInstantEvent(label_, TRACE_SCOPE_THREAD, arguments_, | 562 EmitFuchsiaInstantEvent(label_, TRACE_SCOPE_THREAD, arguments_, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 609 arguments_length_); | 575 arguments_length_); |
| 610 break; | 576 break; |
| 611 default: | 577 default: |
| 612 // TODO(zra): Figure out what to do with kDuration, kCounter, and | 578 // TODO(zra): Figure out what to do with kDuration, kCounter, and |
| 613 // kMetadata. | 579 // kMetadata. |
| 614 break; | 580 break; |
| 615 } | 581 } |
| 616 } | 582 } |
| 617 #endif | 583 #endif |
| 618 | 584 |
| 619 | |
| 620 intptr_t TimelineEvent::PrintSystrace(char* buffer, intptr_t buffer_size) { | 585 intptr_t TimelineEvent::PrintSystrace(char* buffer, intptr_t buffer_size) { |
| 621 ASSERT(buffer != NULL); | 586 ASSERT(buffer != NULL); |
| 622 ASSERT(buffer_size > 0); | 587 ASSERT(buffer_size > 0); |
| 623 buffer[0] = '\0'; | 588 buffer[0] = '\0'; |
| 624 intptr_t length = 0; | 589 intptr_t length = 0; |
| 625 int64_t pid = OS::ProcessId(); | 590 int64_t pid = OS::ProcessId(); |
| 626 switch (event_type()) { | 591 switch (event_type()) { |
| 627 case kBegin: { | 592 case kBegin: { |
| 628 length = OS::SNPrint(buffer, buffer_size, "B|%" Pd64 "|%s", pid, label()); | 593 length = OS::SNPrint(buffer, buffer_size, "B|%" Pd64 "|%s", pid, label()); |
| 629 } break; | 594 } break; |
| 630 case kEnd: { | 595 case kEnd: { |
| 631 length = OS::SNPrint(buffer, buffer_size, "E"); | 596 length = OS::SNPrint(buffer, buffer_size, "E"); |
| 632 } break; | 597 } break; |
| 633 case kCounter: { | 598 case kCounter: { |
| 634 if (arguments_length_ > 0) { | 599 if (arguments_length_ > 0) { |
| 635 // We only report the first counter value. | 600 // We only report the first counter value. |
| 636 length = OS::SNPrint(buffer, buffer_size, "C|%" Pd64 "|%s|%s", pid, | 601 length = OS::SNPrint(buffer, buffer_size, "C|%" Pd64 "|%s|%s", pid, |
| 637 label(), arguments_[0].value); | 602 label(), arguments_[0].value); |
| 638 } | 603 } |
| 639 } | 604 } |
| 640 default: | 605 default: |
| 641 // Ignore event types that we cannot serialize to the Systrace format. | 606 // Ignore event types that we cannot serialize to the Systrace format. |
| 642 break; | 607 break; |
| 643 } | 608 } |
| 644 return length; | 609 return length; |
| 645 } | 610 } |
| 646 | 611 |
| 647 | |
| 648 void TimelineEvent::Complete() { | 612 void TimelineEvent::Complete() { |
| 649 TimelineEventRecorder* recorder = Timeline::recorder(); | 613 TimelineEventRecorder* recorder = Timeline::recorder(); |
| 650 if (recorder != NULL) { | 614 if (recorder != NULL) { |
| 651 recorder->CompleteEvent(this); | 615 recorder->CompleteEvent(this); |
| 652 } | 616 } |
| 653 } | 617 } |
| 654 | 618 |
| 655 | |
| 656 void TimelineEvent::FreeArguments() { | 619 void TimelineEvent::FreeArguments() { |
| 657 if (arguments_ == NULL) { | 620 if (arguments_ == NULL) { |
| 658 return; | 621 return; |
| 659 } | 622 } |
| 660 for (intptr_t i = 0; i < arguments_length_; i++) { | 623 for (intptr_t i = 0; i < arguments_length_; i++) { |
| 661 free(arguments_[i].value); | 624 free(arguments_[i].value); |
| 662 } | 625 } |
| 663 free(arguments_); | 626 free(arguments_); |
| 664 arguments_ = NULL; | 627 arguments_ = NULL; |
| 665 arguments_length_ = 0; | 628 arguments_length_ = 0; |
| 666 } | 629 } |
| 667 | 630 |
| 668 | |
| 669 void TimelineEvent::StreamInit(TimelineStream* stream) { | 631 void TimelineEvent::StreamInit(TimelineStream* stream) { |
| 670 if (stream != NULL) { | 632 if (stream != NULL) { |
| 671 category_ = stream->name(); | 633 category_ = stream->name(); |
| 672 } else { | 634 } else { |
| 673 category_ = ""; | 635 category_ = ""; |
| 674 } | 636 } |
| 675 } | 637 } |
| 676 | 638 |
| 677 | |
| 678 void TimelineEvent::Init(EventType event_type, const char* label) { | 639 void TimelineEvent::Init(EventType event_type, const char* label) { |
| 679 ASSERT(label != NULL); | 640 ASSERT(label != NULL); |
| 680 state_ = 0; | 641 state_ = 0; |
| 681 timestamp0_ = 0; | 642 timestamp0_ = 0; |
| 682 timestamp1_ = 0; | 643 timestamp1_ = 0; |
| 683 thread_timestamp0_ = -1; | 644 thread_timestamp0_ = -1; |
| 684 thread_timestamp1_ = -1; | 645 thread_timestamp1_ = -1; |
| 685 OSThread* os_thread = OSThread::Current(); | 646 OSThread* os_thread = OSThread::Current(); |
| 686 ASSERT(os_thread != NULL); | 647 ASSERT(os_thread != NULL); |
| 687 thread_ = os_thread->trace_id(); | 648 thread_ = os_thread->trace_id(); |
| 688 Isolate* isolate = Isolate::Current(); | 649 Isolate* isolate = Isolate::Current(); |
| 689 if (isolate != NULL) { | 650 if (isolate != NULL) { |
| 690 isolate_id_ = isolate->main_port(); | 651 isolate_id_ = isolate->main_port(); |
| 691 } else { | 652 } else { |
| 692 isolate_id_ = ILLEGAL_PORT; | 653 isolate_id_ = ILLEGAL_PORT; |
| 693 } | 654 } |
| 694 label_ = label; | 655 label_ = label; |
| 695 FreeArguments(); | 656 FreeArguments(); |
| 696 set_pre_serialized_json(false); | 657 set_pre_serialized_json(false); |
| 697 set_event_type(event_type); | 658 set_event_type(event_type); |
| 698 set_owns_label(false); | 659 set_owns_label(false); |
| 699 } | 660 } |
| 700 | 661 |
| 701 | |
| 702 bool TimelineEvent::Within(int64_t time_origin_micros, | 662 bool TimelineEvent::Within(int64_t time_origin_micros, |
| 703 int64_t time_extent_micros) { | 663 int64_t time_extent_micros) { |
| 704 if ((time_origin_micros == -1) || (time_extent_micros == -1)) { | 664 if ((time_origin_micros == -1) || (time_extent_micros == -1)) { |
| 705 // No time range specified. | 665 // No time range specified. |
| 706 return true; | 666 return true; |
| 707 } | 667 } |
| 708 if (IsFinishedDuration()) { | 668 if (IsFinishedDuration()) { |
| 709 // Event is from e_t0 to e_t1. | 669 // Event is from e_t0 to e_t1. |
| 710 int64_t e_t0 = TimeOrigin(); | 670 int64_t e_t0 = TimeOrigin(); |
| 711 int64_t e_t1 = TimeEnd(); | 671 int64_t e_t1 = TimeEnd(); |
| 712 ASSERT(e_t0 <= e_t1); | 672 ASSERT(e_t0 <= e_t1); |
| 713 // Range is from r_t0 to r_t1. | 673 // Range is from r_t0 to r_t1. |
| 714 int64_t r_t0 = time_origin_micros; | 674 int64_t r_t0 = time_origin_micros; |
| 715 int64_t r_t1 = time_origin_micros + time_extent_micros; | 675 int64_t r_t1 = time_origin_micros + time_extent_micros; |
| 716 ASSERT(r_t0 <= r_t1); | 676 ASSERT(r_t0 <= r_t1); |
| 717 return !((r_t1 < e_t0) || (e_t1 < r_t0)); | 677 return !((r_t1 < e_t0) || (e_t1 < r_t0)); |
| 718 } | 678 } |
| 719 int64_t delta = TimeOrigin() - time_origin_micros; | 679 int64_t delta = TimeOrigin() - time_origin_micros; |
| 720 return (delta >= 0) && (delta <= time_extent_micros); | 680 return (delta >= 0) && (delta <= time_extent_micros); |
| 721 } | 681 } |
| 722 | 682 |
| 723 | |
| 724 const char* TimelineEvent::GetSerializedJSON() const { | 683 const char* TimelineEvent::GetSerializedJSON() const { |
| 725 ASSERT(pre_serialized_json()); | 684 ASSERT(pre_serialized_json()); |
| 726 ASSERT(arguments_length_ == 1); | 685 ASSERT(arguments_length_ == 1); |
| 727 ASSERT(arguments_ != NULL); | 686 ASSERT(arguments_ != NULL); |
| 728 return arguments_[0].value; | 687 return arguments_[0].value; |
| 729 } | 688 } |
| 730 | 689 |
| 731 | |
| 732 void TimelineEvent::PrintJSON(JSONStream* stream) const { | 690 void TimelineEvent::PrintJSON(JSONStream* stream) const { |
| 733 if (!FLAG_support_service) { | 691 if (!FLAG_support_service) { |
| 734 return; | 692 return; |
| 735 } | 693 } |
| 736 if (pre_serialized_json()) { | 694 if (pre_serialized_json()) { |
| 737 // Event has already been serialized into JSON- just append the | 695 // Event has already been serialized into JSON- just append the |
| 738 // raw data. | 696 // raw data. |
| 739 stream->AppendSerializedObject(GetSerializedJSON()); | 697 stream->AppendSerializedObject(GetSerializedJSON()); |
| 740 return; | 698 return; |
| 741 } | 699 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 796 args.AddProperty(arg.name, arg.value); | 754 args.AddProperty(arg.name, arg.value); |
| 797 } | 755 } |
| 798 if (isolate_id_ != ILLEGAL_PORT) { | 756 if (isolate_id_ != ILLEGAL_PORT) { |
| 799 // If we have one, append the isolate id. | 757 // If we have one, append the isolate id. |
| 800 args.AddPropertyF("isolateNumber", "%" Pd64 "", | 758 args.AddPropertyF("isolateNumber", "%" Pd64 "", |
| 801 static_cast<int64_t>(isolate_id_)); | 759 static_cast<int64_t>(isolate_id_)); |
| 802 } | 760 } |
| 803 } | 761 } |
| 804 } | 762 } |
| 805 | 763 |
| 806 | |
| 807 int64_t TimelineEvent::TimeOrigin() const { | 764 int64_t TimelineEvent::TimeOrigin() const { |
| 808 return timestamp0_; | 765 return timestamp0_; |
| 809 } | 766 } |
| 810 | 767 |
| 811 | |
| 812 int64_t TimelineEvent::AsyncId() const { | 768 int64_t TimelineEvent::AsyncId() const { |
| 813 return timestamp1_; | 769 return timestamp1_; |
| 814 } | 770 } |
| 815 | 771 |
| 816 | |
| 817 int64_t TimelineEvent::LowTime() const { | 772 int64_t TimelineEvent::LowTime() const { |
| 818 return timestamp0_; | 773 return timestamp0_; |
| 819 } | 774 } |
| 820 | 775 |
| 821 | |
| 822 int64_t TimelineEvent::HighTime() const { | 776 int64_t TimelineEvent::HighTime() const { |
| 823 if (event_type() == kDuration) { | 777 if (event_type() == kDuration) { |
| 824 return timestamp1_; | 778 return timestamp1_; |
| 825 } else { | 779 } else { |
| 826 return timestamp0_; | 780 return timestamp0_; |
| 827 } | 781 } |
| 828 } | 782 } |
| 829 | 783 |
| 830 | |
| 831 int64_t TimelineEvent::TimeDuration() const { | 784 int64_t TimelineEvent::TimeDuration() const { |
| 832 if (timestamp1_ == 0) { | 785 if (timestamp1_ == 0) { |
| 833 // This duration is still open, use current time as end. | 786 // This duration is still open, use current time as end. |
| 834 return OS::GetCurrentMonotonicMicros() - timestamp0_; | 787 return OS::GetCurrentMonotonicMicros() - timestamp0_; |
| 835 } | 788 } |
| 836 return timestamp1_ - timestamp0_; | 789 return timestamp1_ - timestamp0_; |
| 837 } | 790 } |
| 838 | 791 |
| 839 | |
| 840 bool TimelineEvent::HasThreadCPUTime() const { | 792 bool TimelineEvent::HasThreadCPUTime() const { |
| 841 return (thread_timestamp0_ != -1); | 793 return (thread_timestamp0_ != -1); |
| 842 } | 794 } |
| 843 | 795 |
| 844 | |
| 845 int64_t TimelineEvent::ThreadCPUTimeOrigin() const { | 796 int64_t TimelineEvent::ThreadCPUTimeOrigin() const { |
| 846 ASSERT(HasThreadCPUTime()); | 797 ASSERT(HasThreadCPUTime()); |
| 847 return thread_timestamp0_; | 798 return thread_timestamp0_; |
| 848 } | 799 } |
| 849 | 800 |
| 850 | |
| 851 int64_t TimelineEvent::ThreadCPUTimeDuration() const { | 801 int64_t TimelineEvent::ThreadCPUTimeDuration() const { |
| 852 ASSERT(HasThreadCPUTime()); | 802 ASSERT(HasThreadCPUTime()); |
| 853 if (thread_timestamp1_ == -1) { | 803 if (thread_timestamp1_ == -1) { |
| 854 // This duration is still open, use current time as end. | 804 // This duration is still open, use current time as end. |
| 855 return OS::GetCurrentThreadCPUMicros() - thread_timestamp0_; | 805 return OS::GetCurrentThreadCPUMicros() - thread_timestamp0_; |
| 856 } | 806 } |
| 857 return thread_timestamp1_ - thread_timestamp0_; | 807 return thread_timestamp1_ - thread_timestamp0_; |
| 858 } | 808 } |
| 859 | 809 |
| 860 | |
| 861 TimelineStream::TimelineStream() : name_(NULL), enabled_(false) {} | 810 TimelineStream::TimelineStream() : name_(NULL), enabled_(false) {} |
| 862 | 811 |
| 863 | |
| 864 void TimelineStream::Init(const char* name, bool enabled) { | 812 void TimelineStream::Init(const char* name, bool enabled) { |
| 865 name_ = name; | 813 name_ = name; |
| 866 enabled_ = enabled; | 814 enabled_ = enabled; |
| 867 } | 815 } |
| 868 | 816 |
| 869 | |
| 870 TimelineEvent* TimelineStream::StartEvent() { | 817 TimelineEvent* TimelineStream::StartEvent() { |
| 871 TimelineEventRecorder* recorder = Timeline::recorder(); | 818 TimelineEventRecorder* recorder = Timeline::recorder(); |
| 872 if (!enabled() || (recorder == NULL)) { | 819 if (!enabled() || (recorder == NULL)) { |
| 873 return NULL; | 820 return NULL; |
| 874 } | 821 } |
| 875 ASSERT(name_ != NULL); | 822 ASSERT(name_ != NULL); |
| 876 TimelineEvent* event = recorder->StartEvent(); | 823 TimelineEvent* event = recorder->StartEvent(); |
| 877 if (event != NULL) { | 824 if (event != NULL) { |
| 878 event->StreamInit(this); | 825 event->StreamInit(this); |
| 879 } | 826 } |
| 880 return event; | 827 return event; |
| 881 } | 828 } |
| 882 | 829 |
| 883 | |
| 884 TimelineEventScope::TimelineEventScope(TimelineStream* stream, | 830 TimelineEventScope::TimelineEventScope(TimelineStream* stream, |
| 885 const char* label) | 831 const char* label) |
| 886 : StackResource(reinterpret_cast<Thread*>(NULL)), | 832 : StackResource(reinterpret_cast<Thread*>(NULL)), |
| 887 stream_(stream), | 833 stream_(stream), |
| 888 label_(label), | 834 label_(label), |
| 889 arguments_(NULL), | 835 arguments_(NULL), |
| 890 arguments_length_(0), | 836 arguments_length_(0), |
| 891 enabled_(false) { | 837 enabled_(false) { |
| 892 Init(); | 838 Init(); |
| 893 } | 839 } |
| 894 | 840 |
| 895 | |
| 896 TimelineEventScope::TimelineEventScope(Thread* thread, | 841 TimelineEventScope::TimelineEventScope(Thread* thread, |
| 897 TimelineStream* stream, | 842 TimelineStream* stream, |
| 898 const char* label) | 843 const char* label) |
| 899 : StackResource(thread), | 844 : StackResource(thread), |
| 900 stream_(stream), | 845 stream_(stream), |
| 901 label_(label), | 846 label_(label), |
| 902 arguments_(NULL), | 847 arguments_(NULL), |
| 903 arguments_length_(0), | 848 arguments_length_(0), |
| 904 enabled_(false) { | 849 enabled_(false) { |
| 905 Init(); | 850 Init(); |
| 906 } | 851 } |
| 907 | 852 |
| 908 | |
| 909 TimelineEventScope::~TimelineEventScope() { | 853 TimelineEventScope::~TimelineEventScope() { |
| 910 FreeArguments(); | 854 FreeArguments(); |
| 911 } | 855 } |
| 912 | 856 |
| 913 | |
| 914 void TimelineEventScope::Init() { | 857 void TimelineEventScope::Init() { |
| 915 ASSERT(enabled_ == false); | 858 ASSERT(enabled_ == false); |
| 916 ASSERT(label_ != NULL); | 859 ASSERT(label_ != NULL); |
| 917 ASSERT(stream_ != NULL); | 860 ASSERT(stream_ != NULL); |
| 918 if (!stream_->enabled()) { | 861 if (!stream_->enabled()) { |
| 919 // Stream is not enabled, do nothing. | 862 // Stream is not enabled, do nothing. |
| 920 return; | 863 return; |
| 921 } | 864 } |
| 922 enabled_ = true; | 865 enabled_ = true; |
| 923 } | 866 } |
| 924 | 867 |
| 925 | |
| 926 void TimelineEventScope::SetNumArguments(intptr_t length) { | 868 void TimelineEventScope::SetNumArguments(intptr_t length) { |
| 927 if (!enabled()) { | 869 if (!enabled()) { |
| 928 return; | 870 return; |
| 929 } | 871 } |
| 930 ASSERT(arguments_ == NULL); | 872 ASSERT(arguments_ == NULL); |
| 931 ASSERT(arguments_length_ == 0); | 873 ASSERT(arguments_length_ == 0); |
| 932 arguments_length_ = length; | 874 arguments_length_ = length; |
| 933 if (arguments_length_ == 0) { | 875 if (arguments_length_ == 0) { |
| 934 return; | 876 return; |
| 935 } | 877 } |
| 936 arguments_ = reinterpret_cast<TimelineEventArgument*>( | 878 arguments_ = reinterpret_cast<TimelineEventArgument*>( |
| 937 calloc(sizeof(TimelineEventArgument), length)); | 879 calloc(sizeof(TimelineEventArgument), length)); |
| 938 } | 880 } |
| 939 | 881 |
| 940 | |
| 941 // |name| must be a compile time constant. Takes ownership of |argumentp|. | 882 // |name| must be a compile time constant. Takes ownership of |argumentp|. |
| 942 void TimelineEventScope::SetArgument(intptr_t i, | 883 void TimelineEventScope::SetArgument(intptr_t i, |
| 943 const char* name, | 884 const char* name, |
| 944 char* argument) { | 885 char* argument) { |
| 945 if (!enabled()) { | 886 if (!enabled()) { |
| 946 return; | 887 return; |
| 947 } | 888 } |
| 948 ASSERT(i >= 0); | 889 ASSERT(i >= 0); |
| 949 ASSERT(i < arguments_length_); | 890 ASSERT(i < arguments_length_); |
| 950 arguments_[i].name = name; | 891 arguments_[i].name = name; |
| 951 arguments_[i].value = argument; | 892 arguments_[i].value = argument; |
| 952 } | 893 } |
| 953 | 894 |
| 954 | |
| 955 // |name| must be a compile time constant. Copies |argument|. | 895 // |name| must be a compile time constant. Copies |argument|. |
| 956 void TimelineEventScope::CopyArgument(intptr_t i, | 896 void TimelineEventScope::CopyArgument(intptr_t i, |
| 957 const char* name, | 897 const char* name, |
| 958 const char* argument) { | 898 const char* argument) { |
| 959 if (!enabled()) { | 899 if (!enabled()) { |
| 960 return; | 900 return; |
| 961 } | 901 } |
| 962 SetArgument(i, name, strdup(argument)); | 902 SetArgument(i, name, strdup(argument)); |
| 963 } | 903 } |
| 964 | 904 |
| 965 | |
| 966 void TimelineEventScope::FormatArgument(intptr_t i, | 905 void TimelineEventScope::FormatArgument(intptr_t i, |
| 967 const char* name, | 906 const char* name, |
| 968 const char* fmt, | 907 const char* fmt, |
| 969 ...) { | 908 ...) { |
| 970 if (!enabled()) { | 909 if (!enabled()) { |
| 971 return; | 910 return; |
| 972 } | 911 } |
| 973 va_list args; | 912 va_list args; |
| 974 va_start(args, fmt); | 913 va_start(args, fmt); |
| 975 intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); | 914 intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); |
| 976 va_end(args); | 915 va_end(args); |
| 977 | 916 |
| 978 char* buffer = reinterpret_cast<char*>(malloc(len + 1)); | 917 char* buffer = reinterpret_cast<char*>(malloc(len + 1)); |
| 979 va_list args2; | 918 va_list args2; |
| 980 va_start(args2, fmt); | 919 va_start(args2, fmt); |
| 981 OS::VSNPrint(buffer, (len + 1), fmt, args2); | 920 OS::VSNPrint(buffer, (len + 1), fmt, args2); |
| 982 va_end(args2); | 921 va_end(args2); |
| 983 | 922 |
| 984 SetArgument(i, name, buffer); | 923 SetArgument(i, name, buffer); |
| 985 } | 924 } |
| 986 | 925 |
| 987 | |
| 988 void TimelineEventScope::FreeArguments() { | 926 void TimelineEventScope::FreeArguments() { |
| 989 if (arguments_ == NULL) { | 927 if (arguments_ == NULL) { |
| 990 return; | 928 return; |
| 991 } | 929 } |
| 992 for (intptr_t i = 0; i < arguments_length_; i++) { | 930 for (intptr_t i = 0; i < arguments_length_; i++) { |
| 993 free(arguments_[i].value); | 931 free(arguments_[i].value); |
| 994 } | 932 } |
| 995 free(arguments_); | 933 free(arguments_); |
| 996 arguments_ = NULL; | 934 arguments_ = NULL; |
| 997 arguments_length_ = 0; | 935 arguments_length_ = 0; |
| 998 } | 936 } |
| 999 | 937 |
| 1000 | |
| 1001 void TimelineEventScope::StealArguments(TimelineEvent* event) { | 938 void TimelineEventScope::StealArguments(TimelineEvent* event) { |
| 1002 if (event == NULL) { | 939 if (event == NULL) { |
| 1003 return; | 940 return; |
| 1004 } | 941 } |
| 1005 event->StealArguments(arguments_length_, arguments_); | 942 event->StealArguments(arguments_length_, arguments_); |
| 1006 arguments_length_ = 0; | 943 arguments_length_ = 0; |
| 1007 arguments_ = NULL; | 944 arguments_ = NULL; |
| 1008 } | 945 } |
| 1009 | 946 |
| 1010 | |
| 1011 TimelineDurationScope::TimelineDurationScope(TimelineStream* stream, | 947 TimelineDurationScope::TimelineDurationScope(TimelineStream* stream, |
| 1012 const char* label) | 948 const char* label) |
| 1013 : TimelineEventScope(stream, label) { | 949 : TimelineEventScope(stream, label) { |
| 1014 if (!FLAG_support_timeline || !enabled()) { | 950 if (!FLAG_support_timeline || !enabled()) { |
| 1015 return; | 951 return; |
| 1016 } | 952 } |
| 1017 #if defined(HOST_OS_FUCHSIA) | 953 #if defined(HOST_OS_FUCHSIA) |
| 1018 TRACE_DURATION_BEGIN("dart", label); | 954 TRACE_DURATION_BEGIN("dart", label); |
| 1019 #else | 955 #else |
| 1020 timestamp_ = OS::GetCurrentMonotonicMicros(); | 956 timestamp_ = OS::GetCurrentMonotonicMicros(); |
| 1021 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); | 957 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); |
| 1022 #endif | 958 #endif |
| 1023 } | 959 } |
| 1024 | 960 |
| 1025 | |
| 1026 TimelineDurationScope::TimelineDurationScope(Thread* thread, | 961 TimelineDurationScope::TimelineDurationScope(Thread* thread, |
| 1027 TimelineStream* stream, | 962 TimelineStream* stream, |
| 1028 const char* label) | 963 const char* label) |
| 1029 : TimelineEventScope(thread, stream, label) { | 964 : TimelineEventScope(thread, stream, label) { |
| 1030 if (!FLAG_support_timeline || !enabled()) { | 965 if (!FLAG_support_timeline || !enabled()) { |
| 1031 return; | 966 return; |
| 1032 } | 967 } |
| 1033 #if defined(HOST_OS_FUCHSIA) | 968 #if defined(HOST_OS_FUCHSIA) |
| 1034 TRACE_DURATION_BEGIN("dart", label); | 969 TRACE_DURATION_BEGIN("dart", label); |
| 1035 #else | 970 #else |
| 1036 timestamp_ = OS::GetCurrentMonotonicMicros(); | 971 timestamp_ = OS::GetCurrentMonotonicMicros(); |
| 1037 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); | 972 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); |
| 1038 #endif | 973 #endif |
| 1039 } | 974 } |
| 1040 | 975 |
| 1041 | |
| 1042 TimelineDurationScope::~TimelineDurationScope() { | 976 TimelineDurationScope::~TimelineDurationScope() { |
| 1043 if (!FLAG_support_timeline) { | 977 if (!FLAG_support_timeline) { |
| 1044 return; | 978 return; |
| 1045 } | 979 } |
| 1046 if (!ShouldEmitEvent()) { | 980 if (!ShouldEmitEvent()) { |
| 1047 return; | 981 return; |
| 1048 } | 982 } |
| 1049 #if defined(HOST_OS_FUCHSIA) | 983 #if defined(HOST_OS_FUCHSIA) |
| 1050 EmitFuchsiaEndEvent(label(), arguments(), arguments_length()); | 984 EmitFuchsiaEndEvent(label(), arguments(), arguments_length()); |
| 1051 #else | 985 #else |
| 1052 TimelineEvent* event = stream()->StartEvent(); | 986 TimelineEvent* event = stream()->StartEvent(); |
| 1053 if (event == NULL) { | 987 if (event == NULL) { |
| 1054 // Stream is now disabled. | 988 // Stream is now disabled. |
| 1055 return; | 989 return; |
| 1056 } | 990 } |
| 1057 ASSERT(event != NULL); | 991 ASSERT(event != NULL); |
| 1058 // Emit a duration event. | 992 // Emit a duration event. |
| 1059 event->Duration(label(), timestamp_, OS::GetCurrentMonotonicMicros(), | 993 event->Duration(label(), timestamp_, OS::GetCurrentMonotonicMicros(), |
| 1060 thread_timestamp_, OS::GetCurrentThreadCPUMicros()); | 994 thread_timestamp_, OS::GetCurrentThreadCPUMicros()); |
| 1061 StealArguments(event); | 995 StealArguments(event); |
| 1062 event->Complete(); | 996 event->Complete(); |
| 1063 #endif | 997 #endif |
| 1064 } | 998 } |
| 1065 | 999 |
| 1066 | |
| 1067 TimelineBeginEndScope::TimelineBeginEndScope(TimelineStream* stream, | 1000 TimelineBeginEndScope::TimelineBeginEndScope(TimelineStream* stream, |
| 1068 const char* label) | 1001 const char* label) |
| 1069 : TimelineEventScope(stream, label) { | 1002 : TimelineEventScope(stream, label) { |
| 1070 if (!FLAG_support_timeline) { | 1003 if (!FLAG_support_timeline) { |
| 1071 return; | 1004 return; |
| 1072 } | 1005 } |
| 1073 EmitBegin(); | 1006 EmitBegin(); |
| 1074 } | 1007 } |
| 1075 | 1008 |
| 1076 | |
| 1077 TimelineBeginEndScope::TimelineBeginEndScope(Thread* thread, | 1009 TimelineBeginEndScope::TimelineBeginEndScope(Thread* thread, |
| 1078 TimelineStream* stream, | 1010 TimelineStream* stream, |
| 1079 const char* label) | 1011 const char* label) |
| 1080 : TimelineEventScope(thread, stream, label) { | 1012 : TimelineEventScope(thread, stream, label) { |
| 1081 if (!FLAG_support_timeline) { | 1013 if (!FLAG_support_timeline) { |
| 1082 return; | 1014 return; |
| 1083 } | 1015 } |
| 1084 EmitBegin(); | 1016 EmitBegin(); |
| 1085 } | 1017 } |
| 1086 | 1018 |
| 1087 | |
| 1088 TimelineBeginEndScope::~TimelineBeginEndScope() { | 1019 TimelineBeginEndScope::~TimelineBeginEndScope() { |
| 1089 if (!FLAG_support_timeline) { | 1020 if (!FLAG_support_timeline) { |
| 1090 return; | 1021 return; |
| 1091 } | 1022 } |
| 1092 EmitEnd(); | 1023 EmitEnd(); |
| 1093 } | 1024 } |
| 1094 | 1025 |
| 1095 | |
| 1096 void TimelineBeginEndScope::EmitBegin() { | 1026 void TimelineBeginEndScope::EmitBegin() { |
| 1097 if (!FLAG_support_timeline) { | 1027 if (!FLAG_support_timeline) { |
| 1098 return; | 1028 return; |
| 1099 } | 1029 } |
| 1100 if (!ShouldEmitEvent()) { | 1030 if (!ShouldEmitEvent()) { |
| 1101 return; | 1031 return; |
| 1102 } | 1032 } |
| 1103 TimelineEvent* event = stream()->StartEvent(); | 1033 TimelineEvent* event = stream()->StartEvent(); |
| 1104 if (event == NULL) { | 1034 if (event == NULL) { |
| 1105 // Stream is now disabled. | 1035 // Stream is now disabled. |
| 1106 set_enabled(false); | 1036 set_enabled(false); |
| 1107 return; | 1037 return; |
| 1108 } | 1038 } |
| 1109 ASSERT(event != NULL); | 1039 ASSERT(event != NULL); |
| 1110 // Emit a begin event. | 1040 // Emit a begin event. |
| 1111 event->Begin(label()); | 1041 event->Begin(label()); |
| 1112 event->Complete(); | 1042 event->Complete(); |
| 1113 } | 1043 } |
| 1114 | 1044 |
| 1115 | |
| 1116 void TimelineBeginEndScope::EmitEnd() { | 1045 void TimelineBeginEndScope::EmitEnd() { |
| 1117 if (!FLAG_support_timeline) { | 1046 if (!FLAG_support_timeline) { |
| 1118 return; | 1047 return; |
| 1119 } | 1048 } |
| 1120 if (!ShouldEmitEvent()) { | 1049 if (!ShouldEmitEvent()) { |
| 1121 return; | 1050 return; |
| 1122 } | 1051 } |
| 1123 TimelineEvent* event = stream()->StartEvent(); | 1052 TimelineEvent* event = stream()->StartEvent(); |
| 1124 if (event == NULL) { | 1053 if (event == NULL) { |
| 1125 // Stream is now disabled. | 1054 // Stream is now disabled. |
| 1126 set_enabled(false); | 1055 set_enabled(false); |
| 1127 return; | 1056 return; |
| 1128 } | 1057 } |
| 1129 ASSERT(event != NULL); | 1058 ASSERT(event != NULL); |
| 1130 // Emit an end event. | 1059 // Emit an end event. |
| 1131 event->End(label()); | 1060 event->End(label()); |
| 1132 StealArguments(event); | 1061 StealArguments(event); |
| 1133 event->Complete(); | 1062 event->Complete(); |
| 1134 } | 1063 } |
| 1135 | 1064 |
| 1136 | |
| 1137 TimelineEventFilter::TimelineEventFilter(int64_t time_origin_micros, | 1065 TimelineEventFilter::TimelineEventFilter(int64_t time_origin_micros, |
| 1138 int64_t time_extent_micros) | 1066 int64_t time_extent_micros) |
| 1139 : time_origin_micros_(time_origin_micros), | 1067 : time_origin_micros_(time_origin_micros), |
| 1140 time_extent_micros_(time_extent_micros) { | 1068 time_extent_micros_(time_extent_micros) { |
| 1141 ASSERT(time_origin_micros_ >= -1); | 1069 ASSERT(time_origin_micros_ >= -1); |
| 1142 ASSERT(time_extent_micros_ >= -1); | 1070 ASSERT(time_extent_micros_ >= -1); |
| 1143 } | 1071 } |
| 1144 | 1072 |
| 1145 | |
| 1146 TimelineEventFilter::~TimelineEventFilter() {} | 1073 TimelineEventFilter::~TimelineEventFilter() {} |
| 1147 | 1074 |
| 1148 | |
| 1149 IsolateTimelineEventFilter::IsolateTimelineEventFilter( | 1075 IsolateTimelineEventFilter::IsolateTimelineEventFilter( |
| 1150 Dart_Port isolate_id, | 1076 Dart_Port isolate_id, |
| 1151 int64_t time_origin_micros, | 1077 int64_t time_origin_micros, |
| 1152 int64_t time_extent_micros) | 1078 int64_t time_extent_micros) |
| 1153 : TimelineEventFilter(time_origin_micros, time_extent_micros), | 1079 : TimelineEventFilter(time_origin_micros, time_extent_micros), |
| 1154 isolate_id_(isolate_id) {} | 1080 isolate_id_(isolate_id) {} |
| 1155 | 1081 |
| 1156 | |
| 1157 TimelineEventRecorder::TimelineEventRecorder() | 1082 TimelineEventRecorder::TimelineEventRecorder() |
| 1158 : async_id_(0), time_low_micros_(0), time_high_micros_(0) {} | 1083 : async_id_(0), time_low_micros_(0), time_high_micros_(0) {} |
| 1159 | 1084 |
| 1160 | |
| 1161 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const { | 1085 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const { |
| 1162 if (!FLAG_support_service) { | 1086 if (!FLAG_support_service) { |
| 1163 return; | 1087 return; |
| 1164 } | 1088 } |
| 1165 OSThreadIterator it; | 1089 OSThreadIterator it; |
| 1166 while (it.HasNext()) { | 1090 while (it.HasNext()) { |
| 1167 OSThread* thread = it.Next(); | 1091 OSThread* thread = it.Next(); |
| 1168 const char* thread_name = thread->name(); | 1092 const char* thread_name = thread->name(); |
| 1169 if (thread_name == NULL) { | 1093 if (thread_name == NULL) { |
| 1170 // Only emit a thread name if one was set. | 1094 // Only emit a thread name if one was set. |
| 1171 continue; | 1095 continue; |
| 1172 } | 1096 } |
| 1173 JSONObject obj(events); | 1097 JSONObject obj(events); |
| 1174 int64_t pid = OS::ProcessId(); | 1098 int64_t pid = OS::ProcessId(); |
| 1175 int64_t tid = OSThread::ThreadIdToIntPtr(thread->trace_id()); | 1099 int64_t tid = OSThread::ThreadIdToIntPtr(thread->trace_id()); |
| 1176 obj.AddProperty("name", "thread_name"); | 1100 obj.AddProperty("name", "thread_name"); |
| 1177 obj.AddProperty("ph", "M"); | 1101 obj.AddProperty("ph", "M"); |
| 1178 obj.AddProperty64("pid", pid); | 1102 obj.AddProperty64("pid", pid); |
| 1179 obj.AddProperty64("tid", tid); | 1103 obj.AddProperty64("tid", tid); |
| 1180 { | 1104 { |
| 1181 JSONObject args(&obj, "args"); | 1105 JSONObject args(&obj, "args"); |
| 1182 args.AddPropertyF("name", "%s (%" Pd64 ")", thread_name, tid); | 1106 args.AddPropertyF("name", "%s (%" Pd64 ")", thread_name, tid); |
| 1183 } | 1107 } |
| 1184 } | 1108 } |
| 1185 } | 1109 } |
| 1186 | 1110 |
| 1187 | |
| 1188 TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() { | 1111 TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() { |
| 1189 // Grab the current thread. | 1112 // Grab the current thread. |
| 1190 OSThread* thread = OSThread::Current(); | 1113 OSThread* thread = OSThread::Current(); |
| 1191 ASSERT(thread != NULL); | 1114 ASSERT(thread != NULL); |
| 1192 Mutex* thread_block_lock = thread->timeline_block_lock(); | 1115 Mutex* thread_block_lock = thread->timeline_block_lock(); |
| 1193 ASSERT(thread_block_lock != NULL); | 1116 ASSERT(thread_block_lock != NULL); |
| 1194 // We are accessing the thread's timeline block- so take the lock here. | 1117 // We are accessing the thread's timeline block- so take the lock here. |
| 1195 // This lock will be held until the call to |CompleteEvent| is made. | 1118 // This lock will be held until the call to |CompleteEvent| is made. |
| 1196 thread_block_lock->Lock(); | 1119 thread_block_lock->Lock(); |
| 1197 #if defined(DEBUG) | 1120 #if defined(DEBUG) |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1226 // Drop lock here as no event is being handed out. | 1149 // Drop lock here as no event is being handed out. |
| 1227 #if defined(DEBUG) | 1150 #if defined(DEBUG) |
| 1228 if (T != NULL) { | 1151 if (T != NULL) { |
| 1229 T->DecrementNoSafepointScopeDepth(); | 1152 T->DecrementNoSafepointScopeDepth(); |
| 1230 } | 1153 } |
| 1231 #endif // defined(DEBUG) | 1154 #endif // defined(DEBUG) |
| 1232 thread_block_lock->Unlock(); | 1155 thread_block_lock->Unlock(); |
| 1233 return NULL; | 1156 return NULL; |
| 1234 } | 1157 } |
| 1235 | 1158 |
| 1236 | |
| 1237 void TimelineEventRecorder::ResetTimeTracking() { | 1159 void TimelineEventRecorder::ResetTimeTracking() { |
| 1238 time_high_micros_ = 0; | 1160 time_high_micros_ = 0; |
| 1239 time_low_micros_ = kMaxInt64; | 1161 time_low_micros_ = kMaxInt64; |
| 1240 } | 1162 } |
| 1241 | 1163 |
| 1242 | |
| 1243 void TimelineEventRecorder::ReportTime(int64_t micros) { | 1164 void TimelineEventRecorder::ReportTime(int64_t micros) { |
| 1244 if (time_high_micros_ < micros) { | 1165 if (time_high_micros_ < micros) { |
| 1245 time_high_micros_ = micros; | 1166 time_high_micros_ = micros; |
| 1246 } | 1167 } |
| 1247 if (time_low_micros_ > micros) { | 1168 if (time_low_micros_ > micros) { |
| 1248 time_low_micros_ = micros; | 1169 time_low_micros_ = micros; |
| 1249 } | 1170 } |
| 1250 } | 1171 } |
| 1251 | 1172 |
| 1252 | |
| 1253 int64_t TimelineEventRecorder::TimeOriginMicros() const { | 1173 int64_t TimelineEventRecorder::TimeOriginMicros() const { |
| 1254 if (time_high_micros_ == 0) { | 1174 if (time_high_micros_ == 0) { |
| 1255 return 0; | 1175 return 0; |
| 1256 } | 1176 } |
| 1257 return time_low_micros_; | 1177 return time_low_micros_; |
| 1258 } | 1178 } |
| 1259 | 1179 |
| 1260 | |
| 1261 int64_t TimelineEventRecorder::TimeExtentMicros() const { | 1180 int64_t TimelineEventRecorder::TimeExtentMicros() const { |
| 1262 if (time_high_micros_ == 0) { | 1181 if (time_high_micros_ == 0) { |
| 1263 return 0; | 1182 return 0; |
| 1264 } | 1183 } |
| 1265 return time_high_micros_ - time_low_micros_; | 1184 return time_high_micros_ - time_low_micros_; |
| 1266 } | 1185 } |
| 1267 | 1186 |
| 1268 | |
| 1269 void TimelineEventRecorder::ThreadBlockCompleteEvent(TimelineEvent* event) { | 1187 void TimelineEventRecorder::ThreadBlockCompleteEvent(TimelineEvent* event) { |
| 1270 if (event == NULL) { | 1188 if (event == NULL) { |
| 1271 return; | 1189 return; |
| 1272 } | 1190 } |
| 1273 // Grab the current thread. | 1191 // Grab the current thread. |
| 1274 OSThread* thread = OSThread::Current(); | 1192 OSThread* thread = OSThread::Current(); |
| 1275 ASSERT(thread != NULL); | 1193 ASSERT(thread != NULL); |
| 1276 // Unlock the thread's block lock. | 1194 // Unlock the thread's block lock. |
| 1277 Mutex* thread_block_lock = thread->timeline_block_lock(); | 1195 Mutex* thread_block_lock = thread->timeline_block_lock(); |
| 1278 ASSERT(thread_block_lock != NULL); | 1196 ASSERT(thread_block_lock != NULL); |
| 1279 #if defined(DEBUG) | 1197 #if defined(DEBUG) |
| 1280 Thread* T = Thread::Current(); | 1198 Thread* T = Thread::Current(); |
| 1281 if (T != NULL) { | 1199 if (T != NULL) { |
| 1282 T->DecrementNoSafepointScopeDepth(); | 1200 T->DecrementNoSafepointScopeDepth(); |
| 1283 } | 1201 } |
| 1284 #endif // defined(DEBUG) | 1202 #endif // defined(DEBUG) |
| 1285 thread_block_lock->Unlock(); | 1203 thread_block_lock->Unlock(); |
| 1286 } | 1204 } |
| 1287 | 1205 |
| 1288 | |
| 1289 void TimelineEventRecorder::WriteTo(const char* directory) { | 1206 void TimelineEventRecorder::WriteTo(const char* directory) { |
| 1290 if (!FLAG_support_service) { | 1207 if (!FLAG_support_service) { |
| 1291 return; | 1208 return; |
| 1292 } | 1209 } |
| 1293 Dart_FileOpenCallback file_open = Dart::file_open_callback(); | 1210 Dart_FileOpenCallback file_open = Dart::file_open_callback(); |
| 1294 Dart_FileWriteCallback file_write = Dart::file_write_callback(); | 1211 Dart_FileWriteCallback file_write = Dart::file_write_callback(); |
| 1295 Dart_FileCloseCallback file_close = Dart::file_close_callback(); | 1212 Dart_FileCloseCallback file_close = Dart::file_close_callback(); |
| 1296 if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) { | 1213 if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) { |
| 1297 return; | 1214 return; |
| 1298 } | 1215 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1318 intptr_t output_length = 0; | 1235 intptr_t output_length = 0; |
| 1319 js.Steal(&output, &output_length); | 1236 js.Steal(&output, &output_length); |
| 1320 (*file_write)(output, output_length, file); | 1237 (*file_write)(output, output_length, file); |
| 1321 // Free the stolen output. | 1238 // Free the stolen output. |
| 1322 free(output); | 1239 free(output); |
| 1323 (*file_close)(file); | 1240 (*file_close)(file); |
| 1324 | 1241 |
| 1325 return; | 1242 return; |
| 1326 } | 1243 } |
| 1327 | 1244 |
| 1328 | |
| 1329 int64_t TimelineEventRecorder::GetNextAsyncId() { | 1245 int64_t TimelineEventRecorder::GetNextAsyncId() { |
| 1330 // TODO(johnmccutchan): Gracefully handle wrap around. | 1246 // TODO(johnmccutchan): Gracefully handle wrap around. |
| 1331 uint32_t next = | 1247 uint32_t next = |
| 1332 static_cast<uint32_t>(AtomicOperations::FetchAndIncrement(&async_id_)); | 1248 static_cast<uint32_t>(AtomicOperations::FetchAndIncrement(&async_id_)); |
| 1333 return static_cast<int64_t>(next); | 1249 return static_cast<int64_t>(next); |
| 1334 } | 1250 } |
| 1335 | 1251 |
| 1336 | |
| 1337 void TimelineEventRecorder::FinishBlock(TimelineEventBlock* block) { | 1252 void TimelineEventRecorder::FinishBlock(TimelineEventBlock* block) { |
| 1338 if (block == NULL) { | 1253 if (block == NULL) { |
| 1339 return; | 1254 return; |
| 1340 } | 1255 } |
| 1341 MutexLocker ml(&lock_); | 1256 MutexLocker ml(&lock_); |
| 1342 block->Finish(); | 1257 block->Finish(); |
| 1343 } | 1258 } |
| 1344 | 1259 |
| 1345 | |
| 1346 TimelineEventBlock* TimelineEventRecorder::GetNewBlock() { | 1260 TimelineEventBlock* TimelineEventRecorder::GetNewBlock() { |
| 1347 MutexLocker ml(&lock_); | 1261 MutexLocker ml(&lock_); |
| 1348 return GetNewBlockLocked(); | 1262 return GetNewBlockLocked(); |
| 1349 } | 1263 } |
| 1350 | 1264 |
| 1351 | |
| 1352 TimelineEventFixedBufferRecorder::TimelineEventFixedBufferRecorder( | 1265 TimelineEventFixedBufferRecorder::TimelineEventFixedBufferRecorder( |
| 1353 intptr_t capacity) | 1266 intptr_t capacity) |
| 1354 : blocks_(NULL), capacity_(capacity), num_blocks_(0), block_cursor_(0) { | 1267 : blocks_(NULL), capacity_(capacity), num_blocks_(0), block_cursor_(0) { |
| 1355 // Capacity must be a multiple of TimelineEventBlock::kBlockSize | 1268 // Capacity must be a multiple of TimelineEventBlock::kBlockSize |
| 1356 ASSERT((capacity % TimelineEventBlock::kBlockSize) == 0); | 1269 ASSERT((capacity % TimelineEventBlock::kBlockSize) == 0); |
| 1357 // Allocate blocks array. | 1270 // Allocate blocks array. |
| 1358 num_blocks_ = capacity / TimelineEventBlock::kBlockSize; | 1271 num_blocks_ = capacity / TimelineEventBlock::kBlockSize; |
| 1359 blocks_ = reinterpret_cast<TimelineEventBlock**>( | 1272 blocks_ = reinterpret_cast<TimelineEventBlock**>( |
| 1360 calloc(num_blocks_, sizeof(TimelineEventBlock*))); | 1273 calloc(num_blocks_, sizeof(TimelineEventBlock*))); |
| 1361 // Allocate each block. | 1274 // Allocate each block. |
| 1362 for (intptr_t i = 0; i < num_blocks_; i++) { | 1275 for (intptr_t i = 0; i < num_blocks_; i++) { |
| 1363 blocks_[i] = new TimelineEventBlock(i); | 1276 blocks_[i] = new TimelineEventBlock(i); |
| 1364 } | 1277 } |
| 1365 // Chain blocks together. | 1278 // Chain blocks together. |
| 1366 for (intptr_t i = 0; i < num_blocks_ - 1; i++) { | 1279 for (intptr_t i = 0; i < num_blocks_ - 1; i++) { |
| 1367 blocks_[i]->set_next(blocks_[i + 1]); | 1280 blocks_[i]->set_next(blocks_[i + 1]); |
| 1368 } | 1281 } |
| 1369 } | 1282 } |
| 1370 | 1283 |
| 1371 | |
| 1372 TimelineEventFixedBufferRecorder::~TimelineEventFixedBufferRecorder() { | 1284 TimelineEventFixedBufferRecorder::~TimelineEventFixedBufferRecorder() { |
| 1373 // Delete all blocks. | 1285 // Delete all blocks. |
| 1374 for (intptr_t i = 0; i < num_blocks_; i++) { | 1286 for (intptr_t i = 0; i < num_blocks_; i++) { |
| 1375 TimelineEventBlock* block = blocks_[i]; | 1287 TimelineEventBlock* block = blocks_[i]; |
| 1376 delete block; | 1288 delete block; |
| 1377 } | 1289 } |
| 1378 free(blocks_); | 1290 free(blocks_); |
| 1379 } | 1291 } |
| 1380 | 1292 |
| 1381 | |
| 1382 void TimelineEventFixedBufferRecorder::PrintJSONEvents( | 1293 void TimelineEventFixedBufferRecorder::PrintJSONEvents( |
| 1383 JSONArray* events, | 1294 JSONArray* events, |
| 1384 TimelineEventFilter* filter) { | 1295 TimelineEventFilter* filter) { |
| 1385 if (!FLAG_support_service) { | 1296 if (!FLAG_support_service) { |
| 1386 return; | 1297 return; |
| 1387 } | 1298 } |
| 1388 MutexLocker ml(&lock_); | 1299 MutexLocker ml(&lock_); |
| 1389 ResetTimeTracking(); | 1300 ResetTimeTracking(); |
| 1390 intptr_t block_offset = FindOldestBlockIndex(); | 1301 intptr_t block_offset = FindOldestBlockIndex(); |
| 1391 if (block_offset == -1) { | 1302 if (block_offset == -1) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1404 event->Within(filter->time_origin_micros(), | 1315 event->Within(filter->time_origin_micros(), |
| 1405 filter->time_extent_micros())) { | 1316 filter->time_extent_micros())) { |
| 1406 ReportTime(event->LowTime()); | 1317 ReportTime(event->LowTime()); |
| 1407 ReportTime(event->HighTime()); | 1318 ReportTime(event->HighTime()); |
| 1408 events->AddValue(event); | 1319 events->AddValue(event); |
| 1409 } | 1320 } |
| 1410 } | 1321 } |
| 1411 } | 1322 } |
| 1412 } | 1323 } |
| 1413 | 1324 |
| 1414 | |
| 1415 void TimelineEventFixedBufferRecorder::PrintJSON(JSONStream* js, | 1325 void TimelineEventFixedBufferRecorder::PrintJSON(JSONStream* js, |
| 1416 TimelineEventFilter* filter) { | 1326 TimelineEventFilter* filter) { |
| 1417 if (!FLAG_support_service) { | 1327 if (!FLAG_support_service) { |
| 1418 return; | 1328 return; |
| 1419 } | 1329 } |
| 1420 JSONObject topLevel(js); | 1330 JSONObject topLevel(js); |
| 1421 topLevel.AddProperty("type", "_Timeline"); | 1331 topLevel.AddProperty("type", "_Timeline"); |
| 1422 { | 1332 { |
| 1423 JSONArray events(&topLevel, "traceEvents"); | 1333 JSONArray events(&topLevel, "traceEvents"); |
| 1424 PrintJSONMeta(&events); | 1334 PrintJSONMeta(&events); |
| 1425 PrintJSONEvents(&events, filter); | 1335 PrintJSONEvents(&events, filter); |
| 1426 } | 1336 } |
| 1427 topLevel.AddPropertyTimeMicros("timeOriginMicros", TimeOriginMicros()); | 1337 topLevel.AddPropertyTimeMicros("timeOriginMicros", TimeOriginMicros()); |
| 1428 topLevel.AddPropertyTimeMicros("timeExtentMicros", TimeExtentMicros()); | 1338 topLevel.AddPropertyTimeMicros("timeExtentMicros", TimeExtentMicros()); |
| 1429 } | 1339 } |
| 1430 | 1340 |
| 1431 | |
| 1432 void TimelineEventFixedBufferRecorder::PrintTraceEvent( | 1341 void TimelineEventFixedBufferRecorder::PrintTraceEvent( |
| 1433 JSONStream* js, | 1342 JSONStream* js, |
| 1434 TimelineEventFilter* filter) { | 1343 TimelineEventFilter* filter) { |
| 1435 if (!FLAG_support_service) { | 1344 if (!FLAG_support_service) { |
| 1436 return; | 1345 return; |
| 1437 } | 1346 } |
| 1438 JSONArray events(js); | 1347 JSONArray events(js); |
| 1439 PrintJSONMeta(&events); | 1348 PrintJSONMeta(&events); |
| 1440 PrintJSONEvents(&events, filter); | 1349 PrintJSONEvents(&events, filter); |
| 1441 } | 1350 } |
| 1442 | 1351 |
| 1443 | |
| 1444 TimelineEventBlock* TimelineEventFixedBufferRecorder::GetHeadBlockLocked() { | 1352 TimelineEventBlock* TimelineEventFixedBufferRecorder::GetHeadBlockLocked() { |
| 1445 return blocks_[0]; | 1353 return blocks_[0]; |
| 1446 } | 1354 } |
| 1447 | 1355 |
| 1448 | |
| 1449 void TimelineEventFixedBufferRecorder::Clear() { | 1356 void TimelineEventFixedBufferRecorder::Clear() { |
| 1450 MutexLocker ml(&lock_); | 1357 MutexLocker ml(&lock_); |
| 1451 for (intptr_t i = 0; i < num_blocks_; i++) { | 1358 for (intptr_t i = 0; i < num_blocks_; i++) { |
| 1452 TimelineEventBlock* block = blocks_[i]; | 1359 TimelineEventBlock* block = blocks_[i]; |
| 1453 block->Reset(); | 1360 block->Reset(); |
| 1454 } | 1361 } |
| 1455 } | 1362 } |
| 1456 | 1363 |
| 1457 | |
| 1458 intptr_t TimelineEventFixedBufferRecorder::FindOldestBlockIndex() const { | 1364 intptr_t TimelineEventFixedBufferRecorder::FindOldestBlockIndex() const { |
| 1459 int64_t earliest_time = kMaxInt64; | 1365 int64_t earliest_time = kMaxInt64; |
| 1460 intptr_t earliest_index = -1; | 1366 intptr_t earliest_index = -1; |
| 1461 for (intptr_t block_idx = 0; block_idx < num_blocks_; block_idx++) { | 1367 for (intptr_t block_idx = 0; block_idx < num_blocks_; block_idx++) { |
| 1462 TimelineEventBlock* block = blocks_[block_idx]; | 1368 TimelineEventBlock* block = blocks_[block_idx]; |
| 1463 if (block->IsEmpty()) { | 1369 if (block->IsEmpty()) { |
| 1464 // Skip empty blocks. | 1370 // Skip empty blocks. |
| 1465 continue; | 1371 continue; |
| 1466 } | 1372 } |
| 1467 if (block->LowerTimeBound() < earliest_time) { | 1373 if (block->LowerTimeBound() < earliest_time) { |
| 1468 earliest_time = block->LowerTimeBound(); | 1374 earliest_time = block->LowerTimeBound(); |
| 1469 earliest_index = block_idx; | 1375 earliest_index = block_idx; |
| 1470 } | 1376 } |
| 1471 } | 1377 } |
| 1472 return earliest_index; | 1378 return earliest_index; |
| 1473 } | 1379 } |
| 1474 | 1380 |
| 1475 | |
| 1476 TimelineEvent* TimelineEventFixedBufferRecorder::StartEvent() { | 1381 TimelineEvent* TimelineEventFixedBufferRecorder::StartEvent() { |
| 1477 return ThreadBlockStartEvent(); | 1382 return ThreadBlockStartEvent(); |
| 1478 } | 1383 } |
| 1479 | 1384 |
| 1480 | |
| 1481 void TimelineEventFixedBufferRecorder::CompleteEvent(TimelineEvent* event) { | 1385 void TimelineEventFixedBufferRecorder::CompleteEvent(TimelineEvent* event) { |
| 1482 if (event == NULL) { | 1386 if (event == NULL) { |
| 1483 return; | 1387 return; |
| 1484 } | 1388 } |
| 1485 ThreadBlockCompleteEvent(event); | 1389 ThreadBlockCompleteEvent(event); |
| 1486 } | 1390 } |
| 1487 | 1391 |
| 1488 | |
| 1489 TimelineEventSystraceRecorder::TimelineEventSystraceRecorder(intptr_t capacity) | 1392 TimelineEventSystraceRecorder::TimelineEventSystraceRecorder(intptr_t capacity) |
| 1490 : TimelineEventFixedBufferRecorder(capacity), systrace_fd_(-1) { | 1393 : TimelineEventFixedBufferRecorder(capacity), systrace_fd_(-1) { |
| 1491 #if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) | 1394 #if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) |
| 1492 const char* kSystracePath = "/sys/kernel/debug/tracing/trace_marker"; | 1395 const char* kSystracePath = "/sys/kernel/debug/tracing/trace_marker"; |
| 1493 systrace_fd_ = open(kSystracePath, O_WRONLY); | 1396 systrace_fd_ = open(kSystracePath, O_WRONLY); |
| 1494 if ((systrace_fd_ < 0) && FLAG_trace_timeline) { | 1397 if ((systrace_fd_ < 0) && FLAG_trace_timeline) { |
| 1495 OS::PrintErr("TimelineEventSystraceRecorder: Could not open `%s`\n", | 1398 OS::PrintErr("TimelineEventSystraceRecorder: Could not open `%s`\n", |
| 1496 kSystracePath); | 1399 kSystracePath); |
| 1497 } | 1400 } |
| 1498 #else | 1401 #else |
| 1499 OS::PrintErr( | 1402 OS::PrintErr( |
| 1500 "Warning: The systrace timeline recorder is equivalent to the" | 1403 "Warning: The systrace timeline recorder is equivalent to the" |
| 1501 "ring recorder on this platform."); | 1404 "ring recorder on this platform."); |
| 1502 #endif | 1405 #endif |
| 1503 } | 1406 } |
| 1504 | 1407 |
| 1505 | |
| 1506 TimelineEventSystraceRecorder::~TimelineEventSystraceRecorder() { | 1408 TimelineEventSystraceRecorder::~TimelineEventSystraceRecorder() { |
| 1507 #if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) | 1409 #if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) |
| 1508 if (systrace_fd_ >= 0) { | 1410 if (systrace_fd_ >= 0) { |
| 1509 close(systrace_fd_); | 1411 close(systrace_fd_); |
| 1510 } | 1412 } |
| 1511 #endif | 1413 #endif |
| 1512 } | 1414 } |
| 1513 | 1415 |
| 1514 | |
| 1515 TimelineEventBlock* TimelineEventSystraceRecorder::GetNewBlockLocked() { | 1416 TimelineEventBlock* TimelineEventSystraceRecorder::GetNewBlockLocked() { |
| 1516 // TODO(johnmccutchan): This function should only hand out blocks | 1417 // TODO(johnmccutchan): This function should only hand out blocks |
| 1517 // which have been marked as finished. | 1418 // which have been marked as finished. |
| 1518 if (block_cursor_ == num_blocks_) { | 1419 if (block_cursor_ == num_blocks_) { |
| 1519 block_cursor_ = 0; | 1420 block_cursor_ = 0; |
| 1520 } | 1421 } |
| 1521 TimelineEventBlock* block = blocks_[block_cursor_++]; | 1422 TimelineEventBlock* block = blocks_[block_cursor_++]; |
| 1522 block->Reset(); | 1423 block->Reset(); |
| 1523 block->Open(); | 1424 block->Open(); |
| 1524 return block; | 1425 return block; |
| 1525 } | 1426 } |
| 1526 | 1427 |
| 1527 | |
| 1528 void TimelineEventSystraceRecorder::CompleteEvent(TimelineEvent* event) { | 1428 void TimelineEventSystraceRecorder::CompleteEvent(TimelineEvent* event) { |
| 1529 if (event == NULL) { | 1429 if (event == NULL) { |
| 1530 return; | 1430 return; |
| 1531 } | 1431 } |
| 1532 #if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) | 1432 #if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) |
| 1533 if (systrace_fd_ >= 0) { | 1433 if (systrace_fd_ >= 0) { |
| 1534 // Serialize to the systrace format. | 1434 // Serialize to the systrace format. |
| 1535 const intptr_t kBufferLength = 1024; | 1435 const intptr_t kBufferLength = 1024; |
| 1536 char buffer[kBufferLength]; | 1436 char buffer[kBufferLength]; |
| 1537 const intptr_t event_length = | 1437 const intptr_t event_length = |
| 1538 event->PrintSystrace(&buffer[0], kBufferLength); | 1438 event->PrintSystrace(&buffer[0], kBufferLength); |
| 1539 if (event_length > 0) { | 1439 if (event_length > 0) { |
| 1540 ssize_t __result; | 1440 ssize_t __result; |
| 1541 // Repeatedly attempt the write while we are being interrupted. | 1441 // Repeatedly attempt the write while we are being interrupted. |
| 1542 do { | 1442 do { |
| 1543 __result = write(systrace_fd_, buffer, event_length); | 1443 __result = write(systrace_fd_, buffer, event_length); |
| 1544 } while ((__result == -1L) && (errno == EINTR)); | 1444 } while ((__result == -1L) && (errno == EINTR)); |
| 1545 } | 1445 } |
| 1546 } | 1446 } |
| 1547 #endif | 1447 #endif |
| 1548 ThreadBlockCompleteEvent(event); | 1448 ThreadBlockCompleteEvent(event); |
| 1549 } | 1449 } |
| 1550 | 1450 |
| 1551 | |
| 1552 #if defined(HOST_OS_FUCHSIA) | 1451 #if defined(HOST_OS_FUCHSIA) |
| 1553 TimelineEventFuchsiaRecorder::TimelineEventFuchsiaRecorder(intptr_t capacity) | 1452 TimelineEventFuchsiaRecorder::TimelineEventFuchsiaRecorder(intptr_t capacity) |
| 1554 : TimelineEventFixedBufferRecorder(capacity) {} | 1453 : TimelineEventFixedBufferRecorder(capacity) {} |
| 1555 | 1454 |
| 1556 | 1455 |
| 1557 TimelineEventBlock* TimelineEventFuchsiaRecorder::GetNewBlockLocked() { | 1456 TimelineEventBlock* TimelineEventFuchsiaRecorder::GetNewBlockLocked() { |
| 1558 // TODO(johnmccutchan): This function should only hand out blocks | 1457 // TODO(johnmccutchan): This function should only hand out blocks |
| 1559 // which have been marked as finished. | 1458 // which have been marked as finished. |
| 1560 if (block_cursor_ == num_blocks_) { | 1459 if (block_cursor_ == num_blocks_) { |
| 1561 block_cursor_ = 0; | 1460 block_cursor_ = 0; |
| 1562 } | 1461 } |
| 1563 TimelineEventBlock* block = blocks_[block_cursor_++]; | 1462 TimelineEventBlock* block = blocks_[block_cursor_++]; |
| 1564 block->Reset(); | 1463 block->Reset(); |
| 1565 block->Open(); | 1464 block->Open(); |
| 1566 return block; | 1465 return block; |
| 1567 } | 1466 } |
| 1568 | 1467 |
| 1569 | |
| 1570 void TimelineEventFuchsiaRecorder::CompleteEvent(TimelineEvent* event) { | 1468 void TimelineEventFuchsiaRecorder::CompleteEvent(TimelineEvent* event) { |
| 1571 if (event == NULL) { | 1469 if (event == NULL) { |
| 1572 return; | 1470 return; |
| 1573 } | 1471 } |
| 1574 event->EmitFuchsiaEvent(); | 1472 event->EmitFuchsiaEvent(); |
| 1575 ThreadBlockCompleteEvent(event); | 1473 ThreadBlockCompleteEvent(event); |
| 1576 } | 1474 } |
| 1577 #endif // defined(HOST_OS_FUCHSIA) | 1475 #endif // defined(HOST_OS_FUCHSIA) |
| 1578 | 1476 |
| 1579 | |
| 1580 TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked() { | 1477 TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked() { |
| 1581 // TODO(johnmccutchan): This function should only hand out blocks | 1478 // TODO(johnmccutchan): This function should only hand out blocks |
| 1582 // which have been marked as finished. | 1479 // which have been marked as finished. |
| 1583 if (block_cursor_ == num_blocks_) { | 1480 if (block_cursor_ == num_blocks_) { |
| 1584 block_cursor_ = 0; | 1481 block_cursor_ = 0; |
| 1585 } | 1482 } |
| 1586 TimelineEventBlock* block = blocks_[block_cursor_++]; | 1483 TimelineEventBlock* block = blocks_[block_cursor_++]; |
| 1587 block->Reset(); | 1484 block->Reset(); |
| 1588 block->Open(); | 1485 block->Open(); |
| 1589 return block; | 1486 return block; |
| 1590 } | 1487 } |
| 1591 | 1488 |
| 1592 | |
| 1593 TimelineEventBlock* TimelineEventStartupRecorder::GetNewBlockLocked() { | 1489 TimelineEventBlock* TimelineEventStartupRecorder::GetNewBlockLocked() { |
| 1594 if (block_cursor_ == num_blocks_) { | 1490 if (block_cursor_ == num_blocks_) { |
| 1595 return NULL; | 1491 return NULL; |
| 1596 } | 1492 } |
| 1597 TimelineEventBlock* block = blocks_[block_cursor_++]; | 1493 TimelineEventBlock* block = blocks_[block_cursor_++]; |
| 1598 block->Reset(); | 1494 block->Reset(); |
| 1599 block->Open(); | 1495 block->Open(); |
| 1600 return block; | 1496 return block; |
| 1601 } | 1497 } |
| 1602 | 1498 |
| 1603 | |
| 1604 TimelineEventCallbackRecorder::TimelineEventCallbackRecorder() {} | 1499 TimelineEventCallbackRecorder::TimelineEventCallbackRecorder() {} |
| 1605 | 1500 |
| 1606 | |
| 1607 TimelineEventCallbackRecorder::~TimelineEventCallbackRecorder() {} | 1501 TimelineEventCallbackRecorder::~TimelineEventCallbackRecorder() {} |
| 1608 | 1502 |
| 1609 | |
| 1610 void TimelineEventCallbackRecorder::PrintJSON(JSONStream* js, | 1503 void TimelineEventCallbackRecorder::PrintJSON(JSONStream* js, |
| 1611 TimelineEventFilter* filter) { | 1504 TimelineEventFilter* filter) { |
| 1612 if (!FLAG_support_service) { | 1505 if (!FLAG_support_service) { |
| 1613 return; | 1506 return; |
| 1614 } | 1507 } |
| 1615 JSONObject topLevel(js); | 1508 JSONObject topLevel(js); |
| 1616 topLevel.AddProperty("type", "_Timeline"); | 1509 topLevel.AddProperty("type", "_Timeline"); |
| 1617 { | 1510 { |
| 1618 JSONArray events(&topLevel, "traceEvents"); | 1511 JSONArray events(&topLevel, "traceEvents"); |
| 1619 PrintJSONMeta(&events); | 1512 PrintJSONMeta(&events); |
| 1620 } | 1513 } |
| 1621 } | 1514 } |
| 1622 | 1515 |
| 1623 | |
| 1624 void TimelineEventCallbackRecorder::PrintTraceEvent( | 1516 void TimelineEventCallbackRecorder::PrintTraceEvent( |
| 1625 JSONStream* js, | 1517 JSONStream* js, |
| 1626 TimelineEventFilter* filter) { | 1518 TimelineEventFilter* filter) { |
| 1627 if (!FLAG_support_service) { | 1519 if (!FLAG_support_service) { |
| 1628 return; | 1520 return; |
| 1629 } | 1521 } |
| 1630 JSONArray events(js); | 1522 JSONArray events(js); |
| 1631 } | 1523 } |
| 1632 | 1524 |
| 1633 | |
| 1634 TimelineEvent* TimelineEventCallbackRecorder::StartEvent() { | 1525 TimelineEvent* TimelineEventCallbackRecorder::StartEvent() { |
| 1635 TimelineEvent* event = new TimelineEvent(); | 1526 TimelineEvent* event = new TimelineEvent(); |
| 1636 return event; | 1527 return event; |
| 1637 } | 1528 } |
| 1638 | 1529 |
| 1639 | |
| 1640 void TimelineEventCallbackRecorder::CompleteEvent(TimelineEvent* event) { | 1530 void TimelineEventCallbackRecorder::CompleteEvent(TimelineEvent* event) { |
| 1641 OnEvent(event); | 1531 OnEvent(event); |
| 1642 delete event; | 1532 delete event; |
| 1643 } | 1533 } |
| 1644 | 1534 |
| 1645 | |
| 1646 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder() | 1535 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder() |
| 1647 : head_(NULL), block_index_(0) {} | 1536 : head_(NULL), block_index_(0) {} |
| 1648 | 1537 |
| 1649 TimelineEventEndlessRecorder::~TimelineEventEndlessRecorder() { | 1538 TimelineEventEndlessRecorder::~TimelineEventEndlessRecorder() { |
| 1650 TimelineEventBlock* current = head_; | 1539 TimelineEventBlock* current = head_; |
| 1651 head_ = NULL; | 1540 head_ = NULL; |
| 1652 | 1541 |
| 1653 while (current != NULL) { | 1542 while (current != NULL) { |
| 1654 TimelineEventBlock* next = current->next(); | 1543 TimelineEventBlock* next = current->next(); |
| 1655 delete current; | 1544 delete current; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1666 topLevel.AddProperty("type", "_Timeline"); | 1555 topLevel.AddProperty("type", "_Timeline"); |
| 1667 { | 1556 { |
| 1668 JSONArray events(&topLevel, "traceEvents"); | 1557 JSONArray events(&topLevel, "traceEvents"); |
| 1669 PrintJSONMeta(&events); | 1558 PrintJSONMeta(&events); |
| 1670 PrintJSONEvents(&events, filter); | 1559 PrintJSONEvents(&events, filter); |
| 1671 } | 1560 } |
| 1672 topLevel.AddPropertyTimeMicros("timeOriginMicros", TimeOriginMicros()); | 1561 topLevel.AddPropertyTimeMicros("timeOriginMicros", TimeOriginMicros()); |
| 1673 topLevel.AddPropertyTimeMicros("timeExtentMicros", TimeExtentMicros()); | 1562 topLevel.AddPropertyTimeMicros("timeExtentMicros", TimeExtentMicros()); |
| 1674 } | 1563 } |
| 1675 | 1564 |
| 1676 | |
| 1677 void TimelineEventEndlessRecorder::PrintTraceEvent( | 1565 void TimelineEventEndlessRecorder::PrintTraceEvent( |
| 1678 JSONStream* js, | 1566 JSONStream* js, |
| 1679 TimelineEventFilter* filter) { | 1567 TimelineEventFilter* filter) { |
| 1680 if (!FLAG_support_service) { | 1568 if (!FLAG_support_service) { |
| 1681 return; | 1569 return; |
| 1682 } | 1570 } |
| 1683 JSONArray events(js); | 1571 JSONArray events(js); |
| 1684 PrintJSONMeta(&events); | 1572 PrintJSONMeta(&events); |
| 1685 PrintJSONEvents(&events, filter); | 1573 PrintJSONEvents(&events, filter); |
| 1686 } | 1574 } |
| 1687 | 1575 |
| 1688 | |
| 1689 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() { | 1576 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() { |
| 1690 return head_; | 1577 return head_; |
| 1691 } | 1578 } |
| 1692 | 1579 |
| 1693 | |
| 1694 TimelineEvent* TimelineEventEndlessRecorder::StartEvent() { | 1580 TimelineEvent* TimelineEventEndlessRecorder::StartEvent() { |
| 1695 return ThreadBlockStartEvent(); | 1581 return ThreadBlockStartEvent(); |
| 1696 } | 1582 } |
| 1697 | 1583 |
| 1698 | |
| 1699 void TimelineEventEndlessRecorder::CompleteEvent(TimelineEvent* event) { | 1584 void TimelineEventEndlessRecorder::CompleteEvent(TimelineEvent* event) { |
| 1700 if (event == NULL) { | 1585 if (event == NULL) { |
| 1701 return; | 1586 return; |
| 1702 } | 1587 } |
| 1703 ThreadBlockCompleteEvent(event); | 1588 ThreadBlockCompleteEvent(event); |
| 1704 } | 1589 } |
| 1705 | 1590 |
| 1706 | |
| 1707 TimelineEventBlock* TimelineEventEndlessRecorder::GetNewBlockLocked() { | 1591 TimelineEventBlock* TimelineEventEndlessRecorder::GetNewBlockLocked() { |
| 1708 TimelineEventBlock* block = new TimelineEventBlock(block_index_++); | 1592 TimelineEventBlock* block = new TimelineEventBlock(block_index_++); |
| 1709 block->set_next(head_); | 1593 block->set_next(head_); |
| 1710 block->Open(); | 1594 block->Open(); |
| 1711 head_ = block; | 1595 head_ = block; |
| 1712 if (FLAG_trace_timeline) { | 1596 if (FLAG_trace_timeline) { |
| 1713 OS::Print("Created new block %p\n", block); | 1597 OS::Print("Created new block %p\n", block); |
| 1714 } | 1598 } |
| 1715 return head_; | 1599 return head_; |
| 1716 } | 1600 } |
| 1717 | 1601 |
| 1718 static int TimelineEventBlockCompare(TimelineEventBlock* const* a, | 1602 static int TimelineEventBlockCompare(TimelineEventBlock* const* a, |
| 1719 TimelineEventBlock* const* b) { | 1603 TimelineEventBlock* const* b) { |
| 1720 return (*a)->LowerTimeBound() - (*b)->LowerTimeBound(); | 1604 return (*a)->LowerTimeBound() - (*b)->LowerTimeBound(); |
| 1721 } | 1605 } |
| 1722 | 1606 |
| 1723 | |
| 1724 void TimelineEventEndlessRecorder::PrintJSONEvents( | 1607 void TimelineEventEndlessRecorder::PrintJSONEvents( |
| 1725 JSONArray* events, | 1608 JSONArray* events, |
| 1726 TimelineEventFilter* filter) { | 1609 TimelineEventFilter* filter) { |
| 1727 if (!FLAG_support_service) { | 1610 if (!FLAG_support_service) { |
| 1728 return; | 1611 return; |
| 1729 } | 1612 } |
| 1730 MutexLocker ml(&lock_); | 1613 MutexLocker ml(&lock_); |
| 1731 ResetTimeTracking(); | 1614 ResetTimeTracking(); |
| 1732 // Collect all interesting blocks. | 1615 // Collect all interesting blocks. |
| 1733 MallocGrowableArray<TimelineEventBlock*> blocks(8); | 1616 MallocGrowableArray<TimelineEventBlock*> blocks(8); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1755 event->Within(filter->time_origin_micros(), | 1638 event->Within(filter->time_origin_micros(), |
| 1756 filter->time_extent_micros())) { | 1639 filter->time_extent_micros())) { |
| 1757 ReportTime(event->LowTime()); | 1640 ReportTime(event->LowTime()); |
| 1758 ReportTime(event->HighTime()); | 1641 ReportTime(event->HighTime()); |
| 1759 events->AddValue(event); | 1642 events->AddValue(event); |
| 1760 } | 1643 } |
| 1761 } | 1644 } |
| 1762 } | 1645 } |
| 1763 } | 1646 } |
| 1764 | 1647 |
| 1765 | |
| 1766 void TimelineEventEndlessRecorder::Clear() { | 1648 void TimelineEventEndlessRecorder::Clear() { |
| 1767 TimelineEventBlock* current = head_; | 1649 TimelineEventBlock* current = head_; |
| 1768 while (current != NULL) { | 1650 while (current != NULL) { |
| 1769 TimelineEventBlock* next = current->next(); | 1651 TimelineEventBlock* next = current->next(); |
| 1770 delete current; | 1652 delete current; |
| 1771 current = next; | 1653 current = next; |
| 1772 } | 1654 } |
| 1773 head_ = NULL; | 1655 head_ = NULL; |
| 1774 block_index_ = 0; | 1656 block_index_ = 0; |
| 1775 OSThread* thread = OSThread::Current(); | 1657 OSThread* thread = OSThread::Current(); |
| 1776 thread->set_timeline_block(NULL); | 1658 thread->set_timeline_block(NULL); |
| 1777 } | 1659 } |
| 1778 | 1660 |
| 1779 | |
| 1780 TimelineEventBlock::TimelineEventBlock(intptr_t block_index) | 1661 TimelineEventBlock::TimelineEventBlock(intptr_t block_index) |
| 1781 : next_(NULL), | 1662 : next_(NULL), |
| 1782 length_(0), | 1663 length_(0), |
| 1783 block_index_(block_index), | 1664 block_index_(block_index), |
| 1784 thread_id_(OSThread::kInvalidThreadId), | 1665 thread_id_(OSThread::kInvalidThreadId), |
| 1785 in_use_(false) {} | 1666 in_use_(false) {} |
| 1786 | 1667 |
| 1787 | |
| 1788 TimelineEventBlock::~TimelineEventBlock() { | 1668 TimelineEventBlock::~TimelineEventBlock() { |
| 1789 Reset(); | 1669 Reset(); |
| 1790 } | 1670 } |
| 1791 | 1671 |
| 1792 | |
| 1793 void TimelineEventBlock::PrintJSON(JSONStream* js) const { | 1672 void TimelineEventBlock::PrintJSON(JSONStream* js) const { |
| 1794 ASSERT(!in_use()); | 1673 ASSERT(!in_use()); |
| 1795 JSONArray events(js); | 1674 JSONArray events(js); |
| 1796 for (intptr_t i = 0; i < length(); i++) { | 1675 for (intptr_t i = 0; i < length(); i++) { |
| 1797 const TimelineEvent* event = At(i); | 1676 const TimelineEvent* event = At(i); |
| 1798 events.AddValue(event); | 1677 events.AddValue(event); |
| 1799 } | 1678 } |
| 1800 } | 1679 } |
| 1801 | 1680 |
| 1802 | |
| 1803 TimelineEvent* TimelineEventBlock::StartEvent() { | 1681 TimelineEvent* TimelineEventBlock::StartEvent() { |
| 1804 ASSERT(!IsFull()); | 1682 ASSERT(!IsFull()); |
| 1805 if (FLAG_trace_timeline) { | 1683 if (FLAG_trace_timeline) { |
| 1806 OSThread* os_thread = OSThread::Current(); | 1684 OSThread* os_thread = OSThread::Current(); |
| 1807 ASSERT(os_thread != NULL); | 1685 ASSERT(os_thread != NULL); |
| 1808 intptr_t tid = OSThread::ThreadIdToIntPtr(os_thread->id()); | 1686 intptr_t tid = OSThread::ThreadIdToIntPtr(os_thread->id()); |
| 1809 OS::Print("StartEvent in block %p for thread %" Px "\n", this, tid); | 1687 OS::Print("StartEvent in block %p for thread %" Px "\n", this, tid); |
| 1810 } | 1688 } |
| 1811 return &events_[length_++]; | 1689 return &events_[length_++]; |
| 1812 } | 1690 } |
| 1813 | 1691 |
| 1814 | |
| 1815 int64_t TimelineEventBlock::LowerTimeBound() const { | 1692 int64_t TimelineEventBlock::LowerTimeBound() const { |
| 1816 if (length_ == 0) { | 1693 if (length_ == 0) { |
| 1817 return kMaxInt64; | 1694 return kMaxInt64; |
| 1818 } | 1695 } |
| 1819 ASSERT(length_ > 0); | 1696 ASSERT(length_ > 0); |
| 1820 return events_[0].TimeOrigin(); | 1697 return events_[0].TimeOrigin(); |
| 1821 } | 1698 } |
| 1822 | 1699 |
| 1823 | |
| 1824 bool TimelineEventBlock::CheckBlock() { | 1700 bool TimelineEventBlock::CheckBlock() { |
| 1825 if (length() == 0) { | 1701 if (length() == 0) { |
| 1826 return true; | 1702 return true; |
| 1827 } | 1703 } |
| 1828 | 1704 |
| 1829 for (intptr_t i = 0; i < length(); i++) { | 1705 for (intptr_t i = 0; i < length(); i++) { |
| 1830 if (At(i)->thread() != thread_id()) { | 1706 if (At(i)->thread() != thread_id()) { |
| 1831 return false; | 1707 return false; |
| 1832 } | 1708 } |
| 1833 } | 1709 } |
| 1834 | 1710 |
| 1835 // - events have monotonically increasing timestamps. | 1711 // - events have monotonically increasing timestamps. |
| 1836 int64_t last_time = LowerTimeBound(); | 1712 int64_t last_time = LowerTimeBound(); |
| 1837 for (intptr_t i = 0; i < length(); i++) { | 1713 for (intptr_t i = 0; i < length(); i++) { |
| 1838 if (last_time > At(i)->TimeOrigin()) { | 1714 if (last_time > At(i)->TimeOrigin()) { |
| 1839 return false; | 1715 return false; |
| 1840 } | 1716 } |
| 1841 last_time = At(i)->TimeOrigin(); | 1717 last_time = At(i)->TimeOrigin(); |
| 1842 } | 1718 } |
| 1843 | 1719 |
| 1844 return true; | 1720 return true; |
| 1845 } | 1721 } |
| 1846 | 1722 |
| 1847 | |
| 1848 void TimelineEventBlock::Reset() { | 1723 void TimelineEventBlock::Reset() { |
| 1849 for (intptr_t i = 0; i < kBlockSize; i++) { | 1724 for (intptr_t i = 0; i < kBlockSize; i++) { |
| 1850 // Clear any extra data. | 1725 // Clear any extra data. |
| 1851 events_[i].Reset(); | 1726 events_[i].Reset(); |
| 1852 } | 1727 } |
| 1853 length_ = 0; | 1728 length_ = 0; |
| 1854 thread_id_ = OSThread::kInvalidThreadId; | 1729 thread_id_ = OSThread::kInvalidThreadId; |
| 1855 in_use_ = false; | 1730 in_use_ = false; |
| 1856 } | 1731 } |
| 1857 | 1732 |
| 1858 | |
| 1859 void TimelineEventBlock::Open() { | 1733 void TimelineEventBlock::Open() { |
| 1860 OSThread* os_thread = OSThread::Current(); | 1734 OSThread* os_thread = OSThread::Current(); |
| 1861 ASSERT(os_thread != NULL); | 1735 ASSERT(os_thread != NULL); |
| 1862 thread_id_ = os_thread->trace_id(); | 1736 thread_id_ = os_thread->trace_id(); |
| 1863 in_use_ = true; | 1737 in_use_ = true; |
| 1864 } | 1738 } |
| 1865 | 1739 |
| 1866 | |
| 1867 void TimelineEventBlock::Finish() { | 1740 void TimelineEventBlock::Finish() { |
| 1868 if (FLAG_trace_timeline) { | 1741 if (FLAG_trace_timeline) { |
| 1869 OS::Print("Finish block %p\n", this); | 1742 OS::Print("Finish block %p\n", this); |
| 1870 } | 1743 } |
| 1871 in_use_ = false; | 1744 in_use_ = false; |
| 1872 if (Service::timeline_stream.enabled()) { | 1745 if (Service::timeline_stream.enabled()) { |
| 1873 ServiceEvent service_event(NULL, ServiceEvent::kTimelineEvents); | 1746 ServiceEvent service_event(NULL, ServiceEvent::kTimelineEvents); |
| 1874 service_event.set_timeline_event_block(this); | 1747 service_event.set_timeline_event_block(this); |
| 1875 Service::HandleEvent(&service_event); | 1748 Service::HandleEvent(&service_event); |
| 1876 } | 1749 } |
| 1877 } | 1750 } |
| 1878 | 1751 |
| 1879 | |
| 1880 TimelineEventBlockIterator::TimelineEventBlockIterator( | 1752 TimelineEventBlockIterator::TimelineEventBlockIterator( |
| 1881 TimelineEventRecorder* recorder) | 1753 TimelineEventRecorder* recorder) |
| 1882 : current_(NULL), recorder_(NULL) { | 1754 : current_(NULL), recorder_(NULL) { |
| 1883 Reset(recorder); | 1755 Reset(recorder); |
| 1884 } | 1756 } |
| 1885 | 1757 |
| 1886 | |
| 1887 TimelineEventBlockIterator::~TimelineEventBlockIterator() { | 1758 TimelineEventBlockIterator::~TimelineEventBlockIterator() { |
| 1888 Reset(NULL); | 1759 Reset(NULL); |
| 1889 } | 1760 } |
| 1890 | 1761 |
| 1891 | |
| 1892 void TimelineEventBlockIterator::Reset(TimelineEventRecorder* recorder) { | 1762 void TimelineEventBlockIterator::Reset(TimelineEventRecorder* recorder) { |
| 1893 // Clear current. | 1763 // Clear current. |
| 1894 current_ = NULL; | 1764 current_ = NULL; |
| 1895 if (recorder_ != NULL) { | 1765 if (recorder_ != NULL) { |
| 1896 // Unlock old recorder. | 1766 // Unlock old recorder. |
| 1897 recorder_->lock_.Unlock(); | 1767 recorder_->lock_.Unlock(); |
| 1898 } | 1768 } |
| 1899 recorder_ = recorder; | 1769 recorder_ = recorder; |
| 1900 if (recorder_ == NULL) { | 1770 if (recorder_ == NULL) { |
| 1901 return; | 1771 return; |
| 1902 } | 1772 } |
| 1903 // Lock new recorder. | 1773 // Lock new recorder. |
| 1904 recorder_->lock_.Lock(); | 1774 recorder_->lock_.Lock(); |
| 1905 // Queue up first block. | 1775 // Queue up first block. |
| 1906 current_ = recorder_->GetHeadBlockLocked(); | 1776 current_ = recorder_->GetHeadBlockLocked(); |
| 1907 } | 1777 } |
| 1908 | 1778 |
| 1909 | |
| 1910 bool TimelineEventBlockIterator::HasNext() const { | 1779 bool TimelineEventBlockIterator::HasNext() const { |
| 1911 return current_ != NULL; | 1780 return current_ != NULL; |
| 1912 } | 1781 } |
| 1913 | 1782 |
| 1914 | |
| 1915 TimelineEventBlock* TimelineEventBlockIterator::Next() { | 1783 TimelineEventBlock* TimelineEventBlockIterator::Next() { |
| 1916 ASSERT(current_ != NULL); | 1784 ASSERT(current_ != NULL); |
| 1917 TimelineEventBlock* r = current_; | 1785 TimelineEventBlock* r = current_; |
| 1918 current_ = current_->next(); | 1786 current_ = current_->next(); |
| 1919 return r; | 1787 return r; |
| 1920 } | 1788 } |
| 1921 | 1789 |
| 1922 } // namespace dart | 1790 } // namespace dart |
| 1923 | 1791 |
| 1924 #endif // !PRODUCT | 1792 #endif // !PRODUCT |
| OLD | NEW |