Skip to content

Commit f07b10b

Browse files
authored
[Support] Recycler: Match dealloc size and enforce min size (#121889)
Address sanitizer found mismatching deallocation size in Recycler.
1 parent f22441c commit f07b10b

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

llvm/include/llvm/Support/Recycler.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class Recycler {
7272
void clear(AllocatorType &Allocator) {
7373
while (FreeList) {
7474
T *t = reinterpret_cast<T *>(pop_val());
75-
Allocator.Deallocate(t);
75+
Allocator.Deallocate(t, Size, Align);
7676
}
7777
}
7878

@@ -89,6 +89,8 @@ class Recycler {
8989
"Recycler allocation alignment is less than object align!");
9090
static_assert(sizeof(SubClass) <= Size,
9191
"Recycler allocation size is less than object size!");
92+
static_assert(Size >= sizeof(FreeNode) &&
93+
"Recycler allocation size must be at least sizeof(FreeNode)");
9294
return FreeList ? reinterpret_cast<SubClass *>(pop_val())
9395
: static_cast<SubClass *>(Allocator.Allocate(Size, Align));
9496
}

llvm/unittests/Support/RecyclerTest.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ using namespace llvm;
1414

1515
namespace {
1616

17+
struct Object1 {
18+
char Data[1];
19+
};
20+
1721
struct Object8 {
1822
char Data[8];
1923
};
@@ -22,12 +26,32 @@ class DecoratedMallocAllocator : public MallocAllocator {
2226
public:
2327
int DeallocCount = 0;
2428

29+
void Deallocate(const void *Ptr, size_t Size, size_t Alignment) {
30+
DeallocCount++;
31+
MallocAllocator::Deallocate(Ptr, Size, Alignment);
32+
}
33+
2534
template <typename T> void Deallocate(T *Ptr) {
2635
DeallocCount++;
2736
MallocAllocator::Deallocate(Ptr);
2837
}
2938
};
3039

40+
TEST(RecyclerTest, RecycleAllocation) {
41+
DecoratedMallocAllocator Allocator;
42+
// Recycler needs size to be atleast 8 bytes.
43+
Recycler<Object1, 8, 8> R;
44+
Object1 *A1 = R.Allocate(Allocator);
45+
Object1 *A2 = R.Allocate(Allocator);
46+
R.Deallocate(Allocator, A2);
47+
Object1 *A3 = R.Allocate(Allocator);
48+
EXPECT_EQ(A2, A3); // reuse the deallocated object.
49+
R.Deallocate(Allocator, A1);
50+
R.Deallocate(Allocator, A3);
51+
R.clear(Allocator); // Should deallocate A1 and A3.
52+
EXPECT_EQ(Allocator.DeallocCount, 2);
53+
}
54+
3155
TEST(RecyclerTest, MoveConstructor) {
3256
DecoratedMallocAllocator Allocator;
3357
Recycler<Object8> R;

0 commit comments

Comments
 (0)