@@ -244,6 +244,7 @@ class MapAllocatorCache {
244
244
// The cache is initially empty
245
245
LRUHead = CachedBlock::InvalidEntry;
246
246
LRUTail = CachedBlock::InvalidEntry;
247
+ LastUnreleasedEntry = CachedBlock::InvalidEntry;
247
248
248
249
// Available entries will be retrieved starting from the beginning of the
249
250
// Entries array
@@ -318,9 +319,10 @@ class MapAllocatorCache {
318
319
}
319
320
CachedBlock PrevEntry = Quarantine[QuarantinePos];
320
321
Quarantine[QuarantinePos] = Entry;
321
- if (OldestTime == 0 )
322
- OldestTime = Entry.Time ;
323
322
Entry = PrevEntry;
323
+ // Update the entry time to reflect the time that the
324
+ // quarantined memory is placed in the Entries array
325
+ Entry.Time = Time;
324
326
}
325
327
326
328
// All excess entries are evicted from the cache
@@ -331,9 +333,6 @@ class MapAllocatorCache {
331
333
}
332
334
333
335
insert (Entry);
334
-
335
- if (OldestTime == 0 )
336
- OldestTime = Entry.Time ;
337
336
} while (0 );
338
337
339
338
for (MemMapT &EvictMemMap : EvictionMemMaps)
@@ -532,6 +531,9 @@ class MapAllocatorCache {
532
531
Entries[LRUHead].Prev = static_cast <u16>(FreeIndex);
533
532
}
534
533
534
+ if (LastUnreleasedEntry == CachedBlock::InvalidEntry)
535
+ LastUnreleasedEntry = static_cast <u16>(FreeIndex);
536
+
535
537
Entries[FreeIndex] = Entry;
536
538
Entries[FreeIndex].Next = LRUHead;
537
539
Entries[FreeIndex].Prev = CachedBlock::InvalidEntry;
@@ -549,6 +551,9 @@ class MapAllocatorCache {
549
551
550
552
Entries[I].invalidate ();
551
553
554
+ if (I == LastUnreleasedEntry)
555
+ LastUnreleasedEntry = Entries[LastUnreleasedEntry].Prev ;
556
+
552
557
if (I == LRUHead)
553
558
LRUHead = Entries[I].Next ;
554
559
else
@@ -590,35 +595,37 @@ class MapAllocatorCache {
590
595
}
591
596
}
592
597
593
- void releaseIfOlderThan (CachedBlock &Entry, u64 Time) REQUIRES(Mutex) {
594
- if (!Entry.isValid () || !Entry.Time )
595
- return ;
596
- if (Entry.Time > Time) {
597
- if (OldestTime == 0 || Entry.Time < OldestTime)
598
- OldestTime = Entry.Time ;
599
- return ;
600
- }
598
+ inline void release (CachedBlock &Entry) {
599
+ DCHECK (Entry.Time != 0 );
601
600
Entry.MemMap .releaseAndZeroPagesToOS (Entry.CommitBase , Entry.CommitSize );
602
601
Entry.Time = 0 ;
603
602
}
604
603
605
604
void releaseOlderThan (u64 Time) EXCLUDES(Mutex) {
606
605
ScopedLock L (Mutex);
607
- if (!EntriesCount || OldestTime == 0 || OldestTime > Time )
606
+ if (!EntriesCount)
608
607
return ;
609
- OldestTime = 0 ;
610
- for (uptr I = 0 ; I < Config::getQuarantineSize (); I++)
611
- releaseIfOlderThan (Quarantine[I], Time);
612
- for (uptr I = 0 ; I < Config::getEntriesArraySize (); I++)
613
- releaseIfOlderThan (Entries[I], Time);
614
- }
615
608
609
+ for (uptr I = 0 ; I < Config::getQuarantineSize (); I++) {
610
+ CachedBlock &ReleaseEntry = Quarantine[I];
611
+ if (!ReleaseEntry.isValid () || !ReleaseEntry.Time ||
612
+ ReleaseEntry.Time > Time)
613
+ continue ;
614
+ release (ReleaseEntry);
615
+ }
616
+
617
+ // Release oldest entries first by releasing from decommit base
618
+ while (LastUnreleasedEntry != CachedBlock::InvalidEntry &&
619
+ Entries[LastUnreleasedEntry].Time <= Time) {
620
+ release (Entries[LastUnreleasedEntry]);
621
+ LastUnreleasedEntry = Entries[LastUnreleasedEntry].Prev ;
622
+ }
623
+ }
616
624
HybridMutex Mutex;
617
625
u32 EntriesCount GUARDED_BY (Mutex) = 0;
618
626
u32 QuarantinePos GUARDED_BY (Mutex) = 0;
619
627
atomic_u32 MaxEntriesCount = {};
620
628
atomic_uptr MaxEntrySize = {};
621
- u64 OldestTime GUARDED_BY (Mutex) = 0;
622
629
atomic_s32 ReleaseToOsIntervalMs = {};
623
630
u32 CallsToRetrieve GUARDED_BY (Mutex) = 0;
624
631
u32 SuccessfulRetrieves GUARDED_BY (Mutex) = 0;
@@ -633,6 +640,9 @@ class MapAllocatorCache {
633
640
u16 LRUTail GUARDED_BY (Mutex) = 0;
634
641
// The AvailableHead is the top of the stack of available entries
635
642
u16 AvailableHead GUARDED_BY (Mutex) = 0;
643
+ // The LastUnreleasedEntry is the least recently used entry that has not
644
+ // been released
645
+ u16 LastUnreleasedEntry GUARDED_BY (Mutex) = 0;
636
646
};
637
647
638
648
template <typename Config> class MapAllocator {
0 commit comments