@@ -22,74 +22,6 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache {
2222 typedef typename SizeClassAllocator::SizeClassMap SizeClassMap;
2323 typedef typename SizeClassAllocator::CompactPtrT CompactPtrT;
2424
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-
9325 void init (GlobalStats *S, SizeClassAllocator *A) {
9426 DCHECK (isEmpty ());
9527 Stats.init ();
@@ -151,7 +83,7 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache {
15183 }
15284
15385 void drain () {
154- // Drain BatchClassId last as createBatch can refill it .
86+ // Drain BatchClassId last as it may be needed while draining normal blocks .
15587 for (uptr I = 0 ; I < NumClasses; ++I) {
15688 if (I == BatchClassId)
15789 continue ;
@@ -163,19 +95,11 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache {
16395 DCHECK (isEmpty ());
16496 }
16597
166- TransferBatch *createBatch (uptr ClassId, void *B) {
167- if (ClassId != BatchClassId)
168- B = allocate (BatchClassId);
98+ void *getBatchClassBlock () {
99+ void *B = allocate (BatchClassId);
169100 if (UNLIKELY (!B))
170101 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;
179103 }
180104
181105 LocalStats &getStats () { return Stats; }
@@ -203,6 +127,11 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache {
203127 Str->append (" No block is cached.\n " );
204128 }
205129
130+ static u16 getMaxCached (uptr Size) {
131+ return Min (SizeClassMap::MaxNumCachedHint,
132+ SizeClassMap::getMaxCachedHint (Size));
133+ }
134+
206135private:
207136 static const uptr NumClasses = SizeClassMap::NumClasses;
208137 static const uptr BatchClassId = SizeClassMap::BatchClassId;
@@ -211,7 +140,7 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache {
211140 u16 MaxCount;
212141 // Note: ClassSize is zero for the transfer batch.
213142 uptr ClassSize;
214- CompactPtrT Chunks[2 * TransferBatch::MaxNumCached ];
143+ CompactPtrT Chunks[2 * SizeClassMap::MaxNumCachedHint ];
215144 };
216145 PerClass PerClassArray[NumClasses] = {};
217146 LocalStats Stats;
@@ -228,7 +157,7 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache {
228157 for (uptr I = 0 ; I < NumClasses; I++) {
229158 PerClass *P = &PerClassArray[I];
230159 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));
232161 if (I != BatchClassId) {
233162 P->ClassSize = Size;
234163 } else {
@@ -246,15 +175,14 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache {
246175
247176 NOINLINE bool refill (PerClass *C, uptr ClassId) {
248177 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 ;
258186 }
259187
260188 NOINLINE void drain (PerClass *C, uptr ClassId) {
0 commit comments