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

Unified Diff: runtime/vm/profiler_test.cc

Issue 2771293003: Resubmission of native memory allocation info surfacing in Observatory. Fixed crashing tests and st… (Closed)
Patch Set: Added page to Observatory to display native memory allocation information. 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') | runtime/vm/vm_sources.gypi » ('j') | 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..ccada84dc3b8c8812b8727ed8832a4cabac97a60 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -316,6 +316,217 @@ TEST_CASE(Profiler_TrivialRecordAllocation) {
}
}
+#if defined(DART_USE_TCMALLOC) && defined(HOST_OS_LINUX) && defined(DEBUG) && \
+ defined(HOST_ARCH_x64)
+
+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;
+}
+#endif // defined(DART_USE_TCMALLOC) && !defined(PRODUCT) &&
+ // !defined(TARGET_ARCH_DBC) && !defined(HOST_OS_FUCHSIA)
+
TEST_CASE(Profiler_ToggleRecordAllocation) {
DisableNativeProfileScope dnps;
« no previous file with comments | « runtime/vm/profiler_service.cc ('k') | runtime/vm/vm_sources.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698