123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- // 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.
- #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_ADDRESS_POOL_MANAGER_H_
- #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_ADDRESS_POOL_MANAGER_H_
- #include <bitset>
- #include <limits>
- #include "base/allocator/partition_allocator/address_pool_manager_bitmap.h"
- #include "base/allocator/partition_allocator/address_pool_manager_types.h"
- #include "base/allocator/partition_allocator/partition_address_space.h"
- #include "base/allocator/partition_allocator/partition_alloc_base/compiler_specific.h"
- #include "base/allocator/partition_allocator/partition_alloc_base/component_export.h"
- #include "base/allocator/partition_allocator/partition_alloc_base/debug/debugging_buildflags.h"
- #include "base/allocator/partition_allocator/partition_alloc_base/thread_annotations.h"
- #include "base/allocator/partition_allocator/partition_alloc_check.h"
- #include "base/allocator/partition_allocator/partition_alloc_config.h"
- #include "base/allocator/partition_allocator/partition_alloc_constants.h"
- #include "base/allocator/partition_allocator/partition_lock.h"
- #include "build/build_config.h"
- namespace partition_alloc {
- class AddressSpaceStatsDumper;
- struct AddressSpaceStats;
- struct PoolStats;
- } // namespace partition_alloc
- namespace partition_alloc::internal {
- // (64bit version)
- // AddressPoolManager takes a reserved virtual address space and manages address
- // space allocation.
- //
- // AddressPoolManager (currently) supports up to 3 pools. Each pool manages a
- // contiguous reserved address space. Alloc() takes a pool_handle and returns
- // address regions from the specified pool. Free() also takes a pool_handle and
- // returns the address region back to the manager.
- //
- // (32bit version)
- // AddressPoolManager wraps AllocPages and FreePages and remembers allocated
- // address regions using bitmaps. IsManagedByPartitionAllocBRPPool and
- // IsManagedByPartitionAllocRegularPool use the bitmaps to judge whether a given
- // address is in a pool that supports BackupRefPtr or in a pool that doesn't.
- // All PartitionAlloc allocations must be in either of the pools.
- class PA_COMPONENT_EXPORT(PARTITION_ALLOC) AddressPoolManager {
- public:
- static AddressPoolManager& GetInstance();
- AddressPoolManager(const AddressPoolManager&) = delete;
- AddressPoolManager& operator=(const AddressPoolManager&) = delete;
- #if defined(PA_HAS_64_BITS_POINTERS)
- pool_handle Add(uintptr_t address, size_t length);
- void Remove(pool_handle handle);
- // Populate a |used| bitset of superpages currently in use.
- void GetPoolUsedSuperPages(pool_handle handle,
- std::bitset<kMaxSuperPagesInPool>& used);
- // Return the base address of a pool.
- uintptr_t GetPoolBaseAddress(pool_handle handle);
- #endif
- // Reserves address space from GigaCage.
- uintptr_t Reserve(pool_handle handle,
- uintptr_t requested_address,
- size_t length);
- // Frees address space back to GigaCage and decommits underlying system pages.
- void UnreserveAndDecommit(pool_handle handle,
- uintptr_t address,
- size_t length);
- void ResetForTesting();
- #if !defined(PA_HAS_64_BITS_POINTERS)
- void MarkUsed(pool_handle handle, uintptr_t address, size_t size);
- void MarkUnused(pool_handle handle, uintptr_t address, size_t size);
- static bool IsManagedByRegularPool(uintptr_t address) {
- return AddressPoolManagerBitmap::IsManagedByRegularPool(address);
- }
- static bool IsManagedByBRPPool(uintptr_t address) {
- return AddressPoolManagerBitmap::IsManagedByBRPPool(address);
- }
- #endif // !defined(PA_HAS_64_BITS_POINTERS)
- void DumpStats(AddressSpaceStatsDumper* dumper);
- private:
- friend class AddressPoolManagerForTesting;
- constexpr AddressPoolManager() = default;
- ~AddressPoolManager() = default;
- // Populates `stats` if applicable.
- // Returns whether `stats` was populated. (They might not be, e.g.
- // if PartitionAlloc is wholly unused in this process.)
- bool GetStats(AddressSpaceStats* stats);
- #if defined(PA_HAS_64_BITS_POINTERS)
- class Pool {
- public:
- constexpr Pool() = default;
- ~Pool() = default;
- Pool(const Pool&) = delete;
- Pool& operator=(const Pool&) = delete;
- void Initialize(uintptr_t ptr, size_t length);
- bool IsInitialized();
- void Reset();
- uintptr_t FindChunk(size_t size);
- void FreeChunk(uintptr_t address, size_t size);
- bool TryReserveChunk(uintptr_t address, size_t size);
- void GetUsedSuperPages(std::bitset<kMaxSuperPagesInPool>& used);
- uintptr_t GetBaseAddress();
- void GetStats(PoolStats* stats);
- private:
- Lock lock_;
- // The bitset stores the allocation state of the address pool. 1 bit per
- // super-page: 1 = allocated, 0 = free.
- std::bitset<kMaxSuperPagesInPool> alloc_bitset_ PA_GUARDED_BY(lock_);
- // An index of a bit in the bitset 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 index, but at least we know there is no point in
- // starting the search before it.
- size_t bit_hint_ PA_GUARDED_BY(lock_) = 0;
- size_t total_bits_ = 0;
- uintptr_t address_begin_ = 0;
- #if BUILDFLAG(PA_DCHECK_IS_ON)
- uintptr_t address_end_ = 0;
- #endif
- };
- PA_ALWAYS_INLINE Pool* GetPool(pool_handle handle) {
- PA_DCHECK(0 < handle && handle <= kNumPools);
- return &pools_[handle - 1];
- }
- // Gets the stats for the pool identified by `handle`, if
- // initialized.
- void GetPoolStats(pool_handle handle, PoolStats* stats);
- Pool pools_[kNumPools];
- #endif // defined(PA_HAS_64_BITS_POINTERS)
- static AddressPoolManager singleton_;
- };
- PA_ALWAYS_INLINE pool_handle GetRegularPool() {
- return kRegularPoolHandle;
- }
- PA_ALWAYS_INLINE pool_handle GetBRPPool() {
- return kBRPPoolHandle;
- }
- PA_ALWAYS_INLINE pool_handle GetConfigurablePool() {
- PA_DCHECK(IsConfigurablePoolAvailable());
- return kConfigurablePoolHandle;
- }
- } // namespace partition_alloc::internal
- #endif // BASE_ALLOCATOR_PARTITION_ALLOCATOR_ADDRESS_POOL_MANAGER_H_
|