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