1 /* 2 * Copyright 2014 Google, Inc 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkSmallAllocator.h" 9 #include "SkTypes.h" 10 #include "Test.h" 11 12 class CountingClass { 13 public: 14 CountingClass() { 15 kCount++; 16 } 17 18 ~CountingClass() { 19 kCount--; 20 } 21 22 static int GetCount() { return kCount; } 23 24 private: 25 static int kCount; 26 }; 27 28 int CountingClass::kCount; 29 30 template<uint32_t kMaxObjects, size_t kBytes> void test_allocator(skiatest::Reporter* reporter) { 31 { 32 SkSmallAllocator<kMaxObjects, kBytes> alloc; 33 for (uint32_t i = 0; i < kMaxObjects; ++i) { 34 CountingClass* c = alloc.template createT<CountingClass>(); 35 REPORTER_ASSERT(reporter, c != nullptr); 36 REPORTER_ASSERT(reporter, CountingClass::GetCount() == static_cast<int>(i+1)); 37 } 38 } 39 REPORTER_ASSERT(reporter, CountingClass::GetCount() == 0); 40 } 41 42 // Tests that ensure that the destructor is called, whether the objects 43 // were created in fStorage or on the heap. 44 DEF_TEST(SmallAllocator_destructor, reporter) { 45 // Four times as many bytes as objects will never require any heap 46 // allocations (since SkAlign4(sizeof(CountingClass)) == 4 and the allocator 47 // will stop once it reaches kMaxObjects). 48 test_allocator<5, 20>(reporter); 49 test_allocator<10, 40>(reporter); 50 test_allocator<20, 80>(reporter); 51 52 #ifndef SK_DEBUG 53 // Allowing less bytes than objects means some will be allocated on the 54 // heap. Don't run these in debug where we assert. 55 test_allocator<50, 20>(reporter); 56 test_allocator<100, 20>(reporter); 57 #endif 58 } 59 60 class Dummy { 61 }; 62 63 class DummyContainer { 64 public: 65 explicit DummyContainer(Dummy* d) 66 :fDummy(d) 67 {} 68 69 Dummy* getDummy() const { return fDummy; } 70 71 private: 72 Dummy* fDummy; 73 }; 74 75 // Test that using a createT with a constructor taking a pointer as a 76 // parameter works as expected. 77 DEF_TEST(SmallAllocator_pointer, reporter) { 78 SkSmallAllocator<1, 8> alloc; 79 Dummy d; 80 DummyContainer* container = alloc.createT<DummyContainer>(&d); 81 REPORTER_ASSERT(reporter, container != nullptr); 82 REPORTER_ASSERT(reporter, container->getDummy() == &d); 83 } 84