xref: /llvm-project/llvm/unittests/Support/RecyclerTest.cpp (revision f07b10b7c4706735c1e206b64da4c43aaf88b6af)
1 //===--- unittest/Support/RecyclerTest.cpp --------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/Support/Recycler.h"
10 #include "llvm/Support/AllocatorBase.h"
11 #include "gtest/gtest.h"
12 
13 using namespace llvm;
14 
15 namespace {
16 
17 struct Object1 {
18   char Data[1];
19 };
20 
21 struct Object8 {
22   char Data[8];
23 };
24 
25 class DecoratedMallocAllocator : public MallocAllocator {
26 public:
27   int DeallocCount = 0;
28 
29   void Deallocate(const void *Ptr, size_t Size, size_t Alignment) {
30     DeallocCount++;
31     MallocAllocator::Deallocate(Ptr, Size, Alignment);
32   }
33 
34   template <typename T> void Deallocate(T *Ptr) {
35     DeallocCount++;
36     MallocAllocator::Deallocate(Ptr);
37   }
38 };
39 
40 TEST(RecyclerTest, RecycleAllocation) {
41   DecoratedMallocAllocator Allocator;
42   // Recycler needs size to be atleast 8 bytes.
43   Recycler<Object1, 8, 8> R;
44   Object1 *A1 = R.Allocate(Allocator);
45   Object1 *A2 = R.Allocate(Allocator);
46   R.Deallocate(Allocator, A2);
47   Object1 *A3 = R.Allocate(Allocator);
48   EXPECT_EQ(A2, A3); // reuse the deallocated object.
49   R.Deallocate(Allocator, A1);
50   R.Deallocate(Allocator, A3);
51   R.clear(Allocator); // Should deallocate A1 and A3.
52   EXPECT_EQ(Allocator.DeallocCount, 2);
53 }
54 
55 TEST(RecyclerTest, MoveConstructor) {
56   DecoratedMallocAllocator Allocator;
57   Recycler<Object8> R;
58   Object8 *A1 = R.Allocate(Allocator);
59   Object8 *A2 = R.Allocate(Allocator);
60   R.Deallocate(Allocator, A1);
61   R.Deallocate(Allocator, A2);
62   Recycler<Object8> R2(std::move(R));
63   Object8 *A3 = R2.Allocate(Allocator);
64   R2.Deallocate(Allocator, A3);
65   R.clear(Allocator); // Should not deallocate anything as it was moved from.
66   EXPECT_EQ(Allocator.DeallocCount, 0);
67   R2.clear(Allocator);
68   EXPECT_EQ(Allocator.DeallocCount, 2);
69 }
70 
71 } // end anonymous namespace
72