| 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 <cstring> | 5 #include <cstring> |
| 6 | 6 |
| 7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 | 8 |
| 9 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
| 10 #include "vm/dart_api_state.h" | 10 #include "vm/dart_api_state.h" |
| 11 #include "vm/globals.h" | 11 #include "vm/globals.h" |
| 12 #include "vm/timeline.h" | 12 #include "vm/timeline.h" |
| 13 #include "vm/timeline_analysis.h" | 13 #include "vm/timeline_analysis.h" |
| 14 #include "vm/unit_test.h" | 14 #include "vm/unit_test.h" |
| 15 | 15 |
| 16 namespace dart { | 16 namespace dart { |
| 17 | 17 |
| 18 class TimelineRecorderOverride : public ValueObject { |
| 19 public: |
| 20 explicit TimelineRecorderOverride(TimelineEventRecorder* new_recorder) |
| 21 : recorder_(Timeline::recorder()) { |
| 22 Timeline::recorder_ = new_recorder; |
| 23 } |
| 24 |
| 25 ~TimelineRecorderOverride() { |
| 26 Timeline::recorder_ = recorder_; |
| 27 } |
| 28 |
| 29 private: |
| 30 TimelineEventRecorder* recorder_; |
| 31 }; |
| 32 |
| 33 |
| 18 class TimelineTestHelper : public AllStatic { | 34 class TimelineTestHelper : public AllStatic { |
| 19 public: | 35 public: |
| 20 static void SetStream(TimelineEvent* event, TimelineStream* stream) { | 36 static void SetStream(TimelineEvent* event, TimelineStream* stream) { |
| 21 event->StreamInit(stream); | 37 event->StreamInit(stream); |
| 22 } | 38 } |
| 23 | 39 |
| 24 static TimelineEvent* FakeThreadEvent( | 40 static TimelineEvent* FakeThreadEvent( |
| 25 TimelineEventBlock* block, | 41 TimelineEventBlock* block, |
| 26 intptr_t ftid, | 42 intptr_t ftid, |
| 27 const char* label = "fake", | 43 const char* label = "fake", |
| (...skipping 18 matching lines...) Expand all Loading... |
| 46 ASSERT(label != NULL); | 62 ASSERT(label != NULL); |
| 47 TimelineEvent* event = recorder->StartEvent(); | 63 TimelineEvent* event = recorder->StartEvent(); |
| 48 ASSERT(event != NULL); | 64 ASSERT(event != NULL); |
| 49 event->Duration(label, start, end); | 65 event->Duration(label, start, end); |
| 50 } | 66 } |
| 51 | 67 |
| 52 static void Clear(TimelineEventEndlessRecorder* recorder) { | 68 static void Clear(TimelineEventEndlessRecorder* recorder) { |
| 53 ASSERT(recorder != NULL); | 69 ASSERT(recorder != NULL); |
| 54 recorder->Clear(); | 70 recorder->Clear(); |
| 55 } | 71 } |
| 72 |
| 73 static void FinishBlock(TimelineEventBlock* block) { |
| 74 block->Finish(); |
| 75 } |
| 56 }; | 76 }; |
| 57 | 77 |
| 58 | 78 |
| 59 TEST_CASE(TimelineEventIsValid) { | 79 TEST_CASE(TimelineEventIsValid) { |
| 60 // Create a test stream. | 80 // Create a test stream. |
| 61 TimelineStream stream; | 81 TimelineStream stream; |
| 62 stream.Init("testStream", true); | 82 stream.Init("testStream", true); |
| 63 | 83 |
| 64 TimelineEvent event; | 84 TimelineEvent event; |
| 65 TimelineTestHelper::SetStream(&event, &stream); | 85 TimelineTestHelper::SetStream(&event, &stream); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 event.PrintJSON(&js); | 185 event.PrintJSON(&js); |
| 166 | 186 |
| 167 // Check both arguments. | 187 // Check both arguments. |
| 168 EXPECT_SUBSTRING("\"arg1\":\"value1\"", js.ToCString()); | 188 EXPECT_SUBSTRING("\"arg1\":\"value1\"", js.ToCString()); |
| 169 EXPECT_SUBSTRING("\"arg2\":\"value2\"", js.ToCString()); | 189 EXPECT_SUBSTRING("\"arg2\":\"value2\"", js.ToCString()); |
| 170 } | 190 } |
| 171 } | 191 } |
| 172 | 192 |
| 173 | 193 |
| 174 TEST_CASE(TimelineEventBufferPrintJSON) { | 194 TEST_CASE(TimelineEventBufferPrintJSON) { |
| 175 Isolate* isolate = Isolate::Current(); | 195 TimelineEventRecorder* recorder = Timeline::recorder(); |
| 176 TimelineEventRecorder* recorder = isolate->timeline_event_recorder(); | |
| 177 JSONStream js; | 196 JSONStream js; |
| 178 recorder->PrintJSON(&js); | 197 TimelineEventFilter filter; |
| 198 recorder->PrintJSON(&js, &filter); |
| 179 // Check the type. This test will fail if we ever make Timeline public. | 199 // Check the type. This test will fail if we ever make Timeline public. |
| 180 EXPECT_SUBSTRING("\"type\":\"_Timeline\"", js.ToCString()); | 200 EXPECT_SUBSTRING("\"type\":\"_Timeline\"", js.ToCString()); |
| 181 // Check that there is a traceEvents array. | 201 // Check that there is a traceEvents array. |
| 182 EXPECT_SUBSTRING("\"traceEvents\":[", js.ToCString()); | 202 EXPECT_SUBSTRING("\"traceEvents\":[", js.ToCString()); |
| 183 } | 203 } |
| 184 | 204 |
| 185 | 205 |
| 186 // Count the number of each event type seen. | 206 // Count the number of each event type seen. |
| 187 class EventCounterRecorder : public TimelineEventStreamingRecorder { | 207 class EventCounterRecorder : public TimelineEventStreamingRecorder { |
| 188 public: | 208 public: |
| (...skipping 11 matching lines...) Expand all Loading... |
| 200 return counts_[type]; | 220 return counts_[type]; |
| 201 } | 221 } |
| 202 | 222 |
| 203 private: | 223 private: |
| 204 intptr_t counts_[TimelineEvent::kNumEventTypes]; | 224 intptr_t counts_[TimelineEvent::kNumEventTypes]; |
| 205 }; | 225 }; |
| 206 | 226 |
| 207 | 227 |
| 208 TEST_CASE(TimelineEventStreamingRecorderBasic) { | 228 TEST_CASE(TimelineEventStreamingRecorderBasic) { |
| 209 EventCounterRecorder* recorder = new EventCounterRecorder(); | 229 EventCounterRecorder* recorder = new EventCounterRecorder(); |
| 230 TimelineRecorderOverride override(recorder); |
| 210 | 231 |
| 211 // Initial counts are all zero. | 232 // Initial counts are all zero. |
| 212 for (intptr_t i = TimelineEvent::kNone + 1; | 233 for (intptr_t i = TimelineEvent::kNone + 1; |
| 213 i < TimelineEvent::kNumEventTypes; | 234 i < TimelineEvent::kNumEventTypes; |
| 214 i++) { | 235 i++) { |
| 215 EXPECT_EQ(0, recorder->CountFor(static_cast<TimelineEvent::EventType>(i))); | 236 EXPECT_EQ(0, recorder->CountFor(static_cast<TimelineEvent::EventType>(i))); |
| 216 } | 237 } |
| 217 | 238 |
| 218 // Create a test stream. | 239 // Create a test stream. |
| 219 TimelineStream stream; | 240 TimelineStream stream; |
| 220 stream.Init("testStream", true); | 241 stream.Init("testStream", true); |
| 221 stream.set_recorder(recorder); | |
| 222 | 242 |
| 223 TimelineEvent* event = NULL; | 243 TimelineEvent* event = NULL; |
| 224 | 244 |
| 225 event = stream.StartEvent(); | 245 event = stream.StartEvent(); |
| 226 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration)); | 246 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration)); |
| 227 event->DurationBegin("cabbage"); | 247 event->DurationBegin("cabbage"); |
| 228 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration)); | 248 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration)); |
| 229 event->DurationEnd(); | 249 event->DurationEnd(); |
| 230 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration)); | 250 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration)); |
| 231 event->Complete(); | 251 event->Complete(); |
| 232 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kDuration)); | 252 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kDuration)); |
| 233 | 253 |
| 234 event = stream.StartEvent(); | 254 event = stream.StartEvent(); |
| 235 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kInstant)); | 255 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kInstant)); |
| 236 event->Instant("instantCabbage"); | 256 event->Instant("instantCabbage"); |
| 237 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kInstant)); | 257 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kInstant)); |
| 238 event->Complete(); | 258 event->Complete(); |
| 239 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kInstant)); | 259 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kInstant)); |
| 240 | 260 |
| 241 event = stream.StartEvent(); | 261 event = stream.StartEvent(); |
| 242 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncBegin)); | 262 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncBegin)); |
| 243 int64_t async_id = event->AsyncBegin("asyncBeginCabbage"); | 263 int64_t async_id = recorder->GetNextAsyncId(); |
| 244 EXPECT(async_id >= 0); | 264 EXPECT(async_id >= 0); |
| 265 event->AsyncBegin("asyncBeginCabbage", async_id); |
| 245 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncBegin)); | 266 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncBegin)); |
| 246 event->Complete(); | 267 event->Complete(); |
| 247 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kAsyncBegin)); | 268 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kAsyncBegin)); |
| 248 | 269 |
| 249 event = stream.StartEvent(); | 270 event = stream.StartEvent(); |
| 250 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncInstant)); | 271 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncInstant)); |
| 251 event->AsyncInstant("asyncInstantCabbage", async_id); | 272 event->AsyncInstant("asyncInstantCabbage", async_id); |
| 252 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncInstant)); | 273 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncInstant)); |
| 253 event->Complete(); | 274 event->Complete(); |
| 254 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kAsyncInstant)); | 275 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kAsyncInstant)); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 EXPECT(block_1 != NULL); | 414 EXPECT(block_1 != NULL); |
| 394 // Test that we wrapped. | 415 // Test that we wrapped. |
| 395 EXPECT(block_0 == recorder->GetNewBlock()); | 416 EXPECT(block_0 == recorder->GetNewBlock()); |
| 396 | 417 |
| 397 // Emit the earlier event into block_1. | 418 // Emit the earlier event into block_1. |
| 398 TimelineTestHelper::FakeThreadEvent(block_1, 2, "Alpha", &stream); | 419 TimelineTestHelper::FakeThreadEvent(block_1, 2, "Alpha", &stream); |
| 399 OS::Sleep(1); | 420 OS::Sleep(1); |
| 400 // Emit the later event into block_0. | 421 // Emit the later event into block_0. |
| 401 TimelineTestHelper::FakeThreadEvent(block_0, 2, "Beta", &stream); | 422 TimelineTestHelper::FakeThreadEvent(block_0, 2, "Beta", &stream); |
| 402 | 423 |
| 424 TimelineTestHelper::FinishBlock(block_0); |
| 425 TimelineTestHelper::FinishBlock(block_1); |
| 426 |
| 403 JSONStream js; | 427 JSONStream js; |
| 404 recorder->PrintJSON(&js); | 428 TimelineEventFilter filter; |
| 429 recorder->PrintJSON(&js, &filter); |
| 405 // trace-event has a requirement that events for a thread must have | 430 // trace-event has a requirement that events for a thread must have |
| 406 // monotonically increasing timestamps. | 431 // monotonically increasing timestamps. |
| 407 // Verify that "Alpha" comes before "Beta" even though "Beta" is in the first | 432 // Verify that "Alpha" comes before "Beta" even though "Beta" is in the first |
| 408 // block. | 433 // block. |
| 409 const char* alpha = strstr(js.ToCString(), "Alpha"); | 434 const char* alpha = strstr(js.ToCString(), "Alpha"); |
| 410 const char* beta = strstr(js.ToCString(), "Beta"); | 435 const char* beta = strstr(js.ToCString(), "Beta"); |
| 411 EXPECT(alpha < beta); | 436 EXPECT(alpha < beta); |
| 412 } | 437 } |
| 413 | 438 |
| 414 | 439 |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 EXPECT(!pauses.has_error()); | 601 EXPECT(!pauses.has_error()); |
| 577 EXPECT_EQ(10, pauses.InclusiveTime("a")); | 602 EXPECT_EQ(10, pauses.InclusiveTime("a")); |
| 578 EXPECT_EQ(10, pauses.ExclusiveTime("a")); | 603 EXPECT_EQ(10, pauses.ExclusiveTime("a")); |
| 579 EXPECT_EQ(10, pauses.MaxInclusiveTime("a")); | 604 EXPECT_EQ(10, pauses.MaxInclusiveTime("a")); |
| 580 EXPECT_EQ(8, pauses.MaxExclusiveTime("a")); | 605 EXPECT_EQ(8, pauses.MaxExclusiveTime("a")); |
| 581 } | 606 } |
| 582 TimelineTestHelper::Clear(recorder); | 607 TimelineTestHelper::Clear(recorder); |
| 583 } | 608 } |
| 584 | 609 |
| 585 } // namespace dart | 610 } // namespace dart |
| OLD | NEW |