diff options
author | Reid Kleckner <reid@kleckner.net> | 2009-07-25 21:26:02 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2009-07-25 21:26:02 +0000 |
commit | 7d509134dcec17f6094032196b21af5c67943f0f (patch) | |
tree | 956480aceff06b421f0ab357919fd759843b3712 /unittests | |
parent | b4fc419d83bc4afc8ce5a204dd226d5ae58f5896 (diff) | |
download | external_llvm-7d509134dcec17f6094032196b21af5c67943f0f.zip external_llvm-7d509134dcec17f6094032196b21af5c67943f0f.tar.gz external_llvm-7d509134dcec17f6094032196b21af5c67943f0f.tar.bz2 |
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
Diffstat (limited to 'unittests')
-rw-r--r-- | unittests/Support/AllocatorTest.cpp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/unittests/Support/AllocatorTest.cpp b/unittests/Support/AllocatorTest.cpp index cc3296a..463760d 100644 --- a/unittests/Support/AllocatorTest.cpp +++ b/unittests/Support/AllocatorTest.cpp @@ -10,6 +10,7 @@ #include "llvm/Support/Allocator.h" #include "gtest/gtest.h" +#include <cstdlib> using namespace llvm; @@ -92,4 +93,51 @@ TEST(AllocatorTest, TestOverflow) { EXPECT_EQ(2U, Alloc.GetNumSlabs()); } +// Mock slab allocator that returns slabs aligned on 4096 bytes. There is no +// easy portable way to do this, so this is kind of a hack. +class MockSlabAllocator : public SlabAllocator { + MemSlab *LastSlab; + +public: + virtual ~MockSlabAllocator() { } + + virtual MemSlab *Allocate(size_t Size) { + // Allocate space for the alignment, the slab, and a void* that goes right + // before the slab. + size_t Alignment = 4096; + void *MemBase = malloc(Size + Alignment - 1 + sizeof(void*)); + + // Make the slab. + MemSlab *Slab = (MemSlab*)(((uintptr_t)MemBase + Alignment - 1) & + ~(uintptr_t)(Alignment - 1)); + Slab->Size = Size; + Slab->NextPtr = 0; + + // Hold a pointer to the base so we can free the whole malloced block. + ((void**)Slab)[-1] = MemBase; + + LastSlab = Slab; + return Slab; + } + + virtual void Deallocate(MemSlab *Slab) { + free(((void**)Slab)[-1]); + } + + MemSlab *GetLastSlab() { + return LastSlab; + } +}; + +// Allocate a large-ish block with a really large alignment so that the +// allocator will think that it has space, but after it does the alignment it +// will not. +TEST(AllocatorTest, TestBigAlignment) { + MockSlabAllocator SlabAlloc; + BumpPtrAllocator Alloc(4096, 4096, SlabAlloc); + uintptr_t Ptr = (uintptr_t)Alloc.Allocate(3000, 2048); + MemSlab *Slab = SlabAlloc.GetLastSlab(); + EXPECT_LE(Ptr + 3000, ((uintptr_t)Slab) + Slab->Size); +} + } // anonymous namespace |