3#include <absl/container/btree_set.h>
55 std::integral_constant<
decltype(&SetCompareFn), &SetCompareFn>;
63static_assert(std::is_trivially_destructible_v<MemoryRegion>);
86 "top address must be greater than or equal to the start "
87 "address: {:#x} < {:#x}",
107static_assert(
sizeof(MemorySpace) ==
sizeof(MemoryRegion) +
kPointerSize);
108static_assert(std::is_trivially_destructible_v<MemorySpace>);
124 size_t Size()
const {
return chunk_bits_ >> kSizeShift; }
125 bool IsValid()
const {
return chunk_bits_ != 0; }
130 chunk_bits_ =
size << kSizeShift;
134 chunk_bits_ = kAllocatedBit |
size << kSizeShift;
142 "Expected top bits of {} to be clear",
howmuch);
146 static constexpr size_t MaxSize() {
return kMaxSize; }
149 size_t SizeWithoutAllocatedBit()
const {
153 static constexpr const size_t kAllocatedBit = 1;
154 static constexpr const size_t kMarkBit = 2;
155 static constexpr const size_t kSizeShift = 5;
157 static constexpr const size_t kMaxSize = 0x7FF'FFFF'FFFF'FFFFull;
162 uint64_t chunk_bits_;
188 BASSERT_EQ(pin_count_, 0,
"Trying to mark pinned allocation as disposed");
201 "Overflow of pin_count_");
220static_assert(
alignof(AllocatorFrontMetadata) ==
kPointerSize);
222static_assert(std::is_trivially_destructible_v<AllocatorBackMetadata>);
223static_assert(std::is_trivially_destructible_v<AllocatorFrontMetadata>);
319 "large_space_threshold must be less than space_size: {} >= {}",
336 using FreeList = absl::btree_multiset<MemoryRegion, MemoryRegion::SetCompare>;
337#ifdef BROOM_DEBUG_SLOW
377#ifdef BROOM_FOR_TESTING
408#ifdef BROOM_FOR_TESTING
static void UnpinBasePointer(const void *pointer)
virtual const void * GetBasePointerOfMaybeInnerPointer(const void *maybe_inner) const =0
static constexpr const size_t kGiantMappingSize
static constexpr const int kFrontMetadataSize
static constexpr const size_t kDefaultLargeSpaceSize
MemoryPressure CalculateMemoryPressure() const
static void PinBasePointer(const void *pointer, uint32_t how_many)
static size_t SpaceMask(size_t space_size)
static constexpr const int kTotalMetadataSize
static constexpr const int kBackMetadataSize
virtual void Dispose(void *definitely_uintptr)=0
virtual void * Allocate(size_t requested_size)=0
virtual size_t LargeSpaceThreshold() const =0
virtual bool Grow(size_t requested_size, MemorySpace **space_to_update)=0
static constexpr const size_t kDefaultSpaceSize
virtual ~Allocator()=default
static constexpr const MemoryPermissions kDefaultPermissions
AllocatorStatistics stats_
static constexpr const size_t kDefaultLargeSpaceThreshold
static bool IsPinnedBasePointer(const void *pointer)
virtual void * Allocate(size_t requested_size) override
virtual size_t LargeSpaceThreshold() const override
static constexpr size_t GetRealAllocationSize(size_t requested_size)
void * TryAllocateExactOrFindNext(FreeList &free_list, FreeList::iterator &pos, size_t requested_size)
virtual bool Grow(size_t requested_size, MemorySpace **space_to_update) override
virtual ~FreeListAllocator()
MemorySpace * current_large_space_
FreeList large_free_list_
FreeListAllocator(size_t space_size=kDefaultSpaceSize, size_t large_space_size=kDefaultLargeSpaceSize, size_t large_space_threshold=kDefaultLargeSpaceThreshold)
static constexpr const size_t kLargeSpaceThreshold
MemorySpace * current_space_
void AddOrCoalesceFreeListImpl(FreeList &free_list, const MemoryRegion current, const MemoryRegion previous, const MemoryRegion next, const MemoryRegion coalesced)
std::vector< MemorySpace > spaces_
void FillSpaceAndAddToFreeList(FreeList *list, MemorySpace *space)
void * TryAllocateFromLargeFreeList(size_t requested_size)
void AddOrCoalesceFreeList(const MemoryRegion current, const MemoryRegion previous, const MemoryRegion next, const MemoryRegion coalesced)
void * AllocateRawPointer(size_t requested_size)
void DisposeRawPointer(void *definitely_pointer)
FreeList::iterator FindExactRegion(FreeList &free_list, const MemoryRegion region)
void * TryAllocateFromFreeList(size_t requested_size)
size_t large_space_threshold_
absl::btree_multiset< MemoryRegion, MemoryRegion::SetCompare > FreeList
void AddOrCoalesceLargeFreeList(const MemoryRegion current, const MemoryRegion previous, const MemoryRegion next, const MemoryRegion coalesced)
virtual void Dispose(void *definitely_uintptr) override
static constexpr size_t MaximumAllocationSize()
void * SplitFreeListEntry(FreeList &free_list, FreeList::iterator &pos, size_t requested_size)
virtual const void * GetBasePointerOfMaybeInnerPointer(const void *maybe_inner) const override
void * TryAllocateFromFreeListImpl(FreeList &free_list, size_t requested_size)
std::vector< MemorySpace > large_spaces_
MemoryRegion(const void *start, const void *end)
void IncrementStart(size_t how_much)
bool operator==(const MemoryRegion &other) const
MemoryRegion(const void *start, size_t size)
MemoryRegion(UintPtr start, UintPtr end)
bool AttemptGrow(size_t howmuch)
bool operator!=(const MemoryRegion &other) const
std::integral_constant< decltype(&SetCompareFn), &SetCompareFn > SetCompare
MemorySpace(const void *start, size_t size)
size_t RemainingBytes() const
UintPtr Allocate(size_t size)
#define BASSERT_EQ(lhs, rhs, m,...)
#define BASSERT(x, m,...)
#define BASSERT_GE(lhs, rhs, m,...)
#define BENSURE_GT(lhs, rhs, m,...)
#define BENSURE_LE(lhs, rhs, m,...)
#define BASSERT_LT(lhs, rhs, m,...)
#define BASSERT_GT(lhs, rhs, m,...)
#define BENSURE_LT(lhs, rhs, m,...)
#define BENSURE_EQ(lhs, rhs, m,...)
AllocatorCommonMetadata AllocatorBackMetadata
constexpr const size_t MB
constexpr bool AddOverflowChecked(T lhs, T rhs, T &destination)
constexpr const int kPointerSize
constexpr const uintptr_t kNullUintPtr
constexpr T SafeCast(U v)
std::queue< T, broom::deque< T > > queue
size_t total_mapped_bytes
static T RelaxedFetchAdd(T *where, T howmuch)
static T RelaxedFetchSub(T *where, T howmuch)
static T RelaxedLoad(T *source)