summaryrefslogtreecommitdiff
path: root/chromium/base/allocator/partition_allocator/address_pool_manager_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/base/allocator/partition_allocator/address_pool_manager_unittest.cc')
-rw-r--r--chromium/base/allocator/partition_allocator/address_pool_manager_unittest.cc150
1 files changed, 150 insertions, 0 deletions
diff --git a/chromium/base/allocator/partition_allocator/address_pool_manager_unittest.cc b/chromium/base/allocator/partition_allocator/address_pool_manager_unittest.cc
new file mode 100644
index 00000000000..02ca8874ccf
--- /dev/null
+++ b/chromium/base/allocator/partition_allocator/address_pool_manager_unittest.cc
@@ -0,0 +1,150 @@
+// Copyright 2020 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/allocator/partition_allocator/address_pool_manager.h"
+
+#include "base/allocator/partition_allocator/page_allocator.h"
+#include "base/allocator/partition_allocator/page_allocator_internal.h"
+#include "base/allocator/partition_allocator/partition_alloc_constants.h"
+#include "build/build_config.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+namespace internal {
+
+#if defined(ARCH_CPU_64_BITS) && !defined(OS_NACL)
+
+class AddressPoolManagerTest : public testing::Test {
+ protected:
+ AddressPoolManagerTest() = default;
+ ~AddressPoolManagerTest() override = default;
+
+ void SetUp() override {
+ AddressPoolManager::GetInstance()->ResetForTesting();
+ base_address_ =
+ AllocPages(nullptr, kPoolSize, kSuperPageSize, base::PageInaccessible,
+ PageTag::kPartitionAlloc, false);
+ ASSERT_TRUE(base_address_);
+ pool_ = AddressPoolManager::GetInstance()->Add(
+ reinterpret_cast<uintptr_t>(base_address_), kPoolSize);
+ }
+
+ void TearDown() override { FreePages(base_address_, kPoolSize); }
+
+ static constexpr size_t kPageCnt = 8192;
+ static constexpr size_t kPoolSize = kSuperPageSize * kPageCnt;
+
+ void* base_address_;
+ pool_handle pool_;
+};
+
+TEST_F(AddressPoolManagerTest, TooLargePool) {
+ uintptr_t base_addr = 0x4200000;
+
+ constexpr size_t kSize = 16ull * 1024 * 1024 * 1024;
+ EXPECT_DEATH_IF_SUPPORTED(
+ AddressPoolManager::GetInstance()->Add(base_addr, kSize + kSuperPageSize),
+ "");
+}
+
+TEST_F(AddressPoolManagerTest, ManyPages) {
+ char* base_ptr = reinterpret_cast<char*>(base_address_);
+
+ EXPECT_EQ(AddressPoolManager::GetInstance()->Alloc(pool_,
+ kPageCnt * kSuperPageSize),
+ base_ptr);
+ EXPECT_EQ(AddressPoolManager::GetInstance()->Alloc(pool_, kSuperPageSize),
+ nullptr);
+ AddressPoolManager::GetInstance()->Free(pool_, base_ptr,
+ kPageCnt * kSuperPageSize);
+ EXPECT_EQ(AddressPoolManager::GetInstance()->Alloc(pool_,
+ kPageCnt * kSuperPageSize),
+ base_ptr);
+}
+
+TEST_F(AddressPoolManagerTest, PagesFragmented) {
+ char* base_ptr = reinterpret_cast<char*>(base_address_);
+ void* addrs[kPageCnt];
+ for (size_t i = 0; i < kPageCnt; ++i) {
+ addrs[i] = AddressPoolManager::GetInstance()->Alloc(pool_, kSuperPageSize);
+ EXPECT_EQ(addrs[i], base_ptr + i * kSuperPageSize);
+ }
+ EXPECT_EQ(AddressPoolManager::GetInstance()->Alloc(pool_, kSuperPageSize),
+ nullptr);
+ for (size_t i = 1; i < kPageCnt; i += 2) {
+ AddressPoolManager::GetInstance()->Free(pool_, addrs[i], kSuperPageSize);
+ }
+ EXPECT_EQ(AddressPoolManager::GetInstance()->Alloc(pool_, 2 * kSuperPageSize),
+ nullptr);
+ for (size_t i = 1; i < kPageCnt; i += 2) {
+ addrs[i] = AddressPoolManager::GetInstance()->Alloc(pool_, kSuperPageSize);
+ EXPECT_EQ(addrs[i], base_ptr + i * kSuperPageSize);
+ }
+ EXPECT_EQ(AddressPoolManager::GetInstance()->Alloc(pool_, kSuperPageSize),
+ nullptr);
+}
+
+TEST_F(AddressPoolManagerTest, IrregularPattern) {
+ char* base_ptr = reinterpret_cast<char*>(base_address_);
+
+ void* a1 = AddressPoolManager::GetInstance()->Alloc(pool_, kSuperPageSize);
+ EXPECT_EQ(a1, base_ptr);
+ void* a2 =
+ AddressPoolManager::GetInstance()->Alloc(pool_, 2 * kSuperPageSize);
+ EXPECT_EQ(a2, base_ptr + 1 * kSuperPageSize);
+ void* a3 =
+ AddressPoolManager::GetInstance()->Alloc(pool_, 3 * kSuperPageSize);
+ EXPECT_EQ(a3, base_ptr + 3 * kSuperPageSize);
+ void* a4 =
+ AddressPoolManager::GetInstance()->Alloc(pool_, 4 * kSuperPageSize);
+ EXPECT_EQ(a4, base_ptr + 6 * kSuperPageSize);
+ void* a5 =
+ AddressPoolManager::GetInstance()->Alloc(pool_, 5 * kSuperPageSize);
+ EXPECT_EQ(a5, base_ptr + 10 * kSuperPageSize);
+
+ AddressPoolManager::GetInstance()->Free(pool_, a4, 4 * kSuperPageSize);
+ void* a6 =
+ AddressPoolManager::GetInstance()->Alloc(pool_, 6 * kSuperPageSize);
+ EXPECT_EQ(a6, base_ptr + 15 * kSuperPageSize);
+
+ AddressPoolManager::GetInstance()->Free(pool_, a5, 5 * kSuperPageSize);
+ void* a7 =
+ AddressPoolManager::GetInstance()->Alloc(pool_, 7 * kSuperPageSize);
+ EXPECT_EQ(a7, base_ptr + 6 * kSuperPageSize);
+ void* a8 =
+ AddressPoolManager::GetInstance()->Alloc(pool_, 3 * kSuperPageSize);
+ EXPECT_EQ(a8, base_ptr + 21 * kSuperPageSize);
+ void* a9 =
+ AddressPoolManager::GetInstance()->Alloc(pool_, 2 * kSuperPageSize);
+ EXPECT_EQ(a9, base_ptr + 13 * kSuperPageSize);
+
+ AddressPoolManager::GetInstance()->Free(pool_, a7, 7 * kSuperPageSize);
+ AddressPoolManager::GetInstance()->Free(pool_, a9, 2 * kSuperPageSize);
+ AddressPoolManager::GetInstance()->Free(pool_, a6, 6 * kSuperPageSize);
+ void* a10 =
+ AddressPoolManager::GetInstance()->Alloc(pool_, 15 * kSuperPageSize);
+ EXPECT_EQ(a10, base_ptr + 6 * kSuperPageSize);
+}
+
+TEST_F(AddressPoolManagerTest, DecommittedDataIsErased) {
+ void* data = AddressPoolManager::GetInstance()->Alloc(pool_, kSuperPageSize);
+ ASSERT_TRUE(data);
+
+ memset(data, 42, kSuperPageSize);
+ AddressPoolManager::GetInstance()->Free(pool_, data, kSuperPageSize);
+
+ void* data2 = AddressPoolManager::GetInstance()->Alloc(pool_, kSuperPageSize);
+ ASSERT_EQ(data, data2);
+
+ uint32_t sum = 0;
+ for (size_t i = 0; i < kSuperPageSize; i++) {
+ sum += reinterpret_cast<uint8_t*>(data2)[i];
+ }
+
+ EXPECT_EQ(0u, sum) << sum / 42 << " bytes were not zeroed";
+}
+#endif // defined(ARCH_CPU_64_BITS) && !defined(OS_NACL)
+
+} // namespace internal
+} // namespace base