address_pool_manager.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_ADDRESS_POOL_MANAGER_H_
  5. #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_ADDRESS_POOL_MANAGER_H_
  6. #include <bitset>
  7. #include <limits>
  8. #include "base/allocator/partition_allocator/address_pool_manager_bitmap.h"
  9. #include "base/allocator/partition_allocator/address_pool_manager_types.h"
  10. #include "base/allocator/partition_allocator/partition_address_space.h"
  11. #include "base/allocator/partition_allocator/partition_alloc_base/compiler_specific.h"
  12. #include "base/allocator/partition_allocator/partition_alloc_base/component_export.h"
  13. #include "base/allocator/partition_allocator/partition_alloc_base/debug/debugging_buildflags.h"
  14. #include "base/allocator/partition_allocator/partition_alloc_base/thread_annotations.h"
  15. #include "base/allocator/partition_allocator/partition_alloc_check.h"
  16. #include "base/allocator/partition_allocator/partition_alloc_config.h"
  17. #include "base/allocator/partition_allocator/partition_alloc_constants.h"
  18. #include "base/allocator/partition_allocator/partition_lock.h"
  19. #include "build/build_config.h"
  20. namespace partition_alloc {
  21. class AddressSpaceStatsDumper;
  22. struct AddressSpaceStats;
  23. struct PoolStats;
  24. } // namespace partition_alloc
  25. namespace partition_alloc::internal {
  26. // (64bit version)
  27. // AddressPoolManager takes a reserved virtual address space and manages address
  28. // space allocation.
  29. //
  30. // AddressPoolManager (currently) supports up to 3 pools. Each pool manages a
  31. // contiguous reserved address space. Alloc() takes a pool_handle and returns
  32. // address regions from the specified pool. Free() also takes a pool_handle and
  33. // returns the address region back to the manager.
  34. //
  35. // (32bit version)
  36. // AddressPoolManager wraps AllocPages and FreePages and remembers allocated
  37. // address regions using bitmaps. IsManagedByPartitionAllocBRPPool and
  38. // IsManagedByPartitionAllocRegularPool use the bitmaps to judge whether a given
  39. // address is in a pool that supports BackupRefPtr or in a pool that doesn't.
  40. // All PartitionAlloc allocations must be in either of the pools.
  41. class PA_COMPONENT_EXPORT(PARTITION_ALLOC) AddressPoolManager {
  42. public:
  43. static AddressPoolManager& GetInstance();
  44. AddressPoolManager(const AddressPoolManager&) = delete;
  45. AddressPoolManager& operator=(const AddressPoolManager&) = delete;
  46. #if defined(PA_HAS_64_BITS_POINTERS)
  47. pool_handle Add(uintptr_t address, size_t length);
  48. void Remove(pool_handle handle);
  49. // Populate a |used| bitset of superpages currently in use.
  50. void GetPoolUsedSuperPages(pool_handle handle,
  51. std::bitset<kMaxSuperPagesInPool>& used);
  52. // Return the base address of a pool.
  53. uintptr_t GetPoolBaseAddress(pool_handle handle);
  54. #endif
  55. // Reserves address space from GigaCage.
  56. uintptr_t Reserve(pool_handle handle,
  57. uintptr_t requested_address,
  58. size_t length);
  59. // Frees address space back to GigaCage and decommits underlying system pages.
  60. void UnreserveAndDecommit(pool_handle handle,
  61. uintptr_t address,
  62. size_t length);
  63. void ResetForTesting();
  64. #if !defined(PA_HAS_64_BITS_POINTERS)
  65. void MarkUsed(pool_handle handle, uintptr_t address, size_t size);
  66. void MarkUnused(pool_handle handle, uintptr_t address, size_t size);
  67. static bool IsManagedByRegularPool(uintptr_t address) {
  68. return AddressPoolManagerBitmap::IsManagedByRegularPool(address);
  69. }
  70. static bool IsManagedByBRPPool(uintptr_t address) {
  71. return AddressPoolManagerBitmap::IsManagedByBRPPool(address);
  72. }
  73. #endif // !defined(PA_HAS_64_BITS_POINTERS)
  74. void DumpStats(AddressSpaceStatsDumper* dumper);
  75. private:
  76. friend class AddressPoolManagerForTesting;
  77. constexpr AddressPoolManager() = default;
  78. ~AddressPoolManager() = default;
  79. // Populates `stats` if applicable.
  80. // Returns whether `stats` was populated. (They might not be, e.g.
  81. // if PartitionAlloc is wholly unused in this process.)
  82. bool GetStats(AddressSpaceStats* stats);
  83. #if defined(PA_HAS_64_BITS_POINTERS)
  84. class Pool {
  85. public:
  86. constexpr Pool() = default;
  87. ~Pool() = default;
  88. Pool(const Pool&) = delete;
  89. Pool& operator=(const Pool&) = delete;
  90. void Initialize(uintptr_t ptr, size_t length);
  91. bool IsInitialized();
  92. void Reset();
  93. uintptr_t FindChunk(size_t size);
  94. void FreeChunk(uintptr_t address, size_t size);
  95. bool TryReserveChunk(uintptr_t address, size_t size);
  96. void GetUsedSuperPages(std::bitset<kMaxSuperPagesInPool>& used);
  97. uintptr_t GetBaseAddress();
  98. void GetStats(PoolStats* stats);
  99. private:
  100. Lock lock_;
  101. // The bitset stores the allocation state of the address pool. 1 bit per
  102. // super-page: 1 = allocated, 0 = free.
  103. std::bitset<kMaxSuperPagesInPool> alloc_bitset_ PA_GUARDED_BY(lock_);
  104. // An index of a bit in the bitset before which we know for sure there all
  105. // 1s. This is a best-effort hint in the sense that there still may be lots
  106. // of 1s after this index, but at least we know there is no point in
  107. // starting the search before it.
  108. size_t bit_hint_ PA_GUARDED_BY(lock_) = 0;
  109. size_t total_bits_ = 0;
  110. uintptr_t address_begin_ = 0;
  111. #if BUILDFLAG(PA_DCHECK_IS_ON)
  112. uintptr_t address_end_ = 0;
  113. #endif
  114. };
  115. PA_ALWAYS_INLINE Pool* GetPool(pool_handle handle) {
  116. PA_DCHECK(0 < handle && handle <= kNumPools);
  117. return &pools_[handle - 1];
  118. }
  119. // Gets the stats for the pool identified by `handle`, if
  120. // initialized.
  121. void GetPoolStats(pool_handle handle, PoolStats* stats);
  122. Pool pools_[kNumPools];
  123. #endif // defined(PA_HAS_64_BITS_POINTERS)
  124. static AddressPoolManager singleton_;
  125. };
  126. PA_ALWAYS_INLINE pool_handle GetRegularPool() {
  127. return kRegularPoolHandle;
  128. }
  129. PA_ALWAYS_INLINE pool_handle GetBRPPool() {
  130. return kBRPPoolHandle;
  131. }
  132. PA_ALWAYS_INLINE pool_handle GetConfigurablePool() {
  133. PA_DCHECK(IsConfigurablePoolAvailable());
  134. return kConfigurablePoolHandle;
  135. }
  136. } // namespace partition_alloc::internal
  137. #endif // BASE_ALLOCATOR_PARTITION_ALLOCATOR_ADDRESS_POOL_MANAGER_H_