1 /* 2 * Copyright 2016 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 "Test.h" 9 #include "SkArenaAlloc.h" 10 #include "SkRefCnt.h" 11 12 namespace { 13 14 static int created, destroyed; 15 16 struct Foo { 17 Foo() : x(-2), y(-3.0f) { created++; } 18 Foo(int X, float Y) : x(X), y(Y) { created++; } 19 ~Foo() { destroyed++; } 20 21 int x; 22 float y; 23 }; 24 25 struct Big { 26 Big() {} 27 uint32_t array[128]; 28 }; 29 30 struct Node { 31 Node(Node* n) : next(n) { created++; } 32 ~Node() { 33 destroyed++; 34 if (next) { 35 next->~Node(); 36 } 37 } 38 Node *next; 39 }; 40 41 struct Start { 42 ~Start() { 43 if (start) { 44 start->~Node(); 45 } 46 } 47 Node* start; 48 }; 49 50 struct FooRefCnt : public SkRefCnt { 51 FooRefCnt() : x(-2), y(-3.0f) { created++; } 52 FooRefCnt(int X, float Y) : x(X), y(Y) { created++; } 53 ~FooRefCnt() { destroyed++; } 54 55 int x; 56 float y; 57 }; 58 59 } 60 61 struct WithDtor { 62 ~WithDtor() { } 63 }; 64 65 DEF_TEST(ArenaAlloc, r) { 66 67 { 68 created = 0; 69 destroyed = 0; 70 71 SkArenaAlloc arena{0}; 72 REPORTER_ASSERT(r, *arena.make<int>(3) == 3); 73 Foo* foo = arena.make<Foo>(3, 4.0f); 74 REPORTER_ASSERT(r, foo->x == 3); 75 REPORTER_ASSERT(r, foo->y == 4.0f); 76 REPORTER_ASSERT(r, created == 1); 77 REPORTER_ASSERT(r, destroyed == 0); 78 arena.makeArrayDefault<int>(10); 79 int* zeroed = arena.makeArray<int>(10); 80 for (int i = 0; i < 10; i++) { 81 REPORTER_ASSERT(r, zeroed[i] == 0); 82 } 83 Foo* fooArray = arena.makeArrayDefault<Foo>(10); 84 REPORTER_ASSERT(r, fooArray[3].x == -2); 85 REPORTER_ASSERT(r, fooArray[4].y == -3.0f); 86 REPORTER_ASSERT(r, created == 11); 87 REPORTER_ASSERT(r, destroyed == 0); 88 arena.make<typename std::aligned_storage<10,8>::type>(); 89 } 90 REPORTER_ASSERT(r, created == 11); 91 REPORTER_ASSERT(r, destroyed == 11); 92 93 { 94 created = 0; 95 destroyed = 0; 96 SkSTArenaAlloc<64> arena; 97 98 REPORTER_ASSERT(r, *arena.make<int>(3) == 3); 99 Foo* foo = arena.make<Foo>(3, 4.0f); 100 REPORTER_ASSERT(r, foo->x == 3); 101 REPORTER_ASSERT(r, foo->y == 4.0f); 102 REPORTER_ASSERT(r, created == 1); 103 REPORTER_ASSERT(r, destroyed == 0); 104 arena.makeArrayDefault<int>(10); 105 int* zeroed = arena.makeArray<int>(10); 106 for (int i = 0; i < 10; i++) { 107 REPORTER_ASSERT(r, zeroed[i] == 0); 108 } 109 Foo* fooArray = arena.makeArrayDefault<Foo>(10); 110 REPORTER_ASSERT(r, fooArray[3].x == -2); 111 REPORTER_ASSERT(r, fooArray[4].y == -3.0f); 112 REPORTER_ASSERT(r, created == 11); 113 REPORTER_ASSERT(r, destroyed == 0); 114 arena.make<typename std::aligned_storage<10,8>::type>(); 115 } 116 REPORTER_ASSERT(r, created == 11); 117 REPORTER_ASSERT(r, destroyed == 11); 118 119 { 120 created = 0; 121 destroyed = 0; 122 std::unique_ptr<char[]> block{new char[1024]}; 123 SkArenaAlloc arena{block.get(), 1024, 0}; 124 125 REPORTER_ASSERT(r, *arena.make<int>(3) == 3); 126 Foo* foo = arena.make<Foo>(3, 4.0f); 127 REPORTER_ASSERT(r, foo->x == 3); 128 REPORTER_ASSERT(r, foo->y == 4.0f); 129 REPORTER_ASSERT(r, created == 1); 130 REPORTER_ASSERT(r, destroyed == 0); 131 arena.makeArrayDefault<int>(10); 132 int* zeroed = arena.makeArray<int>(10); 133 for (int i = 0; i < 10; i++) { 134 REPORTER_ASSERT(r, zeroed[i] == 0); 135 } 136 Foo* fooArray = arena.makeArrayDefault<Foo>(10); 137 REPORTER_ASSERT(r, fooArray[3].x == -2); 138 REPORTER_ASSERT(r, fooArray[4].y == -3.0f); 139 REPORTER_ASSERT(r, created == 11); 140 REPORTER_ASSERT(r, destroyed == 0); 141 arena.make<typename std::aligned_storage<10,8>::type>(); 142 } 143 REPORTER_ASSERT(r, created == 11); 144 REPORTER_ASSERT(r, destroyed == 11); 145 146 { 147 SkSTArenaAlloc<64> arena; 148 arena.makeArrayDefault<char>(256); 149 arena.reset(); 150 arena.reset(); 151 } 152 153 { 154 created = 0; 155 destroyed = 0; 156 SkSTArenaAlloc<64> arena; 157 158 Start start; 159 Node* current = nullptr; 160 for (int i = 0; i < 128; i++) { 161 uint64_t* temp = arena.makeArrayDefault<uint64_t>(sizeof(Node) / sizeof(Node*)); 162 current = new (temp)Node(current); 163 } 164 start.start = current; 165 } 166 167 REPORTER_ASSERT(r, created == 128); 168 REPORTER_ASSERT(r, destroyed == 128); 169 170 { 171 created = 0; 172 destroyed = 0; 173 SkSTArenaAlloc<64> arena; 174 175 sk_sp<FooRefCnt> f = arena.makeSkSp<FooRefCnt>(4, 5.0f); 176 REPORTER_ASSERT(r, f->x == 4); 177 REPORTER_ASSERT(r, f->y == 5.0f); 178 REPORTER_ASSERT(r, created == 1); 179 REPORTER_ASSERT(r, destroyed == 0); 180 } 181 REPORTER_ASSERT(r, created == 1); 182 REPORTER_ASSERT(r, destroyed == 1); 183 } 184