//===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator tests ---===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/Allocator.h"
#include "gtest/gtest.h"
#include <cstdlib>

using namespace llvm;

namespace {

TEST(AllocatorTest, Basics) {
  BumpPtrAllocator Alloc;
  int *a = (int*)Alloc.Allocate(sizeof(int), alignof(int));
  int *b = (int*)Alloc.Allocate(sizeof(int) * 10, alignof(int));
  int *c = (int*)Alloc.Allocate(sizeof(int), alignof(int));
  *a = 1;
  b[0] = 2;
  b[9] = 2;
  *c = 3;
  EXPECT_EQ(1, *a);
  EXPECT_EQ(2, b[0]);
  EXPECT_EQ(2, b[9]);
  EXPECT_EQ(3, *c);
  EXPECT_EQ(1U, Alloc.GetNumSlabs());

  BumpPtrAllocator Alloc2 = std::move(Alloc);
  EXPECT_EQ(0U, Alloc.GetNumSlabs());
  EXPECT_EQ(1U, Alloc2.GetNumSlabs());

  // Make sure the old pointers still work. These are especially interesting
  // under ASan or Valgrind.
  EXPECT_EQ(1, *a);
  EXPECT_EQ(2, b[0]);
  EXPECT_EQ(2, b[9]);
  EXPECT_EQ(3, *c);

  Alloc = std::move(Alloc2);
  EXPECT_EQ(0U, Alloc2.GetNumSlabs());
  EXPECT_EQ(1U, Alloc.GetNumSlabs());
}

// Allocate enough bytes to create three slabs.
TEST(AllocatorTest, ThreeSlabs) {
  BumpPtrAllocator Alloc;
  Alloc.Allocate(3000, 1);
  EXPECT_EQ(1U, Alloc.GetNumSlabs());
  Alloc.Allocate(3000, 1);
  EXPECT_EQ(2U, Alloc.GetNumSlabs());
  Alloc.Allocate(3000, 1);
  EXPECT_EQ(3U, Alloc.GetNumSlabs());
}

// Allocate enough bytes to create two slabs, reset the allocator, and do it
// again.
TEST(AllocatorTest, TestReset) {
  BumpPtrAllocator Alloc;

  // Allocate something larger than the SizeThreshold=4096.
  (void)Alloc.Allocate(5000, 1);
  Alloc.Reset();
  // Calling Reset should free all CustomSizedSlabs.
  EXPECT_EQ(0u, Alloc.GetNumSlabs());

  Alloc.Allocate(3000, 1);
  EXPECT_EQ(1U, Alloc.GetNumSlabs());
  Alloc.Allocate(3000, 1);
  EXPECT_EQ(2U, Alloc.GetNumSlabs());
  Alloc.Reset();
  EXPECT_EQ(1U, Alloc.GetNumSlabs());
  Alloc.Allocate(3000, 1);
  EXPECT_EQ(1U, Alloc.GetNumSlabs());
  Alloc.Allocate(3000, 1);
  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;

  // Fill the slab right up until the end pointer.
  Alloc.Allocate(4096, 1);
  EXPECT_EQ(1U, Alloc.GetNumSlabs());

  // If we don't allocate a new slab, then we will have overflowed.
  Alloc.Allocate(1, 1);
  EXPECT_EQ(2U, Alloc.GetNumSlabs());
}

// Test allocating with a size larger than the initial slab size.
TEST(AllocatorTest, TestSmallSlabSize) {
  BumpPtrAllocator Alloc;

  Alloc.Allocate(8000, 1);
  EXPECT_EQ(1U, Alloc.GetNumSlabs());
}

// Test requesting alignment that goes past the end of the current slab.
TEST(AllocatorTest, TestAlignmentPastSlab) {
  BumpPtrAllocator Alloc;
  Alloc.Allocate(4095, 1);

  // Aligning the current slab pointer is likely to move it past the end of the
  // slab, which would confuse any unsigned comparisons with the difference of
  // the end pointer and the aligned pointer.
  Alloc.Allocate(1024, 8192);

  EXPECT_EQ(2U, Alloc.GetNumSlabs());
}

// Test allocating with a decreased growth delay.
TEST(AllocatorTest, TestFasterSlabGrowthDelay) {
  const size_t SlabSize = 4096;
  // Decrease the growth delay to double the slab size every slab.
  const size_t GrowthDelay = 1;
  BumpPtrAllocatorImpl<MallocAllocator, SlabSize, SlabSize, GrowthDelay> Alloc;
  // Disable the red zone for this test. The additional bytes allocated for the
  // red zone would change the allocation numbers we check below.
  Alloc.setRedZoneSize(0);

  Alloc.Allocate(SlabSize, 1);
  EXPECT_EQ(SlabSize, Alloc.getTotalMemory());
  // We hit our growth delay with the previous allocation so the next
  // allocation should get a twice as large slab.
  Alloc.Allocate(SlabSize, 1);
  EXPECT_EQ(SlabSize * 3, Alloc.getTotalMemory());
  Alloc.Allocate(SlabSize, 1);
  EXPECT_EQ(SlabSize * 3, Alloc.getTotalMemory());

  // Both slabs are full again and hit the growth delay again, so the
  // next allocation should again get a slab with four times the size of the
  // original slab size. In total we now should have a memory size of:
  // 1 + 2 + 4 * SlabSize.
  Alloc.Allocate(SlabSize, 1);
  EXPECT_EQ(SlabSize * 7, Alloc.getTotalMemory());
}

// Test allocating with a increased growth delay.
TEST(AllocatorTest, TestSlowerSlabGrowthDelay) {
  const size_t SlabSize = 16;
  // Increase the growth delay to only double the slab size every 256 slabs.
  const size_t GrowthDelay = 256;
  BumpPtrAllocatorImpl<MallocAllocator, SlabSize, SlabSize, GrowthDelay> Alloc;
  // Disable the red zone for this test. The additional bytes allocated for the
  // red zone would change the allocation numbers we check below.
  Alloc.setRedZoneSize(0);

  // Allocate 256 slabs. We should keep getting slabs with the original size
  // as we haven't hit our growth delay on the last allocation.
  for (std::size_t i = 0; i < GrowthDelay; ++i)
    Alloc.Allocate(SlabSize, 1);
  EXPECT_EQ(SlabSize * GrowthDelay, Alloc.getTotalMemory());
  // Allocate another slab. This time we should get another slab allocated
  // that is twice as large as the normal slab size.
  Alloc.Allocate(SlabSize, 1);
  EXPECT_EQ(SlabSize * GrowthDelay + SlabSize * 2, Alloc.getTotalMemory());
}

// 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 {
  static size_t LastSlabSize;

public:
  ~MockSlabAllocator() { }

