| //===--- unittest/Support/ArrayRecyclerTest.cpp ---------------------------===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "llvm/Support/ArrayRecycler.h" | |
| #include "llvm/Support/Allocator.h" | |
| #include "gtest/gtest.h" | |
| #include <cstdlib> | |
| using namespace llvm; | |
| namespace { | |
| struct Object { | |
| int Num; | |
| Object *Other; | |
| }; | |
| typedef ArrayRecycler<Object> ARO; | |
| TEST(ArrayRecyclerTest, Capacity) { | |
| // Capacity size should never be 0. | |
| ARO::Capacity Cap = ARO::Capacity::get(0); | |
| EXPECT_LT(0u, Cap.getSize()); | |
| size_t PrevSize = Cap.getSize(); | |
| for (unsigned N = 1; N != 100; ++N) { | |
| Cap = ARO::Capacity::get(N); | |
| EXPECT_LE(N, Cap.getSize()); | |
| if (PrevSize >= N) | |
| EXPECT_EQ(PrevSize, Cap.getSize()); | |
| else | |
| EXPECT_LT(PrevSize, Cap.getSize()); | |
| PrevSize = Cap.getSize(); | |
| } | |
| // Check that the buckets are monotonically increasing. | |
| Cap = ARO::Capacity::get(0); | |
| PrevSize = Cap.getSize(); | |
| for (unsigned N = 0; N != 20; ++N) { | |
| Cap = Cap.getNext(); | |
| EXPECT_LT(PrevSize, Cap.getSize()); | |
| PrevSize = Cap.getSize(); | |
| } | |
| } | |
| TEST(ArrayRecyclerTest, Basics) { | |
| BumpPtrAllocator Allocator; | |
| ArrayRecycler<Object> DUT; | |
| ARO::Capacity Cap = ARO::Capacity::get(8); | |
| Object *A1 = DUT.allocate(Cap, Allocator); | |
| A1[0].Num = 21; | |
| A1[7].Num = 17; | |
| Object *A2 = DUT.allocate(Cap, Allocator); | |
| A2[0].Num = 121; | |
| A2[7].Num = 117; | |
| Object *A3 = DUT.allocate(Cap, Allocator); | |
| A3[0].Num = 221; | |
| A3[7].Num = 217; | |
| EXPECT_EQ(21, A1[0].Num); | |
| EXPECT_EQ(17, A1[7].Num); | |
| EXPECT_EQ(121, A2[0].Num); | |
| EXPECT_EQ(117, A2[7].Num); | |
| EXPECT_EQ(221, A3[0].Num); | |
| EXPECT_EQ(217, A3[7].Num); | |
| DUT.deallocate(Cap, A2); | |
| // Check that deallocation didn't clobber anything. | |
| EXPECT_EQ(21, A1[0].Num); | |
| EXPECT_EQ(17, A1[7].Num); | |
| EXPECT_EQ(221, A3[0].Num); | |
| EXPECT_EQ(217, A3[7].Num); | |
| // Verify recycling. | |
| Object *A2x = DUT.allocate(Cap, Allocator); | |
| EXPECT_EQ(A2, A2x); | |
| DUT.deallocate(Cap, A2x); | |
| DUT.deallocate(Cap, A1); | |
| DUT.deallocate(Cap, A3); | |
| // Objects are not required to be recycled in reverse deallocation order, but | |
| // that is what the current implementation does. | |
| Object *A3x = DUT.allocate(Cap, Allocator); | |
| EXPECT_EQ(A3, A3x); | |
| Object *A1x = DUT.allocate(Cap, Allocator); | |
| EXPECT_EQ(A1, A1x); | |
| Object *A2y = DUT.allocate(Cap, Allocator); | |
| EXPECT_EQ(A2, A2y); | |
| // Back to allocation from the BumpPtrAllocator. | |
| Object *A4 = DUT.allocate(Cap, Allocator); | |
| EXPECT_NE(A1, A4); | |
| EXPECT_NE(A2, A4); | |
| EXPECT_NE(A3, A4); | |
| DUT.clear(Allocator); | |
| } | |
| } // end anonymous namespace |