1*f4a2713aSLionel Sambuc //===--- unittest/Support/ArrayRecyclerTest.cpp ---------------------------===//
2*f4a2713aSLionel Sambuc //
3*f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4*f4a2713aSLionel Sambuc //
5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7*f4a2713aSLionel Sambuc //
8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9*f4a2713aSLionel Sambuc
10*f4a2713aSLionel Sambuc #include "llvm/Support/ArrayRecycler.h"
11*f4a2713aSLionel Sambuc #include "llvm/Support/Allocator.h"
12*f4a2713aSLionel Sambuc #include "gtest/gtest.h"
13*f4a2713aSLionel Sambuc #include <cstdlib>
14*f4a2713aSLionel Sambuc
15*f4a2713aSLionel Sambuc using namespace llvm;
16*f4a2713aSLionel Sambuc
17*f4a2713aSLionel Sambuc namespace {
18*f4a2713aSLionel Sambuc
19*f4a2713aSLionel Sambuc struct Object {
20*f4a2713aSLionel Sambuc int Num;
21*f4a2713aSLionel Sambuc Object *Other;
22*f4a2713aSLionel Sambuc };
23*f4a2713aSLionel Sambuc typedef ArrayRecycler<Object> ARO;
24*f4a2713aSLionel Sambuc
TEST(ArrayRecyclerTest,Capacity)25*f4a2713aSLionel Sambuc TEST(ArrayRecyclerTest, Capacity) {
26*f4a2713aSLionel Sambuc // Capacity size should never be 0.
27*f4a2713aSLionel Sambuc ARO::Capacity Cap = ARO::Capacity::get(0);
28*f4a2713aSLionel Sambuc EXPECT_LT(0u, Cap.getSize());
29*f4a2713aSLionel Sambuc
30*f4a2713aSLionel Sambuc size_t PrevSize = Cap.getSize();
31*f4a2713aSLionel Sambuc for (unsigned N = 1; N != 100; ++N) {
32*f4a2713aSLionel Sambuc Cap = ARO::Capacity::get(N);
33*f4a2713aSLionel Sambuc EXPECT_LE(N, Cap.getSize());
34*f4a2713aSLionel Sambuc if (PrevSize >= N)
35*f4a2713aSLionel Sambuc EXPECT_EQ(PrevSize, Cap.getSize());
36*f4a2713aSLionel Sambuc else
37*f4a2713aSLionel Sambuc EXPECT_LT(PrevSize, Cap.getSize());
38*f4a2713aSLionel Sambuc PrevSize = Cap.getSize();
39*f4a2713aSLionel Sambuc }
40*f4a2713aSLionel Sambuc
41*f4a2713aSLionel Sambuc // Check that the buckets are monotonically increasing.
42*f4a2713aSLionel Sambuc Cap = ARO::Capacity::get(0);
43*f4a2713aSLionel Sambuc PrevSize = Cap.getSize();
44*f4a2713aSLionel Sambuc for (unsigned N = 0; N != 20; ++N) {
45*f4a2713aSLionel Sambuc Cap = Cap.getNext();
46*f4a2713aSLionel Sambuc EXPECT_LT(PrevSize, Cap.getSize());
47*f4a2713aSLionel Sambuc PrevSize = Cap.getSize();
48*f4a2713aSLionel Sambuc }
49*f4a2713aSLionel Sambuc }
50*f4a2713aSLionel Sambuc
TEST(ArrayRecyclerTest,Basics)51*f4a2713aSLionel Sambuc TEST(ArrayRecyclerTest, Basics) {
52*f4a2713aSLionel Sambuc BumpPtrAllocator Allocator;
53*f4a2713aSLionel Sambuc ArrayRecycler<Object> DUT;
54*f4a2713aSLionel Sambuc
55*f4a2713aSLionel Sambuc ARO::Capacity Cap = ARO::Capacity::get(8);
56*f4a2713aSLionel Sambuc Object *A1 = DUT.allocate(Cap, Allocator);
57*f4a2713aSLionel Sambuc A1[0].Num = 21;
58*f4a2713aSLionel Sambuc A1[7].Num = 17;
59*f4a2713aSLionel Sambuc
60*f4a2713aSLionel Sambuc Object *A2 = DUT.allocate(Cap, Allocator);
61*f4a2713aSLionel Sambuc A2[0].Num = 121;
62*f4a2713aSLionel Sambuc A2[7].Num = 117;
63*f4a2713aSLionel Sambuc
64*f4a2713aSLionel Sambuc Object *A3 = DUT.allocate(Cap, Allocator);
65*f4a2713aSLionel Sambuc A3[0].Num = 221;
66*f4a2713aSLionel Sambuc A3[7].Num = 217;
67*f4a2713aSLionel Sambuc
68*f4a2713aSLionel Sambuc EXPECT_EQ(21, A1[0].Num);
69*f4a2713aSLionel Sambuc EXPECT_EQ(17, A1[7].Num);
70*f4a2713aSLionel Sambuc EXPECT_EQ(121, A2[0].Num);
71*f4a2713aSLionel Sambuc EXPECT_EQ(117, A2[7].Num);
72*f4a2713aSLionel Sambuc EXPECT_EQ(221, A3[0].Num);
73*f4a2713aSLionel Sambuc EXPECT_EQ(217, A3[7].Num);
74*f4a2713aSLionel Sambuc
75*f4a2713aSLionel Sambuc DUT.deallocate(Cap, A2);
76*f4a2713aSLionel Sambuc
77*f4a2713aSLionel Sambuc // Check that deallocation didn't clobber anything.
78*f4a2713aSLionel Sambuc EXPECT_EQ(21, A1[0].Num);
79*f4a2713aSLionel Sambuc EXPECT_EQ(17, A1[7].Num);
80*f4a2713aSLionel Sambuc EXPECT_EQ(221, A3[0].Num);
81*f4a2713aSLionel Sambuc EXPECT_EQ(217, A3[7].Num);
82*f4a2713aSLionel Sambuc
83*f4a2713aSLionel Sambuc // Verify recycling.
84*f4a2713aSLionel Sambuc Object *A2x = DUT.allocate(Cap, Allocator);
85*f4a2713aSLionel Sambuc EXPECT_EQ(A2, A2x);
86*f4a2713aSLionel Sambuc
87*f4a2713aSLionel Sambuc DUT.deallocate(Cap, A2x);
88*f4a2713aSLionel Sambuc DUT.deallocate(Cap, A1);
89*f4a2713aSLionel Sambuc DUT.deallocate(Cap, A3);
90*f4a2713aSLionel Sambuc
91*f4a2713aSLionel Sambuc // Objects are not required to be recycled in reverse deallocation order, but
92*f4a2713aSLionel Sambuc // that is what the current implementation does.
93*f4a2713aSLionel Sambuc Object *A3x = DUT.allocate(Cap, Allocator);
94*f4a2713aSLionel Sambuc EXPECT_EQ(A3, A3x);
95*f4a2713aSLionel Sambuc Object *A1x = DUT.allocate(Cap, Allocator);
96*f4a2713aSLionel Sambuc EXPECT_EQ(A1, A1x);
97*f4a2713aSLionel Sambuc Object *A2y = DUT.allocate(Cap, Allocator);
98*f4a2713aSLionel Sambuc EXPECT_EQ(A2, A2y);
99*f4a2713aSLionel Sambuc
100*f4a2713aSLionel Sambuc // Back to allocation from the BumpPtrAllocator.
101*f4a2713aSLionel Sambuc Object *A4 = DUT.allocate(Cap, Allocator);
102*f4a2713aSLionel Sambuc EXPECT_NE(A1, A4);
103*f4a2713aSLionel Sambuc EXPECT_NE(A2, A4);
104*f4a2713aSLionel Sambuc EXPECT_NE(A3, A4);
105*f4a2713aSLionel Sambuc
106*f4a2713aSLionel Sambuc DUT.clear(Allocator);
107*f4a2713aSLionel Sambuc }
108*f4a2713aSLionel Sambuc
109*f4a2713aSLionel Sambuc } // end anonymous namespace
110