chromium/base/allocator/partition_allocator/src/partition_alloc/partition_bucket.cc

// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#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)
// |start| has to be aligned to kSuperPageSize, but |end| doesn't. This means
// that a partial super page is allowed at the end. Since the block list uses
// kSuperPageSize granularity, a partial super page is considered blocked if
// there is a raw_ptr<T> pointing anywhere in that super page, even if doesn't
// point to that partially allocated region.
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 any blocked super page is found inside the given memory region,
    // the memory region is blocked.
    if (!AddressPoolManagerBitmap::IsAllowedSuperPageForBRPPool(super_page)) {
      AddressPoolManagerBitmap::IncrementBlocklistHitCount();
      return false;
    }
  }
  return true;
}
#endif  // !PA_BUILDFLAG(HAS_64_BIT_POINTERS) &&
        // PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)

// Reserves |requested_size| worth of super pages from the specified pool.
// If BRP pool is requested this function will honor BRP block list.
//
// The returned address will be aligned to kSuperPageSize, and so
// |requested_address| should be. |requested_size| doesn't have to be, however.
//
// |requested_address| is merely a hint, which will be attempted, but easily
// given up on if doesn't work the first time.
//
// The function doesn't need to hold root->lock_ or any other locks, because:
// - It (1) reserves memory, (2) then consults AreAllowedSuperPagesForBRPPool
//   for that memory, and (3) returns the memory if
//   allowed, or unreserves and decommits if not allowed. So no other
//   overlapping region can be allocated while executing
//   AreAllowedSuperPagesForBRPPool.
// - IsAllowedSuperPageForBRPPool (used by AreAllowedSuperPagesForBRPPool) is
//   designed to not need locking.
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) {}

}  // namespace

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) {}

}  // namespace partition_alloc::internal