Skip to content

Commit ce9e1a3

Browse files
committed
[Scudo] Fix SizeClassAllocatorLocalCache::drain
It leaved few blocks in PerClassArray[0]. Reviewed By: cryptoad Differential Revision: https://reviews.llvm.org/D99763
1 parent da98177 commit ce9e1a3

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

compiler-rt/lib/scudo/standalone/local_cache.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,22 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache {
101101
Stats.add(StatFree, ClassSize);
102102
}
103103

104+
bool isEmpty() const {
105+
for (uptr I = 0; I < NumClasses; ++I)
106+
if (PerClassArray[I].Count)
107+
return false;
108+
return true;
109+
}
110+
104111
void drain() {
105-
for (uptr I = 0; I < NumClasses; I++) {
112+
// Drain BatchClassId (0) the last as createBatch can refill it.
113+
for (uptr I = NumClasses; I;) {
114+
--I;
106115
PerClass *C = &PerClassArray[I];
107116
while (C->Count > 0)
108117
drain(C, I);
109118
}
119+
DCHECK(isEmpty());
110120
}
111121

112122
TransferBatch *createBatch(uptr ClassId, void *B) {

compiler-rt/lib/scudo/standalone/tests/combined_test.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,14 @@ template <class Config> static void testAllocator() {
311311
EXPECT_NE(Stats.find("Stats: SizeClassAllocator"), std::string::npos);
312312
EXPECT_NE(Stats.find("Stats: MapAllocator"), std::string::npos);
313313
EXPECT_NE(Stats.find("Stats: Quarantine"), std::string::npos);
314+
315+
bool UnlockRequired;
316+
auto *TSD = Allocator->getTSDRegistry()->getTSDAndLock(&UnlockRequired);
317+
EXPECT_TRUE(!TSD->Cache.isEmpty());
318+
TSD->Cache.drain();
319+
EXPECT_TRUE(TSD->Cache.isEmpty());
320+
if (UnlockRequired)
321+
TSD->unlock();
314322
}
315323

316324
// Test that multiple instantiations of the allocator have not messed up the

0 commit comments

Comments
 (0)