@@ -22,74 +22,6 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache {
22
22
typedef typename SizeClassAllocator::SizeClassMap SizeClassMap;
23
23
typedef typename SizeClassAllocator::CompactPtrT CompactPtrT;
24
24
25
- struct TransferBatch {
26
- static const u16 MaxNumCached = SizeClassMap::MaxNumCachedHint;
27
- void setFromArray (CompactPtrT *Array, u16 N) {
28
- DCHECK_LE (N, MaxNumCached);
29
- Count = N;
30
- memcpy (Batch, Array, sizeof (Batch[0 ]) * Count);
31
- }
32
- void appendFromArray (CompactPtrT *Array, u16 N) {
33
- DCHECK_LE (N, MaxNumCached - Count);
34
- memcpy (Batch + Count, Array, sizeof (Batch[0 ]) * N);
35
- // u16 will be promoted to int by arithmetic type conversion.
36
- Count = static_cast <u16>(Count + N);
37
- }
38
- void appendFromTransferBatch (TransferBatch *B, u16 N) {
39
- DCHECK_LE (N, MaxNumCached - Count);
40
- DCHECK_GE (B->Count , N);
41
- // Append from the back of `B`.
42
- memcpy (Batch + Count, B->Batch + (B->Count - N), sizeof (Batch[0 ]) * N);
43
- // u16 will be promoted to int by arithmetic type conversion.
44
- Count = static_cast <u16>(Count + N);
45
- B->Count = static_cast <u16>(B->Count - N);
46
- }
47
- void clear () { Count = 0 ; }
48
- void add (CompactPtrT P) {
49
- DCHECK_LT (Count, MaxNumCached);
50
- Batch[Count++] = P;
51
- }
52
- void copyToArray (CompactPtrT *Array) const {
53
- memcpy (Array, Batch, sizeof (Batch[0 ]) * Count);
54
- }
55
- u16 getCount () const { return Count; }
56
- bool isEmpty () const { return Count == 0U ; }
57
- CompactPtrT get (u16 I) const {
58
- DCHECK_LE (I, Count);
59
- return Batch[I];
60
- }
61
- static u16 getMaxCached (uptr Size ) {
62
- return Min (MaxNumCached, SizeClassMap::getMaxCachedHint (Size ));
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
- 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 TransferBatch::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> Batches;
88
- };
89
-
90
- static_assert (sizeof (BatchGroup) <= sizeof (TransferBatch),
91
- " BatchGroup uses the same class size as TransferBatch" );
92
-
93
25
void init (GlobalStats *S, SizeClassAllocator *A) {
94
26
DCHECK (isEmpty ());
95
27
Stats.init ();
@@ -151,7 +83,7 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache {
151
83
}
152
84
153
85
void drain () {
154
- // Drain BatchClassId last as createBatch can refill it .
86
+ // Drain BatchClassId last as it may be needed while draining normal blocks .
155
87
for (uptr I = 0 ; I < NumClasses; ++I) {
156
88
if (I == BatchClassId)
157
89
continue ;
@@ -163,19 +95,11 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache {
163
95
DCHECK (isEmpty ());
164
96
}
165
97
166
- TransferBatch *createBatch (uptr ClassId, void *B) {
167
- if (ClassId != BatchClassId)
168
- B = allocate (BatchClassId);
98
+ void *getBatchClassBlock () {
99
+ void *B = allocate (BatchClassId);
169
100
if (UNLIKELY (!B))
170
101
reportOutOfMemory (SizeClassAllocator::getSizeByClassId (BatchClassId));
171
- return reinterpret_cast <TransferBatch *>(B);
172
- }
173
-
174
- BatchGroup *createGroup () {
175
- void *Ptr = allocate (BatchClassId);
176
- if (UNLIKELY (!Ptr ))
177
- reportOutOfMemory (SizeClassAllocator::getSizeByClassId (BatchClassId));
178
- return reinterpret_cast <BatchGroup *>(Ptr );
102
+ return B;
179
103
}
180
104
181
105
LocalStats &getStats () { return Stats; }
@@ -203,6 +127,11 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache {
203
127
Str->append (" No block is cached.\n " );
204
128
}
205
129
130
+ static u16 getMaxCached (uptr Size ) {
131
+ return Min (SizeClassMap::MaxNumCachedHint,
132
+ SizeClassMap::getMaxCachedHint (Size ));
133
+ }
134
+
206
135
private:
207
136
static const uptr NumClasses = SizeClassMap::NumClasses;
208
137
static const uptr BatchClassId = SizeClassMap::BatchClassId;
@@ -211,7 +140,7 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache {
211
140
u16 MaxCount;
212
141
// Note: ClassSize is zero for the transfer batch.
213
142
uptr ClassSize;
214
- CompactPtrT Chunks[2 * TransferBatch::MaxNumCached ];
143
+ CompactPtrT Chunks[2 * SizeClassMap::MaxNumCachedHint ];
215
144
};
216
145
PerClass PerClassArray[NumClasses] = {};
217
146
LocalStats Stats;
@@ -228,7 +157,7 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache {
228
157
for (uptr I = 0 ; I < NumClasses; I++) {
229
158
PerClass *P = &PerClassArray[I];
230
159
const uptr Size = SizeClassAllocator::getSizeByClassId (I);
231
- P->MaxCount = static_cast <u16>(2 * TransferBatch:: getMaxCached (Size ));
160
+ P->MaxCount = static_cast <u16>(2 * getMaxCached (Size ));
232
161
if (I != BatchClassId) {
233
162
P->ClassSize = Size ;
234
163
} else {
@@ -246,15 +175,14 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache {
246
175
247
176
NOINLINE bool refill (PerClass *C, uptr ClassId) {
248
177
initCacheMaybe (C);
249
- TransferBatch *B = Allocator->popBatch (this , ClassId);
250
- if (UNLIKELY (!B))
251
- return false ;
252
- DCHECK_GT (B->getCount (), 0 );
253
- C->Count = B->getCount ();
254
- B->copyToArray (C->Chunks );
255
- B->clear ();
256
- destroyBatch (ClassId, B);
257
- return true ;
178
+
179
+ // TODO(chiahungduan): Pass the max number cached for each size class.
180
+ const u16 NumBlocksRefilled =
181
+ Allocator->popBlocks (this , ClassId, C->Chunks );
182
+ DCHECK_LE (NumBlocksRefilled,
183
+ getMaxCached (SizeClassAllocator::getSizeByClassId (ClassId)));
184
+ C->Count += NumBlocksRefilled;
185
+ return NumBlocksRefilled != 0 ;
258
186
}
259
187
260
188
NOINLINE void drain (PerClass *C, uptr ClassId) {
0 commit comments