Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/trace_event/process_memory_dump.h" | 5 #include "base/trace_event/process_memory_dump.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/memory/aligned_memory.h" | 9 #include "base/memory/aligned_memory.h" |
| 10 #include "base/process/process_metrics.h" | 10 #include "base/process/process_metrics.h" |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 | 23 |
| 24 pmd1->process_totals()->set_resident_set_bytes(42); | 24 pmd1->process_totals()->set_resident_set_bytes(42); |
| 25 pmd1->set_has_process_totals(); | 25 pmd1->set_has_process_totals(); |
| 26 | 26 |
| 27 pmd1->process_mmaps()->AddVMRegion(ProcessMemoryMaps::VMRegion()); | 27 pmd1->process_mmaps()->AddVMRegion(ProcessMemoryMaps::VMRegion()); |
| 28 pmd1->set_has_process_mmaps(); | 28 pmd1->set_has_process_mmaps(); |
| 29 | 29 |
| 30 pmd1->AddOwnershipEdge(MemoryAllocatorDumpGuid(42), | 30 pmd1->AddOwnershipEdge(MemoryAllocatorDumpGuid(42), |
| 31 MemoryAllocatorDumpGuid(4242)); | 31 MemoryAllocatorDumpGuid(4242)); |
| 32 | 32 |
| 33 MemoryAllocatorDumpGuid shared_mad_guid(1); | 33 MemoryAllocatorDumpGuid shared_mad_guid1(1); |
| 34 pmd1->CreateSharedGlobalAllocatorDump(shared_mad_guid); | 34 MemoryAllocatorDumpGuid shared_mad_guid2(2); |
| 35 pmd1->CreateSharedGlobalAllocatorDump(shared_mad_guid1); | |
| 36 pmd1->CreateSharedGlobalAllocatorDump(shared_mad_guid2); | |
| 35 | 37 |
| 36 pmd1->Clear(); | 38 pmd1->Clear(); |
| 37 ASSERT_TRUE(pmd1->allocator_dumps().empty()); | 39 ASSERT_TRUE(pmd1->allocator_dumps().empty()); |
| 38 ASSERT_TRUE(pmd1->allocator_dumps_edges().empty()); | 40 ASSERT_TRUE(pmd1->allocator_dumps_edges().empty()); |
| 39 ASSERT_EQ(nullptr, pmd1->GetAllocatorDump("mad1")); | 41 ASSERT_EQ(nullptr, pmd1->GetAllocatorDump("mad1")); |
| 40 ASSERT_EQ(nullptr, pmd1->GetAllocatorDump("mad2")); | 42 ASSERT_EQ(nullptr, pmd1->GetAllocatorDump("mad2")); |
| 41 ASSERT_FALSE(pmd1->has_process_totals()); | 43 ASSERT_FALSE(pmd1->has_process_totals()); |
| 42 ASSERT_FALSE(pmd1->has_process_mmaps()); | 44 ASSERT_FALSE(pmd1->has_process_mmaps()); |
| 43 ASSERT_TRUE(pmd1->process_mmaps()->vm_regions().empty()); | 45 ASSERT_TRUE(pmd1->process_mmaps()->vm_regions().empty()); |
| 44 ASSERT_EQ(nullptr, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid)); | 46 ASSERT_EQ(nullptr, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid1)); |
| 47 ASSERT_EQ(nullptr, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid2)); | |
| 45 | 48 |
| 46 // Check that calling AsValueInto() doesn't cause a crash. | 49 // Check that calling AsValueInto() doesn't cause a crash. |
| 47 scoped_refptr<TracedValue> traced_value(new TracedValue()); | 50 scoped_refptr<TracedValue> traced_value(new TracedValue()); |
| 48 pmd1->AsValueInto(traced_value.get()); | 51 pmd1->AsValueInto(traced_value.get()); |
| 49 | 52 |
| 50 // Check that the pmd can be reused and behaves as expected. | 53 // Check that the pmd can be reused and behaves as expected. |
| 51 auto mad1 = pmd1->CreateAllocatorDump("mad1"); | 54 auto mad1 = pmd1->CreateAllocatorDump("mad1"); |
| 52 auto mad3 = pmd1->CreateAllocatorDump("mad3"); | 55 auto mad3 = pmd1->CreateAllocatorDump("mad3"); |
| 53 auto shared_mad = pmd1->CreateSharedGlobalAllocatorDump(shared_mad_guid); | 56 auto shared_mad1 = pmd1->CreateSharedGlobalAllocatorDump(shared_mad_guid1); |
| 54 ASSERT_EQ(3u, pmd1->allocator_dumps().size()); | 57 auto shared_mad2 = |
| 58 pmd1->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid2); | |
| 59 ASSERT_EQ(4u, pmd1->allocator_dumps().size()); | |
| 55 ASSERT_EQ(mad1, pmd1->GetAllocatorDump("mad1")); | 60 ASSERT_EQ(mad1, pmd1->GetAllocatorDump("mad1")); |
| 56 ASSERT_EQ(nullptr, pmd1->GetAllocatorDump("mad2")); | 61 ASSERT_EQ(nullptr, pmd1->GetAllocatorDump("mad2")); |
| 57 ASSERT_EQ(mad3, pmd1->GetAllocatorDump("mad3")); | 62 ASSERT_EQ(mad3, pmd1->GetAllocatorDump("mad3")); |
| 58 ASSERT_EQ(shared_mad, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid)); | 63 ASSERT_EQ(shared_mad1, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid1)); |
| 64 ASSERT_EQ(0u /* non-weak */, shared_mad1->flags()); | |
|
Primiano Tucci (use gerrit)
2016/01/19 17:07:11
maybe you could have a Flags::DEFAULT = 0 in the e
ssid
2016/01/20 18:58:34
Done.
| |
| 65 ASSERT_EQ(shared_mad2, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid2)); | |
| 66 ASSERT_EQ(MemoryAllocatorDump::Flag::WEAK, shared_mad2->flags()); | |
| 59 | 67 |
| 60 traced_value = new TracedValue(); | 68 traced_value = new TracedValue(); |
| 61 pmd1->AsValueInto(traced_value.get()); | 69 pmd1->AsValueInto(traced_value.get()); |
| 62 | 70 |
| 63 pmd1.reset(); | 71 pmd1.reset(); |
| 64 } | 72 } |
| 65 | 73 |
| 66 TEST(ProcessMemoryDumpTest, TakeAllDumpsFrom) { | 74 TEST(ProcessMemoryDumpTest, TakeAllDumpsFrom) { |
| 67 scoped_refptr<TracedValue> traced_value(new TracedValue()); | 75 scoped_refptr<TracedValue> traced_value(new TracedValue()); |
| 68 | 76 |
| 69 scoped_ptr<ProcessMemoryDump> pmd1(new ProcessMemoryDump(nullptr)); | 77 scoped_ptr<ProcessMemoryDump> pmd1(new ProcessMemoryDump(nullptr)); |
| 70 auto mad1_1 = pmd1->CreateAllocatorDump("pmd1/mad1"); | 78 auto mad1_1 = pmd1->CreateAllocatorDump("pmd1/mad1"); |
| 71 auto mad1_2 = pmd1->CreateAllocatorDump("pmd1/mad2"); | 79 auto mad1_2 = pmd1->CreateAllocatorDump("pmd1/mad2"); |
| 72 pmd1->AddOwnershipEdge(mad1_1->guid(), mad1_2->guid()); | 80 pmd1->AddOwnershipEdge(mad1_1->guid(), mad1_2->guid()); |
| 73 | 81 |
| 74 scoped_ptr<ProcessMemoryDump> pmd2(new ProcessMemoryDump(nullptr)); | 82 scoped_ptr<ProcessMemoryDump> pmd2(new ProcessMemoryDump(nullptr)); |
| 75 auto mad2_1 = pmd2->CreateAllocatorDump("pmd2/mad1"); | 83 auto mad2_1 = pmd2->CreateAllocatorDump("pmd2/mad1"); |
| 76 auto mad2_2 = pmd2->CreateAllocatorDump("pmd2/mad2"); | 84 auto mad2_2 = pmd2->CreateAllocatorDump("pmd2/mad2"); |
| 77 pmd1->AddOwnershipEdge(mad2_1->guid(), mad2_2->guid()); | 85 pmd1->AddOwnershipEdge(mad2_1->guid(), mad2_2->guid()); |
| 78 | 86 |
| 79 MemoryAllocatorDumpGuid shared_mad_guid(1); | 87 MemoryAllocatorDumpGuid shared_mad_guid1(1); |
| 80 auto shared_mad = pmd2->CreateSharedGlobalAllocatorDump(shared_mad_guid); | 88 MemoryAllocatorDumpGuid shared_mad_guid2(2); |
| 89 auto shared_mad1 = pmd2->CreateSharedGlobalAllocatorDump(shared_mad_guid1); | |
| 90 auto shared_mad2 = | |
| 91 pmd2->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid2); | |
| 81 | 92 |
| 82 pmd1->TakeAllDumpsFrom(pmd2.get()); | 93 pmd1->TakeAllDumpsFrom(pmd2.get()); |
| 83 | 94 |
| 84 // Make sure that pmd2 is empty but still usable after it has been emptied. | 95 // Make sure that pmd2 is empty but still usable after it has been emptied. |
| 85 ASSERT_TRUE(pmd2->allocator_dumps().empty()); | 96 ASSERT_TRUE(pmd2->allocator_dumps().empty()); |
| 86 ASSERT_TRUE(pmd2->allocator_dumps_edges().empty()); | 97 ASSERT_TRUE(pmd2->allocator_dumps_edges().empty()); |
| 87 pmd2->CreateAllocatorDump("pmd2/this_mad_stays_with_pmd2"); | 98 pmd2->CreateAllocatorDump("pmd2/this_mad_stays_with_pmd2"); |
| 88 ASSERT_EQ(1u, pmd2->allocator_dumps().size()); | 99 ASSERT_EQ(1u, pmd2->allocator_dumps().size()); |
| 89 ASSERT_EQ(1u, pmd2->allocator_dumps().count("pmd2/this_mad_stays_with_pmd2")); | 100 ASSERT_EQ(1u, pmd2->allocator_dumps().count("pmd2/this_mad_stays_with_pmd2")); |
| 90 pmd2->AddOwnershipEdge(MemoryAllocatorDumpGuid(42), | 101 pmd2->AddOwnershipEdge(MemoryAllocatorDumpGuid(42), |
| 91 MemoryAllocatorDumpGuid(4242)); | 102 MemoryAllocatorDumpGuid(4242)); |
| 92 | 103 |
| 93 // Check that calling AsValueInto() doesn't cause a crash. | 104 // Check that calling AsValueInto() doesn't cause a crash. |
| 94 pmd2->AsValueInto(traced_value.get()); | 105 pmd2->AsValueInto(traced_value.get()); |
| 95 | 106 |
| 96 // Free the |pmd2| to check that the memory ownership of the two MAD(s) | 107 // Free the |pmd2| to check that the memory ownership of the two MAD(s) |
| 97 // has been transferred to |pmd1|. | 108 // has been transferred to |pmd1|. |
| 98 pmd2.reset(); | 109 pmd2.reset(); |
| 99 | 110 |
| 100 // Now check that |pmd1| has been effectively merged. | 111 // Now check that |pmd1| has been effectively merged. |
| 101 ASSERT_EQ(5u, pmd1->allocator_dumps().size()); | 112 ASSERT_EQ(6u, pmd1->allocator_dumps().size()); |
| 102 ASSERT_EQ(1u, pmd1->allocator_dumps().count("pmd1/mad1")); | 113 ASSERT_EQ(1u, pmd1->allocator_dumps().count("pmd1/mad1")); |
| 103 ASSERT_EQ(1u, pmd1->allocator_dumps().count("pmd1/mad2")); | 114 ASSERT_EQ(1u, pmd1->allocator_dumps().count("pmd1/mad2")); |
| 104 ASSERT_EQ(1u, pmd1->allocator_dumps().count("pmd2/mad1")); | 115 ASSERT_EQ(1u, pmd1->allocator_dumps().count("pmd2/mad1")); |
| 105 ASSERT_EQ(1u, pmd1->allocator_dumps().count("pmd1/mad2")); | 116 ASSERT_EQ(1u, pmd1->allocator_dumps().count("pmd1/mad2")); |
| 106 ASSERT_EQ(2u, pmd1->allocator_dumps_edges().size()); | 117 ASSERT_EQ(2u, pmd1->allocator_dumps_edges().size()); |
| 107 ASSERT_EQ(shared_mad, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid)); | 118 ASSERT_EQ(shared_mad1, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid1)); |
| 119 ASSERT_EQ(shared_mad2, pmd1->GetSharedGlobalAllocatorDump(shared_mad_guid2)); | |
| 120 ASSERT_TRUE(MemoryAllocatorDump::Flag::WEAK & shared_mad2->flags()); | |
| 108 | 121 |
| 109 // Check that calling AsValueInto() doesn't cause a crash. | 122 // Check that calling AsValueInto() doesn't cause a crash. |
| 110 traced_value = new TracedValue(); | 123 traced_value = new TracedValue(); |
| 111 pmd1->AsValueInto(traced_value.get()); | 124 pmd1->AsValueInto(traced_value.get()); |
| 112 | 125 |
| 113 pmd1.reset(); | 126 pmd1.reset(); |
| 114 } | 127 } |
| 115 | 128 |
| 116 TEST(ProcessMemoryDumpTest, Suballocations) { | 129 TEST(ProcessMemoryDumpTest, Suballocations) { |
| 117 scoped_ptr<ProcessMemoryDump> pmd(new ProcessMemoryDump(nullptr)); | 130 scoped_ptr<ProcessMemoryDump> pmd(new ProcessMemoryDump(nullptr)); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 150 ASSERT_TRUE(found_edge[0]); | 163 ASSERT_TRUE(found_edge[0]); |
| 151 ASSERT_TRUE(found_edge[1]); | 164 ASSERT_TRUE(found_edge[1]); |
| 152 | 165 |
| 153 // Check that calling AsValueInto() doesn't cause a crash. | 166 // Check that calling AsValueInto() doesn't cause a crash. |
| 154 scoped_refptr<TracedValue> traced_value(new TracedValue()); | 167 scoped_refptr<TracedValue> traced_value(new TracedValue()); |
| 155 pmd->AsValueInto(traced_value.get()); | 168 pmd->AsValueInto(traced_value.get()); |
| 156 | 169 |
| 157 pmd.reset(); | 170 pmd.reset(); |
| 158 } | 171 } |
| 159 | 172 |
| 173 TEST(ProcessMemoryDumpTest, CreateGlobalDumpTest) { | |
|
Primiano Tucci (use gerrit)
2016/01/19 17:07:11
s/CreateGlobalDUmpTest/GlobalAllocatorDumpTest/
ssid
2016/01/20 18:58:34
Done.
| |
| 174 scoped_ptr<ProcessMemoryDump> pmd(new ProcessMemoryDump(nullptr)); | |
| 175 MemoryAllocatorDumpGuid shared_mad_guid(1); | |
| 176 auto shared_mad1 = pmd->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid); | |
| 177 ASSERT_EQ(shared_mad_guid, shared_mad1->guid()); | |
| 178 ASSERT_EQ(MemoryAllocatorDump::Flag::WEAK, shared_mad1->flags()); | |
| 179 | |
| 180 auto shared_mad2 = pmd->GetSharedGlobalAllocatorDump(shared_mad_guid); | |
| 181 ASSERT_EQ(shared_mad1, shared_mad2); | |
| 182 ASSERT_EQ(MemoryAllocatorDump::Flag::WEAK, shared_mad1->flags()); | |
| 183 | |
| 184 auto shared_mad3 = pmd->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid); | |
| 185 ASSERT_EQ(shared_mad1, shared_mad3); | |
| 186 ASSERT_EQ(MemoryAllocatorDump::Flag::WEAK, shared_mad1->flags()); | |
| 187 | |
| 188 auto shared_mad4 = pmd->CreateSharedGlobalAllocatorDump(shared_mad_guid); | |
| 189 ASSERT_EQ(shared_mad1, shared_mad4); | |
| 190 ASSERT_EQ(0 /* non-weak */, shared_mad1->flags()); | |
| 191 | |
| 192 auto shared_mad5 = pmd->CreateWeakSharedGlobalAllocatorDump(shared_mad_guid); | |
| 193 ASSERT_EQ(shared_mad1, shared_mad5); | |
| 194 ASSERT_EQ(0 /* non-weak */, shared_mad1->flags()); | |
| 195 } | |
| 196 | |
| 160 #if defined(COUNT_RESIDENT_BYTES_SUPPORTED) | 197 #if defined(COUNT_RESIDENT_BYTES_SUPPORTED) |
| 161 TEST(ProcessMemoryDumpTest, CountResidentBytes) { | 198 TEST(ProcessMemoryDumpTest, CountResidentBytes) { |
| 162 const size_t page_size = base::GetPageSize(); | 199 const size_t page_size = base::GetPageSize(); |
| 163 | 200 |
| 164 // Allocate few page of dirty memory and check if it is resident. | 201 // Allocate few page of dirty memory and check if it is resident. |
| 165 const size_t size1 = 5 * page_size; | 202 const size_t size1 = 5 * page_size; |
| 166 scoped_ptr<char, base::AlignedFreeDeleter> memory1( | 203 scoped_ptr<char, base::AlignedFreeDeleter> memory1( |
| 167 static_cast<char*>(base::AlignedAlloc(size1, page_size))); | 204 static_cast<char*>(base::AlignedAlloc(size1, page_size))); |
| 168 memset(memory1.get(), 0, size1); | 205 memset(memory1.get(), 0, size1); |
| 169 size_t res1 = ProcessMemoryDump::CountResidentBytes(memory1.get(), size1); | 206 size_t res1 = ProcessMemoryDump::CountResidentBytes(memory1.get(), size1); |
| 170 ASSERT_EQ(res1, size1); | 207 ASSERT_EQ(res1, size1); |
| 171 | 208 |
| 172 // Allocate a large memory segment (>32Mib). | 209 // Allocate a large memory segment (>32Mib). |
| 173 const size_t kVeryLargeMemorySize = 34 * 1024 * 1024; | 210 const size_t kVeryLargeMemorySize = 34 * 1024 * 1024; |
| 174 scoped_ptr<char, base::AlignedFreeDeleter> memory2( | 211 scoped_ptr<char, base::AlignedFreeDeleter> memory2( |
| 175 static_cast<char*>(base::AlignedAlloc(kVeryLargeMemorySize, page_size))); | 212 static_cast<char*>(base::AlignedAlloc(kVeryLargeMemorySize, page_size))); |
| 176 memset(memory2.get(), 0, kVeryLargeMemorySize); | 213 memset(memory2.get(), 0, kVeryLargeMemorySize); |
| 177 size_t res2 = ProcessMemoryDump::CountResidentBytes(memory2.get(), | 214 size_t res2 = ProcessMemoryDump::CountResidentBytes(memory2.get(), |
| 178 kVeryLargeMemorySize); | 215 kVeryLargeMemorySize); |
| 179 ASSERT_EQ(res2, kVeryLargeMemorySize); | 216 ASSERT_EQ(res2, kVeryLargeMemorySize); |
| 180 } | 217 } |
| 181 #endif // defined(COUNT_RESIDENT_BYTES_SUPPORTED) | 218 #endif // defined(COUNT_RESIDENT_BYTES_SUPPORTED) |
| 182 | 219 |
| 183 } // namespace trace_event | 220 } // namespace trace_event |
| 184 } // namespace base | 221 } // namespace base |
| OLD | NEW |