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