| 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 | 
|---|