@@ -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
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  = static_cast <u16 >(C->Count  + NumBlocksRefilled);
185+     return  NumBlocksRefilled != 0 ;
258186  }
259187
260188  NOINLINE void  drain (PerClass *C, uptr ClassId) {
0 commit comments