  void *Allocate(size_t Size, size_t /*Alignment*/) {
    // Allocate space for the alignment, the slab, and a void* that goes right
    // before the slab.
    Align Alignment(4096);
    void *MemBase = safe_malloc(Size + Alignment.value() - 1 + sizeof(void *));

    // Find the slab start.
    void *Slab = (void *)alignAddr((char*)MemBase + sizeof(void *), Alignment);

    // Hold a pointer to the base so we can free the whole malloced block.
    ((void**)Slab)[-1] = MemBase;

    LastSlabSize = Size;
    return Slab;
  }

  void Deallocate(void *Slab, size_t /*Size*/, size_t /*Alignment*/) {
    free(((void**)Slab)[-1]);
  }

  static size_t GetLastSlabSize() { return LastSlabSize; }
};

size_t MockSlabAllocator::LastSlabSize = 0;

// 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) {
  BumpPtrAllocatorImpl<MockSlabAllocator> Alloc;

  // First allocate a tiny bit to ensure we have to re-align things.
  (void)Alloc.Allocate(1, 1);

  // Now the big chunk with a big alignment.
  (void)Alloc.Allocate(3000, 2048);

  // We test that the last slab size is not the default 4096 byte slab, but
  // rather a custom sized slab that is larger.
  EXPECT_GT(MockSlabAllocator::GetLastSlabSize(), 4096u);
}

}  // anonymous namespace
