Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(944)

Unified Diff: runtime/vm/profiler_test.cc

Issue 2748403002: Added page to Observatory to display native memory allocation information. (Closed)
Patch Set: Final patch. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/profiler_service.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/profiler_test.cc
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index 08d3980cb74327a8544f11615c85330e43ec050d..5176943c54006ec7ef95479ce5f4e981f8ada696 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -317,6 +317,213 @@ TEST_CASE(Profiler_TrivialRecordAllocation) {
}
+DART_NOINLINE static void NativeAllocationSampleHelper(char** result) {
+ ASSERT(result != NULL);
+ *result = static_cast<char*>(malloc(sizeof(char) * 1024));
+}
+
+
+ISOLATE_UNIT_TEST_CASE(Profiler_NativeAllocation) {
+ bool enable_malloc_hooks_saved = FLAG_enable_malloc_hooks;
+ FLAG_enable_malloc_hooks = true;
+
+ MallocHooks::InitOnce();
+ MallocHooks::ResetStats();
+ bool stack_trace_collection_enabled =
+ MallocHooks::stack_trace_collection_enabled();
+ MallocHooks::set_stack_trace_collection_enabled(true);
+
+ char* result = NULL;
+ const int64_t before_allocations_micros = Dart_TimelineGetMicros();
+ NativeAllocationSampleHelper(&result);
+
+ // Disable stack allocation stack trace collection to avoid muddying up
+ // results.
+ MallocHooks::set_stack_trace_collection_enabled(false);
+ const int64_t after_allocations_micros = Dart_TimelineGetMicros();
+ const int64_t allocation_extent_micros =
+ after_allocations_micros - before_allocations_micros;
+
+ // Walk the trie and do a sanity check of the allocation values associated
+ // with each node.
+ {
+ Thread* thread = Thread::Current();
+ Isolate* isolate = thread->isolate();
+ StackZone zone(thread);
+ HANDLESCOPE(thread);
+ Profile profile(isolate);
+
+ // Filter for the class in the time range.
+ NativeAllocationSampleFilter filter(before_allocations_micros,
+ allocation_extent_micros);
+ profile.Build(thread, &filter, Profile::kNoTags);
+ // We should have 1 allocation sample.
+ EXPECT_EQ(1, profile.sample_count());
+ ProfileTrieWalker walker(&profile);
+
+ // Exclusive code: NativeAllocationSampleHelper -> main.
+ walker.Reset(Profile::kExclusiveCode);
+ // Move down from the root.
+ EXPECT(walker.Down());
+ EXPECT_SUBSTRING("[Native]", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 1024);
+ EXPECT(walker.Down());
+ EXPECT_STREQ("dart::Dart_TestProfiler_NativeAllocation()",
+ walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(walker.Down());
+ EXPECT_STREQ("dart::TestCase::Run()", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(walker.Down());
+ EXPECT_STREQ("dart::TestCaseBase::RunTest()", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(walker.Down());
+ EXPECT_STREQ("dart::TestCaseBase::RunAll()", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(walker.Down());
+ EXPECT_STREQ("main", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(!walker.Down());
+
+ // Inclusive code: main -> NativeAllocationSampleHelper.
+ walker.Reset(Profile::kInclusiveCode);
+ // Move down from the root.
+ EXPECT(walker.Down());
+ EXPECT_STREQ("main", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(walker.Down());
+ EXPECT_STREQ("dart::TestCaseBase::RunAll()", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(walker.Down());
+ EXPECT_STREQ("dart::TestCaseBase::RunTest()", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(walker.Down());
+ EXPECT_STREQ("dart::TestCase::Run()", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(walker.Down());
+ EXPECT_STREQ("dart::Dart_TestProfiler_NativeAllocation()",
+ walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(walker.Down());
+ EXPECT_SUBSTRING("[Native]", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 1024);
+ EXPECT(!walker.Down());
+
+ // Exclusive function: NativeAllocationSampleHelper -> main.
+ walker.Reset(Profile::kExclusiveFunction);
+ // Move down from the root.
+ EXPECT(walker.Down());
+ EXPECT_SUBSTRING("[Native]", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 1024);
+ EXPECT(walker.Down());
+ EXPECT_STREQ("dart::Dart_TestProfiler_NativeAllocation()",
+ walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(walker.Down());
+ EXPECT_STREQ("dart::TestCase::Run()", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(walker.Down());
+ EXPECT_STREQ("dart::TestCaseBase::RunTest()", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(walker.Down());
+ EXPECT_STREQ("dart::TestCaseBase::RunAll()", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(walker.Down());
+ EXPECT_STREQ("main", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(!walker.Down());
+
+ // Inclusive function: main -> NativeAllocationSampleHelper.
+ walker.Reset(Profile::kInclusiveFunction);
+ // Move down from the root.
+ EXPECT(walker.Down());
+ EXPECT_STREQ("main", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(walker.Down());
+ EXPECT_STREQ("dart::TestCaseBase::RunAll()", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(walker.Down());
+ EXPECT_STREQ("dart::TestCaseBase::RunTest()", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(walker.Down());
+ EXPECT_STREQ("dart::TestCase::Run()", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(walker.Down());
+ EXPECT_STREQ("dart::Dart_TestProfiler_NativeAllocation()",
+ walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 0);
+ EXPECT(walker.Down());
+ EXPECT_SUBSTRING("[Native]", walker.CurrentName());
+ EXPECT_EQ(walker.CurrentInclusiveAllocations(), 1024);
+ EXPECT_EQ(walker.CurrentExclusiveAllocations(), 1024);
+ EXPECT(!walker.Down());
+ }
+
+ MallocHooks::set_stack_trace_collection_enabled(true);
+ free(result);
+ MallocHooks::set_stack_trace_collection_enabled(false);
+
+ // Check to see that the native allocation sample associated with the memory
+ // freed above is marked as free and is no longer reported.
+ {
+ Thread* thread = Thread::Current();
+ Isolate* isolate = thread->isolate();
+ StackZone zone(thread);
+ HANDLESCOPE(thread);
+ Profile profile(isolate);
+
+ // Filter for the class in the time range.
+ NativeAllocationSampleFilter filter(before_allocations_micros,
+ allocation_extent_micros);
+ profile.Build(thread, &filter, Profile::kNoTags);
+ // We should have 0 allocation samples since we freed the memory.
+ EXPECT_EQ(0, profile.sample_count());
+ }
+
+ // Query with a time filter where no allocations occurred.
+ {
+ Thread* thread = Thread::Current();
+ Isolate* isolate = thread->isolate();
+ StackZone zone(thread);
+ HANDLESCOPE(thread);
+ Profile profile(isolate);
+ NativeAllocationSampleFilter filter(Dart_TimelineGetMicros(), 16000);
+ profile.Build(thread, &filter, Profile::kNoTags);
+ // We should have no allocation samples because none occured within
+ // the specified time range.
+ EXPECT_EQ(0, profile.sample_count());
+ }
+
+ MallocHooks::set_stack_trace_collection_enabled(
+ stack_trace_collection_enabled);
+ MallocHooks::TearDown();
+ FLAG_enable_malloc_hooks = enable_malloc_hooks_saved;
+}
+
+
TEST_CASE(Profiler_ToggleRecordAllocation) {
DisableNativeProfileScope dnps;
const char* kScript =
« no previous file with comments | « runtime/vm/profiler_service.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698