| OLD | NEW | 
|---|
| 1 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/assert.h" | 5 #include "platform/assert.h" | 
| 6 | 6 | 
| 7 #include "vm/dart_api_impl.h" | 7 #include "vm/dart_api_impl.h" | 
| 8 #include "vm/dart_api_state.h" | 8 #include "vm/dart_api_state.h" | 
| 9 #include "vm/globals.h" | 9 #include "vm/globals.h" | 
| 10 #include "vm/profiler.h" | 10 #include "vm/profiler.h" | 
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 310     AllocationFilter filter(isolate->main_port(), class_a.id(), | 310     AllocationFilter filter(isolate->main_port(), class_a.id(), | 
| 311                             Dart_TimelineGetMicros(), 16000); | 311                             Dart_TimelineGetMicros(), 16000); | 
| 312     profile.Build(thread, &filter, Profile::kNoTags); | 312     profile.Build(thread, &filter, Profile::kNoTags); | 
| 313     // We should have no allocation samples because none occured within | 313     // We should have no allocation samples because none occured within | 
| 314     // the specified time range. | 314     // the specified time range. | 
| 315     EXPECT_EQ(0, profile.sample_count()); | 315     EXPECT_EQ(0, profile.sample_count()); | 
| 316   } | 316   } | 
| 317 } | 317 } | 
| 318 | 318 | 
| 319 | 319 | 
|  | 320 DART_NOINLINE static void NativeAllocationSampleHelper(char** result) { | 
|  | 321   ASSERT(result != NULL); | 
|  | 322   *result = static_cast<char*>(malloc(sizeof(char) * 1024)); | 
|  | 323 } | 
|  | 324 | 
|  | 325 | 
|  | 326 ISOLATE_UNIT_TEST_CASE(Profiler_NativeAllocation) { | 
|  | 327   bool enable_malloc_hooks_saved = FLAG_enable_malloc_hooks; | 
|  | 328   FLAG_enable_malloc_hooks = true; | 
|  | 329 | 
|  | 330   MallocHooks::InitOnce(); | 
|  | 331   MallocHooks::ResetStats(); | 
|  | 332   bool stack_trace_collection_enabled = | 
|  | 333       MallocHooks::stack_trace_collection_enabled(); | 
|  | 334   MallocHooks::set_stack_trace_collection_enabled(true); | 
|  | 335 | 
|  | 336   char* result = NULL; | 
|  | 337   const int64_t before_allocations_micros = Dart_TimelineGetMicros(); | 
|  | 338   NativeAllocationSampleHelper(&result); | 
|  | 339 | 
|  | 340   // Disable stack allocation stack trace collection to avoid muddying up | 
|  | 341   // results. | 
|  | 342   MallocHooks::set_stack_trace_collection_enabled(false); | 
|  | 343   const int64_t after_allocations_micros = Dart_TimelineGetMicros(); | 
|  | 344   const int64_t allocation_extent_micros = | 
|  | 345       after_allocations_micros - before_allocations_micros; | 
|  | 346 | 
|  | 347   // Walk the trie and do a sanity check of the allocation values associated | 
|  | 348   // with each node. | 
|  | 349   { | 
|  | 350     Thread* thread = Thread::Current(); | 
|  | 351     Isolate* isolate = thread->isolate(); | 
|  | 352     StackZone zone(thread); | 
|  | 353     HANDLESCOPE(thread); | 
|  | 354     Profile profile(isolate); | 
|  | 355 | 
|  | 356     // Filter for the class in the time range. | 
|  | 357     NativeAllocationSampleFilter filter(before_allocations_micros, | 
|  | 358                                         allocation_extent_micros); | 
|  | 359     profile.Build(thread, &filter, Profile::kNoTags); | 
|  | 360     // We should have 1 allocation sample. | 
|  | 361     EXPECT_EQ(1, profile.sample_count()); | 
|  | 362     ProfileTrieWalker walker(&profile); | 
|  | 363 | 
|  | 364     // Exclusive code: NativeAllocationSampleHelper -> main. | 
|  | 365     walker.Reset(Profile::kExclusiveCode); | 
|  | 366     // Move down from the root. | 
|  | 367     EXPECT(walker.Down()); | 
|  | 368     EXPECT_SUBSTRING("[Native]", walker.CurrentName()); | 
|  | 369     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 370     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 1024); | 
|  | 371     EXPECT(walker.Down()); | 
|  | 372     EXPECT_STREQ("dart::Dart_TestProfiler_NativeAllocation()", | 
|  | 373                  walker.CurrentName()); | 
|  | 374     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 375     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 376     EXPECT(walker.Down()); | 
|  | 377     EXPECT_STREQ("dart::TestCase::Run()", walker.CurrentName()); | 
|  | 378     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 379     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 380     EXPECT(walker.Down()); | 
|  | 381     EXPECT_STREQ("dart::TestCaseBase::RunTest()", walker.CurrentName()); | 
|  | 382     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 383     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 384     EXPECT(walker.Down()); | 
|  | 385     EXPECT_STREQ("dart::TestCaseBase::RunAll()", walker.CurrentName()); | 
|  | 386     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 387     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 388     EXPECT(walker.Down()); | 
|  | 389     EXPECT_STREQ("main", walker.CurrentName()); | 
|  | 390     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 391     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 392     EXPECT(!walker.Down()); | 
|  | 393 | 
|  | 394     // Inclusive code: main -> NativeAllocationSampleHelper. | 
|  | 395     walker.Reset(Profile::kInclusiveCode); | 
|  | 396     // Move down from the root. | 
|  | 397     EXPECT(walker.Down()); | 
|  | 398     EXPECT_STREQ("main", walker.CurrentName()); | 
|  | 399     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 400     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 401     EXPECT(walker.Down()); | 
|  | 402     EXPECT_STREQ("dart::TestCaseBase::RunAll()", walker.CurrentName()); | 
|  | 403     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 404     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 405     EXPECT(walker.Down()); | 
|  | 406     EXPECT_STREQ("dart::TestCaseBase::RunTest()", walker.CurrentName()); | 
|  | 407     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 408     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 409     EXPECT(walker.Down()); | 
|  | 410     EXPECT_STREQ("dart::TestCase::Run()", walker.CurrentName()); | 
|  | 411     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 412     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 413     EXPECT(walker.Down()); | 
|  | 414     EXPECT_STREQ("dart::Dart_TestProfiler_NativeAllocation()", | 
|  | 415                  walker.CurrentName()); | 
|  | 416     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 417     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 418     EXPECT(walker.Down()); | 
|  | 419     EXPECT_SUBSTRING("[Native]", walker.CurrentName()); | 
|  | 420     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 421     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 1024); | 
|  | 422     EXPECT(!walker.Down()); | 
|  | 423 | 
|  | 424     // Exclusive function: NativeAllocationSampleHelper -> main. | 
|  | 425     walker.Reset(Profile::kExclusiveFunction); | 
|  | 426     // Move down from the root. | 
|  | 427     EXPECT(walker.Down()); | 
|  | 428     EXPECT_SUBSTRING("[Native]", walker.CurrentName()); | 
|  | 429     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 430     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 1024); | 
|  | 431     EXPECT(walker.Down()); | 
|  | 432     EXPECT_STREQ("dart::Dart_TestProfiler_NativeAllocation()", | 
|  | 433                  walker.CurrentName()); | 
|  | 434     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 435     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 436     EXPECT(walker.Down()); | 
|  | 437     EXPECT_STREQ("dart::TestCase::Run()", walker.CurrentName()); | 
|  | 438     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 439     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 440     EXPECT(walker.Down()); | 
|  | 441     EXPECT_STREQ("dart::TestCaseBase::RunTest()", walker.CurrentName()); | 
|  | 442     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 443     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 444     EXPECT(walker.Down()); | 
|  | 445     EXPECT_STREQ("dart::TestCaseBase::RunAll()", walker.CurrentName()); | 
|  | 446     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 447     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 448     EXPECT(walker.Down()); | 
|  | 449     EXPECT_STREQ("main", walker.CurrentName()); | 
|  | 450     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 451     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 452     EXPECT(!walker.Down()); | 
|  | 453 | 
|  | 454     // Inclusive function: main -> NativeAllocationSampleHelper. | 
|  | 455     walker.Reset(Profile::kInclusiveFunction); | 
|  | 456     // Move down from the root. | 
|  | 457     EXPECT(walker.Down()); | 
|  | 458     EXPECT_STREQ("main", walker.CurrentName()); | 
|  | 459     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 460     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 461     EXPECT(walker.Down()); | 
|  | 462     EXPECT_STREQ("dart::TestCaseBase::RunAll()", walker.CurrentName()); | 
|  | 463     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 464     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 465     EXPECT(walker.Down()); | 
|  | 466     EXPECT_STREQ("dart::TestCaseBase::RunTest()", walker.CurrentName()); | 
|  | 467     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 468     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 469     EXPECT(walker.Down()); | 
|  | 470     EXPECT_STREQ("dart::TestCase::Run()", walker.CurrentName()); | 
|  | 471     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 472     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 473     EXPECT(walker.Down()); | 
|  | 474     EXPECT_STREQ("dart::Dart_TestProfiler_NativeAllocation()", | 
|  | 475                  walker.CurrentName()); | 
|  | 476     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 477     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0); | 
|  | 478     EXPECT(walker.Down()); | 
|  | 479     EXPECT_SUBSTRING("[Native]", walker.CurrentName()); | 
|  | 480     EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024); | 
|  | 481     EXPECT_EQ(walker.CurrentExclusiveAllocations(), 1024); | 
|  | 482     EXPECT(!walker.Down()); | 
|  | 483   } | 
|  | 484 | 
|  | 485   MallocHooks::set_stack_trace_collection_enabled(true); | 
|  | 486   free(result); | 
|  | 487   MallocHooks::set_stack_trace_collection_enabled(false); | 
|  | 488 | 
|  | 489   // Check to see that the native allocation sample associated with the memory | 
|  | 490   // freed above is marked as free and is no longer reported. | 
|  | 491   { | 
|  | 492     Thread* thread = Thread::Current(); | 
|  | 493     Isolate* isolate = thread->isolate(); | 
|  | 494     StackZone zone(thread); | 
|  | 495     HANDLESCOPE(thread); | 
|  | 496     Profile profile(isolate); | 
|  | 497 | 
|  | 498     // Filter for the class in the time range. | 
|  | 499     NativeAllocationSampleFilter filter(before_allocations_micros, | 
|  | 500                                         allocation_extent_micros); | 
|  | 501     profile.Build(thread, &filter, Profile::kNoTags); | 
|  | 502     // We should have 0 allocation samples since we freed the memory. | 
|  | 503     EXPECT_EQ(0, profile.sample_count()); | 
|  | 504   } | 
|  | 505 | 
|  | 506   // Query with a time filter where no allocations occurred. | 
|  | 507   { | 
|  | 508     Thread* thread = Thread::Current(); | 
|  | 509     Isolate* isolate = thread->isolate(); | 
|  | 510     StackZone zone(thread); | 
|  | 511     HANDLESCOPE(thread); | 
|  | 512     Profile profile(isolate); | 
|  | 513     NativeAllocationSampleFilter filter(Dart_TimelineGetMicros(), 16000); | 
|  | 514     profile.Build(thread, &filter, Profile::kNoTags); | 
|  | 515     // We should have no allocation samples because none occured within | 
|  | 516     // the specified time range. | 
|  | 517     EXPECT_EQ(0, profile.sample_count()); | 
|  | 518   } | 
|  | 519 | 
|  | 520   MallocHooks::set_stack_trace_collection_enabled( | 
|  | 521       stack_trace_collection_enabled); | 
|  | 522   MallocHooks::TearDown(); | 
|  | 523   FLAG_enable_malloc_hooks = enable_malloc_hooks_saved; | 
|  | 524 } | 
|  | 525 | 
|  | 526 | 
| 320 TEST_CASE(Profiler_ToggleRecordAllocation) { | 527 TEST_CASE(Profiler_ToggleRecordAllocation) { | 
| 321   DisableNativeProfileScope dnps; | 528   DisableNativeProfileScope dnps; | 
| 322   const char* kScript = | 529   const char* kScript = | 
| 323       "class A {\n" | 530       "class A {\n" | 
| 324       "  var a;\n" | 531       "  var a;\n" | 
| 325       "  var b;\n" | 532       "  var b;\n" | 
| 326       "}\n" | 533       "}\n" | 
| 327       "class B {\n" | 534       "class B {\n" | 
| 328       "  static boo() {\n" | 535       "  static boo() {\n" | 
| 329       "    return new A();\n" | 536       "    return new A();\n" | 
| (...skipping 2264 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2594   EXPECT_SUBSTRING("\"positions\":[\"TempMove\",39]", js.ToCString()); | 2801   EXPECT_SUBSTRING("\"positions\":[\"TempMove\",39]", js.ToCString()); | 
| 2595   // Verify exclusive ticks in main. | 2802   // Verify exclusive ticks in main. | 
| 2596   EXPECT_SUBSTRING("\"exclusiveTicks\":[1,0]", js.ToCString()); | 2803   EXPECT_SUBSTRING("\"exclusiveTicks\":[1,0]", js.ToCString()); | 
| 2597   // Verify inclusive ticks in main. | 2804   // Verify inclusive ticks in main. | 
| 2598   EXPECT_SUBSTRING("\"inclusiveTicks\":[1,2]", js.ToCString()); | 2805   EXPECT_SUBSTRING("\"inclusiveTicks\":[1,2]", js.ToCString()); | 
| 2599 } | 2806 } | 
| 2600 | 2807 | 
| 2601 #endif  // !PRODUCT | 2808 #endif  // !PRODUCT | 
| 2602 | 2809 | 
| 2603 }  // namespace dart | 2810 }  // namespace dart | 
| OLD | NEW | 
|---|