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
15namespace scudo {
16
17template <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 bool empty() { return Count == 0; }
44 void add(CompactPtrT P) {
45 DCHECK_LT(Count, MaxNumCached);
46 Batch[Count++] = P;
47 }
48 void moveToArray(CompactPtrT *Array) {
49 memcpy(Array, Batch, sizeof(Batch[0]) * Count);
50 clear();
51 }
52
53 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 }
58 u16 getCount() const { return Count; }
59 bool isEmpty() const { return Count == 0U; }
60 CompactPtrT get(u16 I) const {
61 DCHECK_LE(I, Count);
62 return Batch[I];
63 }
64 TransferBatch *Next;
65
66private:
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.
73template <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