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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef SCUDO_ALLOCATOR_COMMON_H_ 10 #define SCUDO_ALLOCATOR_COMMON_H_ 11 12 #include "common.h" 13 #include "list.h" 14 15 namespace scudo { 16 17 template <class SizeClassAllocator> struct TransferBatch { 18 typedef typename SizeClassAllocator::SizeClassMap SizeClassMap; 19 typedef typename SizeClassAllocator::CompactPtrT CompactPtrT; 20 21 static const u16 MaxNumCached = SizeClassMap::MaxNumCachedHint; setFromArrayTransferBatch22 void setFromArray(CompactPtrT *Array, u16 N) { 23 DCHECK_LE(N, MaxNumCached); 24 Count = N; 25 memcpy(Batch, Array, sizeof(Batch[0]) * Count); 26 } appendFromArrayTransferBatch27 void appendFromArray(CompactPtrT *Array, u16 N) { 28 DCHECK_LE(N, MaxNumCached - Count); 29 memcpy(Batch + Count, Array, sizeof(Batch[0]) * N); 30 // u16 will be promoted to int by arithmetic type conversion. 31 Count = static_cast<u16>(Count + N); 32 } appendFromTransferBatchTransferBatch33 void appendFromTransferBatch(TransferBatch *B, u16 N) { 34 DCHECK_LE(N, MaxNumCached - Count); 35 DCHECK_GE(B->Count, N); 36 // Append from the back of `B`. 37 memcpy(Batch + Count, B->Batch + (B->Count - N), sizeof(Batch[0]) * N); 38 // u16 will be promoted to int by arithmetic type conversion. 39 Count = static_cast<u16>(Count + N); 40 B->Count = static_cast<u16>(B->Count - N); 41 } clearTransferBatch42 void clear() { Count = 0; } emptyTransferBatch43 bool empty() { return Count == 0; } addTransferBatch44 void add(CompactPtrT P) { 45 DCHECK_LT(Count, MaxNumCached); 46 Batch[Count++] = P; 47 } moveToArrayTransferBatch48 void moveToArray(CompactPtrT *Array) { 49 memcpy(Array, Batch, sizeof(Batch[0]) * Count); 50 clear(); 51 } 52 moveNToArrayTransferBatch53 void moveNToArray(CompactPtrT *Array, u16 N) { 54 DCHECK_LE(N, Count); 55 memcpy(Array, Batch + Count - N, sizeof(Batch[0]) * N); 56 Count = static_cast<u16>(Count - N); 57 } getCountTransferBatch58 u16 getCount() const { return Count; } isEmptyTransferBatch59 bool isEmpty() const { return Count == 0U; } getTransferBatch60 CompactPtrT get(u16 I) const { 61 DCHECK_LE(I, Count); 62 return Batch[I]; 63 } 64 TransferBatch *Next; 65 66 private: 67 CompactPtrT Batch[MaxNumCached]; 68 u16 Count; 69 }; 70 71 // A BatchGroup is used to collect blocks. Each group has a group id to 72 // identify the group kind of contained blocks. 73 template <class SizeClassAllocator> struct BatchGroup { 74 // `Next` is used by IntrusiveList. 75 BatchGroup *Next; 76 // The compact base address of each group 77 uptr CompactPtrGroupBase; 78 // Cache value of SizeClassAllocatorLocalCache::getMaxCached() 79 u16 MaxCachedPerBatch; 80 // Number of blocks pushed into this group. This is an increment-only 81 // counter. 82 uptr PushedBlocks; 83 // This is used to track how many bytes are not in-use since last time we 84 // tried to release pages. 85 uptr BytesInBGAtLastCheckpoint; 86 // Blocks are managed by TransferBatch in a list. 87 SinglyLinkedList<TransferBatch<SizeClassAllocator>> Batches; 88 }; 89 90 } // namespace scudo 91 92 #endif // SCUDO_ALLOCATOR_COMMON_H_ 93