| 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 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 event.PrintJSON(&js); | 181 event.PrintJSON(&js); |
| 166 | 182 |
| 167 // Check both arguments. | 183 // Check both arguments. |
| 168 EXPECT_SUBSTRING("\"arg1\":\"value1\"", js.ToCString()); | 184 EXPECT_SUBSTRING("\"arg1\":\"value1\"", js.ToCString()); |
| 169 EXPECT_SUBSTRING("\"arg2\":\"value2\"", js.ToCString()); | 185 EXPECT_SUBSTRING("\"arg2\":\"value2\"", js.ToCString()); |
| 170 } | 186 } |
| 171 } | 187 } |
| 172 | 188 |
| 173 | 189 |
| 174 TEST_CASE(TimelineEventBufferPrintJSON) { | 190 TEST_CASE(TimelineEventBufferPrintJSON) { |
| 175 Isolate* isolate = Isolate::Current(); | 191 TimelineEventRecorder* recorder = Timeline::recorder(); |
| 176 TimelineEventRecorder* recorder = isolate->timeline_event_recorder(); | |
| 177 JSONStream js; | 192 JSONStream js; |
| 178 recorder->PrintJSON(&js); | 193 TimelineEventFilter filter; |
| 194 recorder->PrintJSON(&js, &filter); |
| 179 // Check the type. This test will fail if we ever make Timeline public. | 195 // Check the type. This test will fail if we ever make Timeline public. |
| 180 EXPECT_SUBSTRING("\"type\":\"_Timeline\"", js.ToCString()); | 196 EXPECT_SUBSTRING("\"type\":\"_Timeline\"", js.ToCString()); |
| 181 // Check that there is a traceEvents array. | 197 // Check that there is a traceEvents array. |
| 182 EXPECT_SUBSTRING("\"traceEvents\":[", js.ToCString()); | 198 EXPECT_SUBSTRING("\"traceEvents\":[", js.ToCString()); |
| 183 } | 199 } |
| 184 | 200 |
| 185 | 201 |
| 186 // Count the number of each event type seen. | 202 // Count the number of each event type seen. |
| 187 class EventCounterRecorder : public TimelineEventStreamingRecorder { | 203 class EventCounterRecorder : public TimelineEventStreamingRecorder { |
| 188 public: | 204 public: |
| (...skipping 11 matching lines...) Expand all Loading... |
| 200 return counts_[type]; | 216 return counts_[type]; |
| 201 } | 217 } |
| 202 | 218 |
| 203 private: | 219 private: |
| 204 intptr_t counts_[TimelineEvent::kNumEventTypes]; | 220 intptr_t counts_[TimelineEvent::kNumEventTypes]; |
| 205 }; | 221 }; |
| 206 | 222 |
| 207 | 223 |
| 208 TEST_CASE(TimelineEventStreamingRecorderBasic) { | 224 TEST_CASE(TimelineEventStreamingRecorderBasic) { |
| 209 EventCounterRecorder* recorder = new EventCounterRecorder(); | 225 EventCounterRecorder* recorder = new EventCounterRecorder(); |
| 226 TimelineRecorderOverride override(recorder); |
| 210 | 227 |
| 211 // Initial counts are all zero. | 228 // Initial counts are all zero. |
| 212 for (intptr_t i = TimelineEvent::kNone + 1; | 229 for (intptr_t i = TimelineEvent::kNone + 1; |
| 213 i < TimelineEvent::kNumEventTypes; | 230 i < TimelineEvent::kNumEventTypes; |
| 214 i++) { | 231 i++) { |
| 215 EXPECT_EQ(0, recorder->CountFor(static_cast<TimelineEvent::EventType>(i))); | 232 EXPECT_EQ(0, recorder->CountFor(static_cast<TimelineEvent::EventType>(i))); |
| 216 } | 233 } |
| 217 | 234 |
| 218 // Create a test stream. | 235 // Create a test stream. |
| 219 TimelineStream stream; | 236 TimelineStream stream; |
| 220 stream.Init("testStream", true); | 237 stream.Init("testStream", true); |
| 221 stream.set_recorder(recorder); | |
| 222 | 238 |
| 223 TimelineEvent* event = NULL; | 239 TimelineEvent* event = NULL; |
| 224 | 240 |
| 225 event = stream.StartEvent(); | 241 event = stream.StartEvent(); |
| 226 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration)); | 242 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration)); |
| 227 event->DurationBegin("cabbage"); | 243 event->DurationBegin("cabbage"); |
| 228 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration)); | 244 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration)); |
| 229 event->DurationEnd(); | 245 event->DurationEnd(); |
| 230 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration)); | 246 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kDuration)); |
| 231 event->Complete(); | 247 event->Complete(); |
| 232 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kDuration)); | 248 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kDuration)); |
| 233 | 249 |
| 234 event = stream.StartEvent(); | 250 event = stream.StartEvent(); |
| 235 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kInstant)); | 251 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kInstant)); |
| 236 event->Instant("instantCabbage"); | 252 event->Instant("instantCabbage"); |
| 237 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kInstant)); | 253 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kInstant)); |
| 238 event->Complete(); | 254 event->Complete(); |
| 239 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kInstant)); | 255 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kInstant)); |
| 240 | 256 |
| 241 event = stream.StartEvent(); | 257 event = stream.StartEvent(); |
| 242 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncBegin)); | 258 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncBegin)); |
| 243 int64_t async_id = event->AsyncBegin("asyncBeginCabbage"); | 259 int64_t async_id = recorder->GetNextAsyncId(); |
| 244 EXPECT(async_id >= 0); | 260 EXPECT(async_id >= 0); |
| 261 event->AsyncBegin("asyncBeginCabbage", async_id); |
| 245 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncBegin)); | 262 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncBegin)); |
| 246 event->Complete(); | 263 event->Complete(); |
| 247 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kAsyncBegin)); | 264 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kAsyncBegin)); |
| 248 | 265 |
| 249 event = stream.StartEvent(); | 266 event = stream.StartEvent(); |
| 250 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncInstant)); | 267 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncInstant)); |
| 251 event->AsyncInstant("asyncInstantCabbage", async_id); | 268 event->AsyncInstant("asyncInstantCabbage", async_id); |
| 252 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncInstant)); | 269 EXPECT_EQ(0, recorder->CountFor(TimelineEvent::kAsyncInstant)); |
| 253 event->Complete(); | 270 event->Complete(); |
| 254 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kAsyncInstant)); | 271 EXPECT_EQ(1, recorder->CountFor(TimelineEvent::kAsyncInstant)); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 // Test that we wrapped. | 411 // Test that we wrapped. |
| 395 EXPECT(block_0 == recorder->GetNewBlock()); | 412 EXPECT(block_0 == recorder->GetNewBlock()); |
| 396 | 413 |
| 397 // Emit the earlier event into block_1. | 414 // Emit the earlier event into block_1. |
| 398 TimelineTestHelper::FakeThreadEvent(block_1, 2, "Alpha", &stream); | 415 TimelineTestHelper::FakeThreadEvent(block_1, 2, "Alpha", &stream); |
| 399 OS::Sleep(1); | 416 OS::Sleep(1); |
| 400 // Emit the later event into block_0. | 417 // Emit the later event into block_0. |
| 401 TimelineTestHelper::FakeThreadEvent(block_0, 2, "Beta", &stream); | 418 TimelineTestHelper::FakeThreadEvent(block_0, 2, "Beta", &stream); |
| 402 | 419 |
| 403 JSONStream js; | 420 JSONStream js; |
| 404 recorder->PrintJSON(&js); | 421 TimelineEventFilter filter; |
| 422 recorder->PrintJSON(&js, &filter); |
| 405 // trace-event has a requirement that events for a thread must have | 423 // trace-event has a requirement that events for a thread must have |
| 406 // monotonically increasing timestamps. | 424 // monotonically increasing timestamps. |
| 407 // Verify that "Alpha" comes before "Beta" even though "Beta" is in the first | 425 // Verify that "Alpha" comes before "Beta" even though "Beta" is in the first |
| 408 // block. | 426 // block. |
| 409 const char* alpha = strstr(js.ToCString(), "Alpha"); | 427 const char* alpha = strstr(js.ToCString(), "Alpha"); |
| 410 const char* beta = strstr(js.ToCString(), "Beta"); | 428 const char* beta = strstr(js.ToCString(), "Beta"); |
| 411 EXPECT(alpha < beta); | 429 EXPECT(alpha < beta); |
| 412 } | 430 } |
| 413 | 431 |
| 414 | 432 |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 EXPECT(!pauses.has_error()); | 594 EXPECT(!pauses.has_error()); |
| 577 EXPECT_EQ(10, pauses.InclusiveTime("a")); | 595 EXPECT_EQ(10, pauses.InclusiveTime("a")); |
| 578 EXPECT_EQ(10, pauses.ExclusiveTime("a")); | 596 EXPECT_EQ(10, pauses.ExclusiveTime("a")); |
| 579 EXPECT_EQ(10, pauses.MaxInclusiveTime("a")); | 597 EXPECT_EQ(10, pauses.MaxInclusiveTime("a")); |
| 580 EXPECT_EQ(8, pauses.MaxExclusiveTime("a")); | 598 EXPECT_EQ(8, pauses.MaxExclusiveTime("a")); |
| 581 } | 599 } |
| 582 TimelineTestHelper::Clear(recorder); | 600 TimelineTestHelper::Clear(recorder); |
| 583 } | 601 } |
| 584 | 602 |
| 585 } // namespace dart | 603 } // namespace dart |
| OLD | NEW |