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 "vm/timeline_analysis.h" | 5 #include "vm/timeline_analysis.h" |
6 | 6 |
7 #include "vm/flags.h" | 7 #include "vm/flags.h" |
8 #include "vm/log.h" | 8 #include "vm/log.h" |
9 #include "vm/os_thread.h" | 9 #include "vm/os_thread.h" |
10 | 10 |
(...skipping 21 matching lines...) Expand all Loading... |
32 ASSERT(*a != NULL); | 32 ASSERT(*a != NULL); |
33 ASSERT(b != NULL); | 33 ASSERT(b != NULL); |
34 ASSERT(*b != NULL); | 34 ASSERT(*b != NULL); |
35 return (*a)->LowerTimeBound() - (*b)->LowerTimeBound(); | 35 return (*a)->LowerTimeBound() - (*b)->LowerTimeBound(); |
36 } | 36 } |
37 | 37 |
38 | 38 |
39 void TimelineAnalysisThread::Finalize() { | 39 void TimelineAnalysisThread::Finalize() { |
40 blocks_.Sort(CompareBlocksLowerTimeBound); | 40 blocks_.Sort(CompareBlocksLowerTimeBound); |
41 if (FLAG_trace_timeline_analysis) { | 41 if (FLAG_trace_timeline_analysis) { |
42 ISL_Print("Thread %" Px " has %" Pd " blocks\n", | 42 THR_Print("Thread %" Px " has %" Pd " blocks\n", |
43 OSThread::ThreadIdToIntPtr(id_), | 43 OSThread::ThreadIdToIntPtr(id_), |
44 blocks_.length()); | 44 blocks_.length()); |
45 } | 45 } |
46 } | 46 } |
47 | 47 |
48 | 48 |
49 TimelineAnalysisThreadEventIterator::TimelineAnalysisThreadEventIterator( | 49 TimelineAnalysisThreadEventIterator::TimelineAnalysisThreadEventIterator( |
50 TimelineAnalysisThread* thread) { | 50 TimelineAnalysisThread* thread) { |
51 Reset(thread); | 51 Reset(thread); |
52 } | 52 } |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 TimelineEventBlockIterator it(recorder_); | 156 TimelineEventBlockIterator it(recorder_); |
157 while (it.HasNext()) { | 157 while (it.HasNext()) { |
158 TimelineEventBlock* block = it.Next(); | 158 TimelineEventBlock* block = it.Next(); |
159 ASSERT(block != NULL); | 159 ASSERT(block != NULL); |
160 if (block->IsEmpty()) { | 160 if (block->IsEmpty()) { |
161 // Skip empty blocks. | 161 // Skip empty blocks. |
162 continue; | 162 continue; |
163 } | 163 } |
164 if (!block->CheckBlock()) { | 164 if (!block->CheckBlock()) { |
165 if (FLAG_trace_timeline_analysis) { | 165 if (FLAG_trace_timeline_analysis) { |
166 ISL_Print("DiscoverThreads block %" Pd " " | 166 THR_Print("DiscoverThreads block %" Pd " " |
167 "violates invariants.\n", block->block_index()); | 167 "violates invariants.\n", block->block_index()); |
168 } | 168 } |
169 SetError("Block %" Pd " violates invariants. See " | 169 SetError("Block %" Pd " violates invariants. See " |
170 "TimelineEventBlock::CheckBlock", block->block_index()); | 170 "TimelineEventBlock::CheckBlock", block->block_index()); |
171 return; | 171 return; |
172 } | 172 } |
173 TimelineAnalysisThread* thread = GetOrAddThread(block->thread()); | 173 TimelineAnalysisThread* thread = GetOrAddThread(block->thread()); |
174 ASSERT(thread != NULL); | 174 ASSERT(thread != NULL); |
175 thread->AddBlock(block); | 175 thread->AddBlock(block); |
176 } | 176 } |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 } | 293 } |
294 | 294 |
295 | 295 |
296 void TimelinePauses::ProcessThread(TimelineAnalysisThread* thread) { | 296 void TimelinePauses::ProcessThread(TimelineAnalysisThread* thread) { |
297 ASSERT(thread != NULL); | 297 ASSERT(thread != NULL); |
298 stack_.Clear(); | 298 stack_.Clear(); |
299 labels_.Clear(); | 299 labels_.Clear(); |
300 | 300 |
301 TimelineAnalysisThreadEventIterator it(thread); | 301 TimelineAnalysisThreadEventIterator it(thread); |
302 if (FLAG_trace_timeline_analysis) { | 302 if (FLAG_trace_timeline_analysis) { |
303 ISL_Print(">>> TimelinePauses::ProcessThread %" Px "\n", | 303 THR_Print(">>> TimelinePauses::ProcessThread %" Px "\n", |
304 OSThread::ThreadIdToIntPtr(thread->id())); | 304 OSThread::ThreadIdToIntPtr(thread->id())); |
305 } | 305 } |
306 intptr_t event_count = 0; | 306 intptr_t event_count = 0; |
307 while (it.HasNext()) { | 307 while (it.HasNext()) { |
308 TimelineEvent* event = it.Next(); | 308 TimelineEvent* event = it.Next(); |
309 if (!event->IsFinishedDuration()) { | 309 if (!event->IsFinishedDuration()) { |
310 // We only care about finished duration events. | 310 // We only care about finished duration events. |
311 continue; | 311 continue; |
312 } | 312 } |
313 int64_t start = event->TimeOrigin(); | 313 int64_t start = event->TimeOrigin(); |
314 PopFinished(start); | 314 PopFinished(start); |
315 if (!CheckStack(event)) { | 315 if (!CheckStack(event)) { |
316 SetError("Duration check fail."); | 316 SetError("Duration check fail."); |
317 return; | 317 return; |
318 } | 318 } |
319 event_count++; | 319 event_count++; |
320 Push(event); | 320 Push(event); |
321 } | 321 } |
322 // Pop remaining stack. | 322 // Pop remaining stack. |
323 PopFinished(kMaxInt64); | 323 PopFinished(kMaxInt64); |
324 if (FLAG_trace_timeline_analysis) { | 324 if (FLAG_trace_timeline_analysis) { |
325 ISL_Print("<<< TimelinePauses::ProcessThread %" Px " had %" Pd " events\n", | 325 THR_Print("<<< TimelinePauses::ProcessThread %" Px " had %" Pd " events\n", |
326 OSThread::ThreadIdToIntPtr(thread->id()), | 326 OSThread::ThreadIdToIntPtr(thread->id()), |
327 event_count); | 327 event_count); |
328 } | 328 } |
329 } | 329 } |
330 | 330 |
331 | 331 |
332 // Verify that |event| is contained within all parent events on the stack. | 332 // Verify that |event| is contained within all parent events on the stack. |
333 bool TimelinePauses::CheckStack(TimelineEvent* event) { | 333 bool TimelinePauses::CheckStack(TimelineEvent* event) { |
334 ASSERT(event != NULL); | 334 ASSERT(event != NULL); |
335 for (intptr_t i = 0; i < stack_.length(); i++) { | 335 for (intptr_t i = 0; i < stack_.length(); i++) { |
336 const StackItem& slot = stack_.At(i); | 336 const StackItem& slot = stack_.At(i); |
337 if (!slot.event->DurationContains(event)) { | 337 if (!slot.event->DurationContains(event)) { |
338 return false; | 338 return false; |
339 } | 339 } |
340 } | 340 } |
341 return true; | 341 return true; |
342 } | 342 } |
343 | 343 |
344 | 344 |
345 void TimelinePauses::PopFinished(int64_t start) { | 345 void TimelinePauses::PopFinished(int64_t start) { |
346 while (stack_.length() > 0) { | 346 while (stack_.length() > 0) { |
347 const StackItem& top = stack_.Last(); | 347 const StackItem& top = stack_.Last(); |
348 if (top.event->DurationFinishedBefore(start)) { | 348 if (top.event->DurationFinishedBefore(start)) { |
349 top.pause_info->OnPop(top.exclusive_micros); | 349 top.pause_info->OnPop(top.exclusive_micros); |
350 // Top of stack completes before |start|. | 350 // Top of stack completes before |start|. |
351 stack_.RemoveLast(); | 351 stack_.RemoveLast(); |
352 if (FLAG_trace_timeline_analysis) { | 352 if (FLAG_trace_timeline_analysis) { |
353 ISL_Print("Popping %s (%" Pd64 " <= %" Pd64 ")\n", | 353 THR_Print("Popping %s (%" Pd64 " <= %" Pd64 ")\n", |
354 top.event->label(), | 354 top.event->label(), |
355 top.event->TimeEnd(), | 355 top.event->TimeEnd(), |
356 start); | 356 start); |
357 } | 357 } |
358 } else { | 358 } else { |
359 return; | 359 return; |
360 } | 360 } |
361 } | 361 } |
362 } | 362 } |
363 | 363 |
364 | 364 |
365 void TimelinePauses::Push(TimelineEvent* event) { | 365 void TimelinePauses::Push(TimelineEvent* event) { |
366 TimelineLabelPauseInfo* pause_info = GetOrAddLabelPauseInfo(event->label()); | 366 TimelineLabelPauseInfo* pause_info = GetOrAddLabelPauseInfo(event->label()); |
367 ASSERT(pause_info != NULL); | 367 ASSERT(pause_info != NULL); |
368 // |pause_info| will be running for |event->TimeDuration()|. | 368 // |pause_info| will be running for |event->TimeDuration()|. |
369 if (FLAG_trace_timeline_analysis) { | 369 if (FLAG_trace_timeline_analysis) { |
370 ISL_Print("Pushing %s %" Pd64 " us\n", | 370 THR_Print("Pushing %s %" Pd64 " us\n", |
371 pause_info->name(), | 371 pause_info->name(), |
372 event->TimeDuration()); | 372 event->TimeDuration()); |
373 } | 373 } |
374 pause_info->OnPush(event->TimeDuration(), IsLabelOnStack(event->label())); | 374 pause_info->OnPush(event->TimeDuration(), IsLabelOnStack(event->label())); |
375 if (StackDepth() > 0) { | 375 if (StackDepth() > 0) { |
376 StackItem& top = GetStackTop(); | 376 StackItem& top = GetStackTop(); |
377 // |top| is under |event|'s shadow, adjust the exclusive micros. | 377 // |top| is under |event|'s shadow, adjust the exclusive micros. |
378 top.exclusive_micros -= event->TimeDuration(); | 378 top.exclusive_micros -= event->TimeDuration(); |
379 } | 379 } |
380 // Push onto the stack. | 380 // Push onto the stack. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 if (pause_info != NULL) { | 416 if (pause_info != NULL) { |
417 return pause_info; | 417 return pause_info; |
418 } | 418 } |
419 // New label. | 419 // New label. |
420 pause_info = new TimelineLabelPauseInfo(name); | 420 pause_info = new TimelineLabelPauseInfo(name); |
421 labels_.Add(pause_info); | 421 labels_.Add(pause_info); |
422 return pause_info; | 422 return pause_info; |
423 } | 423 } |
424 | 424 |
425 } // namespace dart | 425 } // namespace dart |
OLD | NEW |