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