#include "partition_alloc/partition_bucket.h"
#include <algorithm>
#include <cstdint>
#include <tuple>
#include "partition_alloc/address_pool_manager.h"
#include "partition_alloc/build_config.h"
#include "partition_alloc/buildflags.h"
#include "partition_alloc/freeslot_bitmap.h"
#include "partition_alloc/freeslot_bitmap_constants.h"
#include "partition_alloc/oom.h"
#include "partition_alloc/page_allocator.h"
#include "partition_alloc/page_allocator_constants.h"
#include "partition_alloc/partition_address_space.h"
#include "partition_alloc/partition_alloc.h"
#include "partition_alloc/partition_alloc_base/bits.h"
#include "partition_alloc/partition_alloc_base/compiler_specific.h"
#include "partition_alloc/partition_alloc_base/component_export.h"
#include "partition_alloc/partition_alloc_base/debug/alias.h"
#include "partition_alloc/partition_alloc_base/immediate_crash.h"
#include "partition_alloc/partition_alloc_base/thread_annotations.h"
#include "partition_alloc/partition_alloc_check.h"
#include "partition_alloc/partition_alloc_config.h"
#include "partition_alloc/partition_alloc_constants.h"
#include "partition_alloc/partition_alloc_forward.h"
#include "partition_alloc/partition_direct_map_extent.h"
#include "partition_alloc/partition_freelist_entry.h"
#include "partition_alloc/partition_oom.h"
#include "partition_alloc/partition_page.h"
#include "partition_alloc/partition_root.h"
#include "partition_alloc/reservation_offset_table.h"
#include "partition_alloc/tagging.h"
namespace partition_alloc::internal {
namespace {
[[noreturn]] PA_NOINLINE void PartitionOutOfMemoryMappingFailure(
PartitionRoot* root,
size_t size) PA_LOCKS_EXCLUDED(PartitionRootLock(root)) { … }
[[noreturn]] PA_NOINLINE void PartitionOutOfMemoryCommitFailure(
PartitionRoot* root,
size_t size) PA_LOCKS_EXCLUDED(PartitionRootLock(root)) { … }
#if !PA_BUILDFLAG(HAS_64_BIT_POINTERS) && \
PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
bool AreAllowedSuperPagesForBRPPool(uintptr_t start, uintptr_t end) {
PA_DCHECK(!(start % kSuperPageSize));
for (uintptr_t super_page = start; super_page < end;
super_page += kSuperPageSize) {
if (!AddressPoolManagerBitmap::IsAllowedSuperPageForBRPPool(super_page)) {
AddressPoolManagerBitmap::IncrementBlocklistHitCount();
return false;
}
}
return true;
}
#endif
uintptr_t ReserveMemoryFromPool(pool_handle pool,
uintptr_t requested_address,
size_t requested_size) { … }
SlotSpanMetadata* PartitionDirectMap(PartitionRoot* root,
AllocFlags flags,
size_t raw_size,
size_t slot_span_alignment) { … }
uint8_t ComputeSystemPagesPerSlotSpanPreferSmall(size_t slot_size) { … }
uint8_t ComputeSystemPagesPerSlotSpanInternal(size_t slot_size) { … }
}
uint8_t ComputeSystemPagesPerSlotSpan(size_t slot_size,
bool prefer_smaller_slot_spans) { … }
void PartitionBucket::Init(uint32_t new_slot_size,
bool use_small_single_slot_spans) { … }
PA_ALWAYS_INLINE SlotSpanMetadata* PartitionBucket::AllocNewSlotSpan(
PartitionRoot* root,
AllocFlags flags,
size_t slot_span_alignment) { … }
void PartitionBucket::InitCanStoreRawSize(bool use_small_single_slot_spans) { … }
uintptr_t PartitionBucket::AllocNewSuperPageSpan(PartitionRoot* root,
size_t super_page_count,
AllocFlags flags) { … }
PA_ALWAYS_INLINE uintptr_t
PartitionBucket::AllocNewSuperPage(PartitionRoot* root, AllocFlags flags) { … }
PA_ALWAYS_INLINE uintptr_t
PartitionBucket::InitializeSuperPage(PartitionRoot* root,
uintptr_t super_page,
uintptr_t requested_address) { … }
PA_ALWAYS_INLINE void PartitionBucket::InitializeSlotSpan(
SlotSpanMetadata* slot_span) { … }
PA_ALWAYS_INLINE uintptr_t
PartitionBucket::ProvisionMoreSlotsAndAllocOne(PartitionRoot* root,
AllocFlags flags,
SlotSpanMetadata* slot_span) { … }
bool PartitionBucket::SetNewActiveSlotSpan() { … }
void PartitionBucket::MaintainActiveList() { … }
void PartitionBucket::SortSmallerSlotSpanFreeLists() { … }
PA_COMPONENT_EXPORT(PARTITION_ALLOC)
bool CompareSlotSpans(SlotSpanMetadata* a, SlotSpanMetadata* b) { … }
void PartitionBucket::SortActiveSlotSpans() { … }
uintptr_t PartitionBucket::SlowPathAlloc(PartitionRoot* root,
AllocFlags flags,
size_t raw_size,
size_t slot_span_alignment,
SlotSpanMetadata** slot_span,
bool* is_already_zeroed) { … }
uintptr_t PartitionBucket::AllocNewSuperPageSpanForGwpAsan(
PartitionRoot* root,
size_t super_page_count,
AllocFlags flags) { … }
void PartitionBucket::InitializeSlotSpanForGwpAsan(
SlotSpanMetadata* slot_span) { … }
}