92 lines · c
1//===-- allocator_common.h --------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef SCUDO_ALLOCATOR_COMMON_H_10#define SCUDO_ALLOCATOR_COMMON_H_11 12#include "common.h"13#include "list.h"14 15namespace scudo {16 17template <class SizeClassAllocator> struct Batch {18 typedef typename SizeClassAllocator::SizeClassMap SizeClassMap;19 typedef typename SizeClassAllocator::CompactPtrT CompactPtrT;20 21 void setFromArray(CompactPtrT *Array, u16 N) {22 DCHECK_LE(N, SizeClassAllocator::MaxNumBlocksInBatch);23 Count = N;24 memcpy(Blocks, Array, sizeof(Blocks[0]) * Count);25 }26 void appendFromArray(CompactPtrT *Array, u16 N) {27 DCHECK_LE(N, SizeClassAllocator::MaxNumBlocksInBatch - Count);28 memcpy(Blocks + Count, Array, sizeof(Blocks[0]) * N);29 // u16 will be promoted to int by arithmetic type conversion.30 Count = static_cast<u16>(Count + N);31 }32 void appendFromBatch(Batch *B, u16 N) {33 DCHECK_LE(N, SizeClassAllocator::MaxNumBlocksInBatch - Count);34 DCHECK_GE(B->Count, N);35 // Append from the back of `B`.36 memcpy(Blocks + Count, B->Blocks + (B->Count - N), sizeof(Blocks[0]) * N);37 // u16 will be promoted to int by arithmetic type conversion.38 Count = static_cast<u16>(Count + N);39 B->Count = static_cast<u16>(B->Count - N);40 }41 void clear() { Count = 0; }42 bool empty() { return Count == 0; }43 void add(CompactPtrT P) {44 DCHECK_LT(Count, SizeClassAllocator::MaxNumBlocksInBatch);45 Blocks[Count++] = P;46 }47 void moveToArray(CompactPtrT *Array) {48 memcpy(Array, Blocks, sizeof(Blocks[0]) * Count);49 clear();50 }51 52 void moveNToArray(CompactPtrT *Array, u16 N) {53 DCHECK_LE(N, Count);54 memcpy(Array, Blocks + Count - N, sizeof(Blocks[0]) * N);55 Count = static_cast<u16>(Count - N);56 }57 u16 getCount() const { return Count; }58 bool isEmpty() const { return Count == 0U; }59 CompactPtrT get(u16 I) const {60 DCHECK_LE(I, Count);61 return Blocks[I];62 }63 Batch *Next;64 65private:66 u16 Count;67 CompactPtrT Blocks[];68};69 70// A BatchGroup is used to collect blocks. Each group has a group id to71// identify the group kind of contained blocks.72template <class SizeClassAllocator> struct BatchGroup {73 // `Next` is used by IntrusiveList.74 BatchGroup *Next;75 // The compact base address of each group76 uptr CompactPtrGroupBase;77 // This is used to track how many bytes are not in-use since last time we78 // tried to release pages.79 uptr BytesInBGAtLastCheckpoint;80 // Blocks are managed by Batch in a list.81 SinglyLinkedList<Batch<SizeClassAllocator>> Batches;82 // Cache value of SizeClassAllocatorLocalCache::getMaxCached()83 // TODO(chiahungduan): Except BatchClass, every Batch stores the same number84 // of blocks. As long as we make BatchClass follow this constraint, this85 // field can be removed.86 u16 MaxCachedPerBatch;87};88 89} // namespace scudo90 91#endif // SCUDO_ALLOCATOR_COMMON_H_92