llvm.org GIT mirror llvm / 7d50913
Added a test and fixed a bug in BumpPtrAllocator relating to large alignment values. Hopefully this fixes PR4622. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77088 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner 10 years ago
2 changed file(s) with 50 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
9494 }
9595
9696 // If Size is really big, allocate a separate slab for it.
97 if (Size > SizeThreshold) {
98 size_t PaddedSize = Size + sizeof(MemSlab) + Alignment - 1;
97 size_t PaddedSize = Size + sizeof(MemSlab) + Alignment - 1;
98 if (PaddedSize > SizeThreshold) {
9999 MemSlab *NewSlab = Allocator.Allocate(PaddedSize);
100100
101101 // Put the new slab after the current slab, since we are not allocating
99 #include "llvm/Support/Allocator.h"
1010
1111 #include "gtest/gtest.h"
12 #include
1213
1314 using namespace llvm;
1415
9192 EXPECT_EQ(2U, Alloc.GetNumSlabs());
9293 }
9394
95 // Mock slab allocator that returns slabs aligned on 4096 bytes. There is no
96 // easy portable way to do this, so this is kind of a hack.
97 class MockSlabAllocator : public SlabAllocator {
98 MemSlab *LastSlab;
99
100 public:
101 virtual ~MockSlabAllocator() { }
102
103 virtual MemSlab *Allocate(size_t Size) {
104 // Allocate space for the alignment, the slab, and a void* that goes right
105 // before the slab.
106 size_t Alignment = 4096;
107 void *MemBase = malloc(Size + Alignment - 1 + sizeof(void*));
108
109 // Make the slab.
110 MemSlab *Slab = (MemSlab*)(((uintptr_t)MemBase + Alignment - 1) &
111 ~(uintptr_t)(Alignment - 1));
112 Slab->Size = Size;
113 Slab->NextPtr = 0;
114
115 // Hold a pointer to the base so we can free the whole malloced block.
116 ((void**)Slab)[-1] = MemBase;
117
118 LastSlab = Slab;
119 return Slab;
120 }
121
122 virtual void Deallocate(MemSlab *Slab) {
123 free(((void**)Slab)[-1]);
124 }
125
126 MemSlab *GetLastSlab() {
127 return LastSlab;
128 }
129 };
130
131 // Allocate a large-ish block with a really large alignment so that the
132 // allocator will think that it has space, but after it does the alignment it
133 // will not.
134 TEST(AllocatorTest, TestBigAlignment) {
135 MockSlabAllocator SlabAlloc;
136 BumpPtrAllocator Alloc(4096, 4096, SlabAlloc);
137 uintptr_t Ptr = (uintptr_t)Alloc.Allocate(3000, 2048);
138 MemSlab *Slab = SlabAlloc.GetLastSlab();
139 EXPECT_LE(Ptr + 3000, ((uintptr_t)Slab) + Slab->Size);
140 }
141
94142 } // anonymous namespace