xref: /aosp_15_r20/external/scudo/standalone/allocator_common.h (revision 76559068c068bd27e82aff38fac3bfc865233bca)
1*76559068SAndroid Build Coastguard Worker //===-- allocator_common.h --------------------------------------*- C++ -*-===//
2*76559068SAndroid Build Coastguard Worker //
3*76559068SAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*76559068SAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information.
5*76559068SAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*76559068SAndroid Build Coastguard Worker //
7*76559068SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
8*76559068SAndroid Build Coastguard Worker 
9*76559068SAndroid Build Coastguard Worker #ifndef SCUDO_ALLOCATOR_COMMON_H_
10*76559068SAndroid Build Coastguard Worker #define SCUDO_ALLOCATOR_COMMON_H_
11*76559068SAndroid Build Coastguard Worker 
12*76559068SAndroid Build Coastguard Worker #include "common.h"
13*76559068SAndroid Build Coastguard Worker #include "list.h"
14*76559068SAndroid Build Coastguard Worker 
15*76559068SAndroid Build Coastguard Worker namespace scudo {
16*76559068SAndroid Build Coastguard Worker 
17*76559068SAndroid Build Coastguard Worker template <class SizeClassAllocator> struct TransferBatch {
18*76559068SAndroid Build Coastguard Worker   typedef typename SizeClassAllocator::SizeClassMap SizeClassMap;
19*76559068SAndroid Build Coastguard Worker   typedef typename SizeClassAllocator::CompactPtrT CompactPtrT;
20*76559068SAndroid Build Coastguard Worker 
21*76559068SAndroid Build Coastguard Worker   static const u16 MaxNumCached = SizeClassMap::MaxNumCachedHint;
setFromArrayTransferBatch22*76559068SAndroid Build Coastguard Worker   void setFromArray(CompactPtrT *Array, u16 N) {
23*76559068SAndroid Build Coastguard Worker     DCHECK_LE(N, MaxNumCached);
24*76559068SAndroid Build Coastguard Worker     Count = N;
25*76559068SAndroid Build Coastguard Worker     memcpy(Batch, Array, sizeof(Batch[0]) * Count);
26*76559068SAndroid Build Coastguard Worker   }
appendFromArrayTransferBatch27*76559068SAndroid Build Coastguard Worker   void appendFromArray(CompactPtrT *Array, u16 N) {
28*76559068SAndroid Build Coastguard Worker     DCHECK_LE(N, MaxNumCached - Count);
29*76559068SAndroid Build Coastguard Worker     memcpy(Batch + Count, Array, sizeof(Batch[0]) * N);
30*76559068SAndroid Build Coastguard Worker     // u16 will be promoted to int by arithmetic type conversion.
31*76559068SAndroid Build Coastguard Worker     Count = static_cast<u16>(Count + N);
32*76559068SAndroid Build Coastguard Worker   }
appendFromTransferBatchTransferBatch33*76559068SAndroid Build Coastguard Worker   void appendFromTransferBatch(TransferBatch *B, u16 N) {
34*76559068SAndroid Build Coastguard Worker     DCHECK_LE(N, MaxNumCached - Count);
35*76559068SAndroid Build Coastguard Worker     DCHECK_GE(B->Count, N);
36*76559068SAndroid Build Coastguard Worker     // Append from the back of `B`.
37*76559068SAndroid Build Coastguard Worker     memcpy(Batch + Count, B->Batch + (B->Count - N), sizeof(Batch[0]) * N);
38*76559068SAndroid Build Coastguard Worker     // u16 will be promoted to int by arithmetic type conversion.
39*76559068SAndroid Build Coastguard Worker     Count = static_cast<u16>(Count + N);
40*76559068SAndroid Build Coastguard Worker     B->Count = static_cast<u16>(B->Count - N);
41*76559068SAndroid Build Coastguard Worker   }
clearTransferBatch42*76559068SAndroid Build Coastguard Worker   void clear() { Count = 0; }
emptyTransferBatch43*76559068SAndroid Build Coastguard Worker   bool empty() { return Count == 0; }
addTransferBatch44*76559068SAndroid Build Coastguard Worker   void add(CompactPtrT P) {
45*76559068SAndroid Build Coastguard Worker     DCHECK_LT(Count, MaxNumCached);
46*76559068SAndroid Build Coastguard Worker     Batch[Count++] = P;
47*76559068SAndroid Build Coastguard Worker   }
moveToArrayTransferBatch48*76559068SAndroid Build Coastguard Worker   void moveToArray(CompactPtrT *Array) {
49*76559068SAndroid Build Coastguard Worker     memcpy(Array, Batch, sizeof(Batch[0]) * Count);
50*76559068SAndroid Build Coastguard Worker     clear();
51*76559068SAndroid Build Coastguard Worker   }
52*76559068SAndroid Build Coastguard Worker 
moveNToArrayTransferBatch53*76559068SAndroid Build Coastguard Worker   void moveNToArray(CompactPtrT *Array, u16 N) {
54*76559068SAndroid Build Coastguard Worker     DCHECK_LE(N, Count);
55*76559068SAndroid Build Coastguard Worker     memcpy(Array, Batch + Count - N, sizeof(Batch[0]) * N);
56*76559068SAndroid Build Coastguard Worker     Count = static_cast<u16>(Count - N);
57*76559068SAndroid Build Coastguard Worker   }
getCountTransferBatch58*76559068SAndroid Build Coastguard Worker   u16 getCount() const { return Count; }
isEmptyTransferBatch59*76559068SAndroid Build Coastguard Worker   bool isEmpty() const { return Count == 0U; }
getTransferBatch60*76559068SAndroid Build Coastguard Worker   CompactPtrT get(u16 I) const {
61*76559068SAndroid Build Coastguard Worker     DCHECK_LE(I, Count);
62*76559068SAndroid Build Coastguard Worker     return Batch[I];
63*76559068SAndroid Build Coastguard Worker   }
64*76559068SAndroid Build Coastguard Worker   TransferBatch *Next;
65*76559068SAndroid Build Coastguard Worker 
66*76559068SAndroid Build Coastguard Worker private:
67*76559068SAndroid Build Coastguard Worker   CompactPtrT Batch[MaxNumCached];
68*76559068SAndroid Build Coastguard Worker   u16 Count;
69*76559068SAndroid Build Coastguard Worker };
70*76559068SAndroid Build Coastguard Worker 
71*76559068SAndroid Build Coastguard Worker // A BatchGroup is used to collect blocks. Each group has a group id to
72*76559068SAndroid Build Coastguard Worker // identify the group kind of contained blocks.
73*76559068SAndroid Build Coastguard Worker template <class SizeClassAllocator> struct BatchGroup {
74*76559068SAndroid Build Coastguard Worker   // `Next` is used by IntrusiveList.
75*76559068SAndroid Build Coastguard Worker   BatchGroup *Next;
76*76559068SAndroid Build Coastguard Worker   // The compact base address of each group
77*76559068SAndroid Build Coastguard Worker   uptr CompactPtrGroupBase;
78*76559068SAndroid Build Coastguard Worker   // This is used to track how many bytes are not in-use since last time we
79*76559068SAndroid Build Coastguard Worker   // tried to release pages.
80*76559068SAndroid Build Coastguard Worker   uptr BytesInBGAtLastCheckpoint;
81*76559068SAndroid Build Coastguard Worker   // Blocks are managed by TransferBatch in a list.
82*76559068SAndroid Build Coastguard Worker   SinglyLinkedList<TransferBatch<SizeClassAllocator>> Batches;
83*76559068SAndroid Build Coastguard Worker   // Cache value of SizeClassAllocatorLocalCache::getMaxCached()
84*76559068SAndroid Build Coastguard Worker   u16 MaxCachedPerBatch;
85*76559068SAndroid Build Coastguard Worker };
86*76559068SAndroid Build Coastguard Worker 
87*76559068SAndroid Build Coastguard Worker } // namespace scudo
88*76559068SAndroid Build Coastguard Worker 
89*76559068SAndroid Build Coastguard Worker #endif // SCUDO_ALLOCATOR_COMMON_H_
90