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; 22 void setFromArray(CompactPtrT *Array, u16 N) { 23 DCHECK_LE(N, MaxNumCached); 24 Count = N; 25 memcpy(Batch, Array, sizeof(Batch[0]) * Count); 26 } 27 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 } 33 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 } 42 void clear() { Count = 0; } 43 void add(CompactPtrT P) { 44 DCHECK_LT(Count, MaxNumCached); 45 Batch[Count++] = P; 46 } 47 void moveToArray(CompactPtrT *Array) { 48 memcpy(Array, Batch, sizeof(Batch[0]) * Count); 49 clear(); 50 } 51 u16 getCount() const { return Count; } 52 bool isEmpty() const { return Count == 0U; } 53 CompactPtrT get(u16 I) const { 54 DCHECK_LE(I, Count); 55 return Batch[I]; 56 } 57 TransferBatch *Next; 58 59 private: 60 CompactPtrT Batch[MaxNumCached]; 61 u16 Count; 62 }; 63 64 // A BatchGroup is used to collect blocks. Each group has a group id to 65 // identify the group kind of contained blocks. 66 template <class SizeClassAllocator> struct BatchGroup { 67 // `Next` is used by IntrusiveList. 68 BatchGroup *Next; 69 // The compact base address of each group 70 uptr CompactPtrGroupBase; 71 // Cache value of SizeClassAllocatorLocalCache::getMaxCached() 72 u16 MaxCachedPerBatch; 73 // Number of blocks pushed into this group. This is an increment-only 74 // counter. 75 uptr PushedBlocks; 76 // This is used to track how many bytes are not in-use since last time we 77 // tried to release pages. 78 uptr BytesInBGAtLastCheckpoint; 79 // Blocks are managed by TransferBatch in a list. 80 SinglyLinkedList<TransferBatch<SizeClassAllocator>> Batches; 81 }; 82 83 } // namespace scudo 84 85 #endif // SCUDO_ALLOCATOR_COMMON_H_ 86