X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=unittests%2FSupport%2FAllocatorTest.cpp;h=cb9fa430369b7231dde61507b31dff6da9314a8f;hb=7172b38af7ed5d1c1e2c97fadfb0ae0c19aff816;hp=139270b185f71c644c5c9bbaab2077aa1068f515;hpb=95eb3ad353460c6987a9d1e03a3e3e12c75b4059;p=oota-llvm.git diff --git a/unittests/Support/AllocatorTest.cpp b/unittests/Support/AllocatorTest.cpp index 139270b185f..cb9fa430369 100644 --- a/unittests/Support/AllocatorTest.cpp +++ b/unittests/Support/AllocatorTest.cpp @@ -8,8 +8,8 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/Allocator.h" - #include "gtest/gtest.h" +#include using namespace llvm; @@ -58,4 +58,93 @@ TEST(AllocatorTest, TestReset) { EXPECT_EQ(2U, Alloc.GetNumSlabs()); } +// Test some allocations at varying alignments. +TEST(AllocatorTest, TestAlignment) { + BumpPtrAllocator Alloc; + uintptr_t a; + a = (uintptr_t)Alloc.Allocate(1, 2); + EXPECT_EQ(0U, a & 1); + a = (uintptr_t)Alloc.Allocate(1, 4); + EXPECT_EQ(0U, a & 3); + a = (uintptr_t)Alloc.Allocate(1, 8); + EXPECT_EQ(0U, a & 7); + a = (uintptr_t)Alloc.Allocate(1, 16); + EXPECT_EQ(0U, a & 15); + a = (uintptr_t)Alloc.Allocate(1, 32); + EXPECT_EQ(0U, a & 31); + a = (uintptr_t)Alloc.Allocate(1, 64); + EXPECT_EQ(0U, a & 63); + a = (uintptr_t)Alloc.Allocate(1, 128); + EXPECT_EQ(0U, a & 127); +} + +// Test allocating just over the slab size. This tests a bug where before the +// allocator incorrectly calculated the buffer end pointer. +TEST(AllocatorTest, TestOverflow) { + BumpPtrAllocator Alloc(4096, 4096); + + // Fill the slab right up until the end pointer. + Alloc.Allocate(4096 - sizeof(MemSlab), 0); + EXPECT_EQ(1U, Alloc.GetNumSlabs()); + + // If we don't allocate a new slab, then we will have overflowed. + Alloc.Allocate(1, 0); + EXPECT_EQ(2U, Alloc.GetNumSlabs()); +} + +// Test allocating with a size larger than the initial slab size. +TEST(AllocatorTest, TestSmallSlabSize) { + BumpPtrAllocator Alloc(128); + + Alloc.Allocate(200, 0); + 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+sizeof(void*)+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