| Index: base/trace_event/memory_profiler_allocation_register_unittest.cc
|
| diff --git a/base/trace_event/memory_profiler_allocation_register_unittest.cc b/base/trace_event/memory_profiler_allocation_register_unittest.cc
|
| deleted file mode 100644
|
| index 0c976c467ccdcb31ca8954896f2ae6d2a954fbbf..0000000000000000000000000000000000000000
|
| --- a/base/trace_event/memory_profiler_allocation_register_unittest.cc
|
| +++ /dev/null
|
| @@ -1,228 +0,0 @@
|
| -// Copyright 2015 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "base/trace_event/memory_profiler_allocation_register.h"
|
| -
|
| -#include "base/process/process_metrics.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -
|
| -namespace base {
|
| -namespace trace_event {
|
| -
|
| -class AllocationRegisterTest : public testing::Test {
|
| - public:
|
| - static const uint32_t kNumBuckets = AllocationRegister::kNumBuckets;
|
| - static const uint32_t kNumCells = AllocationRegister::kNumCells;
|
| -
|
| - // Returns the number of cells that the |AllocationRegister| can store per
|
| - // system page.
|
| - size_t GetNumCellsPerPage() {
|
| - return GetPageSize() / sizeof(AllocationRegister::Cell);
|
| - }
|
| -
|
| - uint32_t GetHighWaterMark(const AllocationRegister& reg) {
|
| - return reg.next_unused_cell_;
|
| - }
|
| -};
|
| -
|
| -// Iterates over all entries in the allocation register and returns the bitwise
|
| -// or of all addresses stored in it.
|
| -uintptr_t OrAllAddresses(const AllocationRegister& reg) {
|
| - uintptr_t acc = 0;
|
| -
|
| - for (auto i : reg)
|
| - acc |= reinterpret_cast<uintptr_t>(i.address);
|
| -
|
| - return acc;
|
| -}
|
| -
|
| -// Iterates over all entries in the allocation register and returns the sum of
|
| -// the sizes of the entries.
|
| -size_t SumAllSizes(const AllocationRegister& reg) {
|
| - size_t sum = 0;
|
| -
|
| - for (auto i : reg)
|
| - sum += i.size;
|
| -
|
| - return sum;
|
| -}
|
| -
|
| -TEST_F(AllocationRegisterTest, InsertRemove) {
|
| - AllocationRegister reg;
|
| - AllocationContext ctx;
|
| -
|
| - EXPECT_EQ(0u, OrAllAddresses(reg));
|
| -
|
| - reg.Insert(reinterpret_cast<void*>(1), 0, ctx);
|
| -
|
| - EXPECT_EQ(1u, OrAllAddresses(reg));
|
| -
|
| - reg.Insert(reinterpret_cast<void*>(2), 0, ctx);
|
| -
|
| - EXPECT_EQ(3u, OrAllAddresses(reg));
|
| -
|
| - reg.Insert(reinterpret_cast<void*>(4), 0, ctx);
|
| -
|
| - EXPECT_EQ(7u, OrAllAddresses(reg));
|
| -
|
| - reg.Remove(reinterpret_cast<void*>(2));
|
| -
|
| - EXPECT_EQ(5u, OrAllAddresses(reg));
|
| -
|
| - reg.Remove(reinterpret_cast<void*>(4));
|
| -
|
| - EXPECT_EQ(1u, OrAllAddresses(reg));
|
| -
|
| - reg.Remove(reinterpret_cast<void*>(1));
|
| -
|
| - EXPECT_EQ(0u, OrAllAddresses(reg));
|
| -}
|
| -
|
| -TEST_F(AllocationRegisterTest, DoubleFreeIsAllowed) {
|
| - AllocationRegister reg;
|
| - AllocationContext ctx;
|
| -
|
| - reg.Insert(reinterpret_cast<void*>(1), 0, ctx);
|
| - reg.Insert(reinterpret_cast<void*>(2), 0, ctx);
|
| - reg.Remove(reinterpret_cast<void*>(1));
|
| - reg.Remove(reinterpret_cast<void*>(1)); // Remove for the second time.
|
| - reg.Remove(reinterpret_cast<void*>(4)); // Remove never inserted address.
|
| -
|
| - EXPECT_EQ(2u, OrAllAddresses(reg));
|
| -}
|
| -
|
| -TEST_F(AllocationRegisterTest, DoubleInsertOverwrites) {
|
| - // TODO(ruuda): Although double insert happens in practice, it should not.
|
| - // Find out the cause and ban double insert if possible.
|
| - AllocationRegister reg;
|
| - AllocationContext ctx;
|
| - StackFrame frame1 = "Foo";
|
| - StackFrame frame2 = "Bar";
|
| -
|
| - ctx.backtrace.frames[0] = frame1;
|
| - reg.Insert(reinterpret_cast<void*>(1), 11, ctx);
|
| -
|
| - auto elem = *reg.begin();
|
| -
|
| - EXPECT_EQ(frame1, elem.context.backtrace.frames[0]);
|
| - EXPECT_EQ(11u, elem.size);
|
| - EXPECT_EQ(reinterpret_cast<void*>(1), elem.address);
|
| -
|
| - ctx.backtrace.frames[0] = frame2;
|
| - reg.Insert(reinterpret_cast<void*>(1), 13, ctx);
|
| -
|
| - elem = *reg.begin();
|
| -
|
| - EXPECT_EQ(frame2, elem.context.backtrace.frames[0]);
|
| - EXPECT_EQ(13u, elem.size);
|
| - EXPECT_EQ(reinterpret_cast<void*>(1), elem.address);
|
| -}
|
| -
|
| -// Check that even if more entries than the number of buckets are inserted, the
|
| -// register still behaves correctly.
|
| -TEST_F(AllocationRegisterTest, InsertRemoveCollisions) {
|
| - size_t expected_sum = 0;
|
| - AllocationRegister reg;
|
| - AllocationContext ctx;
|
| -
|
| - // By inserting 100 more entries than the number of buckets, there will be at
|
| - // least 100 collisions.
|
| - for (uintptr_t i = 1; i <= kNumBuckets + 100; i++) {
|
| - size_t size = i % 31;
|
| - expected_sum += size;
|
| - reg.Insert(reinterpret_cast<void*>(i), size, ctx);
|
| -
|
| - // Don't check the sum on every iteration to keep the test fast.
|
| - if (i % (1 << 14) == 0)
|
| - EXPECT_EQ(expected_sum, SumAllSizes(reg));
|
| - }
|
| -
|
| - EXPECT_EQ(expected_sum, SumAllSizes(reg));
|
| -
|
| - for (uintptr_t i = 1; i <= kNumBuckets + 100; i++) {
|
| - size_t size = i % 31;
|
| - expected_sum -= size;
|
| - reg.Remove(reinterpret_cast<void*>(i));
|
| -
|
| - if (i % (1 << 14) == 0)
|
| - EXPECT_EQ(expected_sum, SumAllSizes(reg));
|
| - }
|
| -
|
| - EXPECT_EQ(expected_sum, SumAllSizes(reg));
|
| -}
|
| -
|
| -// The previous tests are not particularly good for testing iterators, because
|
| -// elements are removed and inserted in the same order, meaning that the cells
|
| -// fill up from low to high index, and are then freed from low to high index.
|
| -// This test removes entries in a different order, to ensure that the iterator
|
| -// skips over the freed cells properly. Then insert again to ensure that the
|
| -// free list is utilised properly.
|
| -TEST_F(AllocationRegisterTest, InsertRemoveRandomOrder) {
|
| - size_t expected_sum = 0;
|
| - AllocationRegister reg;
|
| - AllocationContext ctx;
|
| -
|
| - uintptr_t generator = 3;
|
| - uintptr_t prime = 1013;
|
| - uint32_t initial_water_mark = GetHighWaterMark(reg);
|
| -
|
| - for (uintptr_t i = 2; i < prime; i++) {
|
| - size_t size = i % 31;
|
| - expected_sum += size;
|
| - reg.Insert(reinterpret_cast<void*>(i), size, ctx);
|
| - }
|
| -
|
| - // This should have used a fresh slot for each of the |prime - 2| inserts.
|
| - ASSERT_EQ(prime - 2, GetHighWaterMark(reg) - initial_water_mark);
|
| -
|
| - // Iterate the numbers 2, 3, ..., prime - 1 in pseudorandom order.
|
| - for (uintptr_t i = generator; i != 1; i = (i * generator) % prime) {
|
| - size_t size = i % 31;
|
| - expected_sum -= size;
|
| - reg.Remove(reinterpret_cast<void*>(i));
|
| - EXPECT_EQ(expected_sum, SumAllSizes(reg));
|
| - }
|
| -
|
| - ASSERT_EQ(0u, expected_sum);
|
| -
|
| - // Insert |prime - 2| entries again. This should use cells from the free list,
|
| - // so the |next_unused_cell_| index should not change.
|
| - for (uintptr_t i = 2; i < prime; i++)
|
| - reg.Insert(reinterpret_cast<void*>(i), 0, ctx);
|
| -
|
| - ASSERT_EQ(prime - 2, GetHighWaterMark(reg) - initial_water_mark);
|
| -
|
| - // Inserting one more entry should use a fresh cell again.
|
| - reg.Insert(reinterpret_cast<void*>(prime), 0, ctx);
|
| - ASSERT_EQ(prime - 1, GetHighWaterMark(reg) - initial_water_mark);
|
| -}
|
| -
|
| -// Check that the process aborts due to hitting the guard page when inserting
|
| -// too many elements.
|
| -#if GTEST_HAS_DEATH_TEST
|
| -TEST_F(AllocationRegisterTest, OverflowDeathTest) {
|
| - AllocationRegister reg;
|
| - AllocationContext ctx;
|
| - uintptr_t i;
|
| -
|
| - // Fill up all of the memory allocated for the register. |kNumCells| minus 1
|
| - // elements are inserted, because cell 0 is unused, so this should fill up
|
| - // the available cells exactly.
|
| - for (i = 1; i < kNumCells; i++) {
|
| - reg.Insert(reinterpret_cast<void*>(i), 0, ctx);
|
| - }
|
| -
|
| - // Adding just one extra element might still work because the allocated memory
|
| - // is rounded up to the page size. Adding a page full of elements should cause
|
| - // overflow.
|
| - const size_t cells_per_page = GetNumCellsPerPage();
|
| -
|
| - ASSERT_DEATH(for (size_t j = 0; j < cells_per_page; j++) {
|
| - reg.Insert(reinterpret_cast<void*>(i + j), 0, ctx);
|
| - }, "");
|
| -}
|
| -#endif
|
| -
|
| -} // namespace trace_event
|
| -} // namespace base
|
|
|