Commit a92dc8d7 authored by Bartek Nowierski's avatar Bartek Nowierski Committed by Commit Bot

Implement a hint to aid finding a free chunk

The hint points to a bit in the bitmap before which we know for sure
all bits are 1s, so no need to scan those.

Bug: 1086388
Change-Id: If1ff5dfb7a8faa2fd47937e44bb811af67bda7f2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2230149
Commit-Queue: Bartek Nowierski <bartekn@chromium.org>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#776531}
parent d4b77064
......@@ -7,6 +7,7 @@
#include "base/allocator/partition_allocator/page_allocator.h"
#include "base/allocator/partition_allocator/page_allocator_internal.h"
#include "base/bits.h"
#include "base/notreached.h"
#include "base/stl_util.h"
#include <limits>
......@@ -66,12 +67,11 @@ void AddressPoolManager::Free(pool_handle handle, void* ptr, size_t length) {
AddressPoolManager::Pool::Pool(uintptr_t ptr, size_t length)
: total_bits_(length / kSuperPageSize),
address_begin_(ptr)
address_begin_(ptr),
#if DCHECK_IS_ON()
,
address_end_(ptr + length)
address_end_(ptr + length),
#endif
{
bit_hint_(0) {
CHECK_LE(total_bits_, kMaxBits);
CHECK(!(ptr & kSuperPageOffsetMask));
CHECK(!(length & kSuperPageOffsetMask));
......@@ -88,8 +88,9 @@ uintptr_t AddressPoolManager::Pool::FindChunk(size_t requested_size) {
const size_t need_bits = required_size >> kSuperPageShift;
// Use first fit policy to find an available chunk from free chunks.
size_t beg_bit = 0;
size_t curr_bit = 0;
// Start from |bit_hint_|, because we know there is no free chunks before.
size_t beg_bit = bit_hint_;
size_t curr_bit = bit_hint_;
while (true) {
// |end_bit| points 1 past the last bit that needs to be 0. If it goes past
// |total_bits_|, return |nullptr| to signal no free chunk was found.
......@@ -107,6 +108,8 @@ uintptr_t AddressPoolManager::Pool::FindChunk(size_t requested_size) {
// next outer loop pass from checking the same bits.
beg_bit = curr_bit + 1;
found = false;
if (bit_hint_ == curr_bit)
++bit_hint_;
}
}
......@@ -117,6 +120,9 @@ uintptr_t AddressPoolManager::Pool::FindChunk(size_t requested_size) {
DCHECK(!alloc_bitset_.test(i));
alloc_bitset_.set(i);
}
if (bit_hint_ == beg_bit) {
bit_hint_ = end_bit;
}
uintptr_t address = address_begin_ + beg_bit * kSuperPageSize;
#if DCHECK_IS_ON()
DCHECK_LE(address + required_size, address_end_);
......@@ -125,6 +131,7 @@ uintptr_t AddressPoolManager::Pool::FindChunk(size_t requested_size) {
}
}
NOTREACHED();
return 0;
}
......@@ -145,6 +152,7 @@ void AddressPoolManager::Pool::FreeChunk(uintptr_t address, size_t free_size) {
DCHECK(alloc_bitset_.test(i));
alloc_bitset_.reset(i);
}
bit_hint_ = std::min(bit_hint_, beg_bit);
}
AddressPoolManager::Pool::~Pool() = default;
......
......@@ -69,6 +69,12 @@ class BASE_EXPORT AddressPoolManager {
const uintptr_t address_end_;
#endif
// A number of a bit before which we know for sure there all 1s. This is
// a best effort hint in the sense that there still may be lots of 1s after
// this bit, but at least we know there is no point in starting the search
// before it.
size_t bit_hint_;
DISALLOW_COPY_AND_ASSIGN(Pool);
};
......
......@@ -78,6 +78,8 @@ TEST(AddressPoolManager, PagesFragmented) {
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);
}
......@@ -87,6 +89,8 @@ TEST(AddressPoolManager, PagesFragmented) {
addrs[i] = AddressPoolManager::GetInstance()->Alloc(pool, kSuperPageSize);
EXPECT_EQ(addrs[i], base_ptr + i * kSuperPageSize);
}
EXPECT_EQ(AddressPoolManager::GetInstance()->Alloc(pool, kSuperPageSize),
nullptr);
}
TEST(AddressPoolManager, IrregularPattern) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment