Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
ArenaAllocTest.cpp
Go to the documentation of this file.
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
10#include "tests/Test.h"
11
12#include <cstddef>
13#include <cstdint>
14#include <initializer_list>
15#include <limits>
16#include <memory>
17#include <new>
18
19DEF_TEST(ArenaAlloc, r) {
20 static int created = 0,
21 destroyed = 0;
22
23 struct Foo {
24 Foo() : x(-2), y(-3.0f) { created++; }
25 Foo(int X, float Y) : x(X), y(Y) { created++; }
26 ~Foo() { destroyed++; }
27 int x;
28 float y;
29 };
30
31 struct alignas(8) OddAlignment {
32 char buf[10];
33 };
34
35 // Check construction/destruction counts from SkArenaAlloc.
36 created = 0;
37 destroyed = 0;
38 {
39 SkArenaAlloc arena{0};
40 REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
41 Foo* foo = arena.make<Foo>(3, 4.0f);
42 REPORTER_ASSERT(r, foo->x == 3);
43 REPORTER_ASSERT(r, foo->y == 4.0f);
44 REPORTER_ASSERT(r, created == 1);
45 REPORTER_ASSERT(r, destroyed == 0);
46 arena.makeArrayDefault<int>(10);
47 int* zeroed = arena.makeArray<int>(10);
48 for (int i = 0; i < 10; i++) {
49 REPORTER_ASSERT(r, zeroed[i] == 0);
50 }
51 Foo* fooArray = arena.makeArrayDefault<Foo>(10);
52 REPORTER_ASSERT(r, fooArray[3].x == -2);
53 REPORTER_ASSERT(r, fooArray[4].y == -3.0f);
54 REPORTER_ASSERT(r, created == 11);
55 REPORTER_ASSERT(r, destroyed == 0);
56 arena.make<OddAlignment>();
57 }
58 REPORTER_ASSERT(r, created == 11);
59 REPORTER_ASSERT(r, destroyed == 11);
60
61 // Check construction/destruction counts from SkSTArenaAlloc.
62 created = 0;
63 destroyed = 0;
64 {
66 REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
67 Foo* foo = arena.make<Foo>(3, 4.0f);
68 REPORTER_ASSERT(r, foo->x == 3);
69 REPORTER_ASSERT(r, foo->y == 4.0f);
70 REPORTER_ASSERT(r, created == 1);
71 REPORTER_ASSERT(r, destroyed == 0);
72 arena.makeArrayDefault<int>(10);
73 int* zeroed = arena.makeArray<int>(10);
74 for (int i = 0; i < 10; i++) {
75 REPORTER_ASSERT(r, zeroed[i] == 0);
76 }
77 Foo* fooArray = arena.makeArrayDefault<Foo>(10);
78 REPORTER_ASSERT(r, fooArray[3].x == -2);
79 REPORTER_ASSERT(r, fooArray[4].y == -3.0f);
80 REPORTER_ASSERT(r, created == 11);
81 REPORTER_ASSERT(r, destroyed == 0);
82 arena.make<OddAlignment>();
83 }
84 REPORTER_ASSERT(r, created == 11);
85 REPORTER_ASSERT(r, destroyed == 11);
86
87 // Check construction/destruction counts from SkArenaAlloc when passed an initial block.
88 created = 0;
89 destroyed = 0;
90 {
91 std::unique_ptr<char[]> block{new char[1024]};
92 SkArenaAlloc arena{block.get(), 1024, 0};
93 REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
94 Foo* foo = arena.make<Foo>(3, 4.0f);
95 REPORTER_ASSERT(r, foo->x == 3);
96 REPORTER_ASSERT(r, foo->y == 4.0f);
97 REPORTER_ASSERT(r, created == 1);
98 REPORTER_ASSERT(r, destroyed == 0);
99 arena.makeArrayDefault<int>(10);
100 int* zeroed = arena.makeArray<int>(10);
101 for (int i = 0; i < 10; i++) {
102 REPORTER_ASSERT(r, zeroed[i] == 0);
103 }
104 Foo* fooArray = arena.makeArrayDefault<Foo>(10);
105 REPORTER_ASSERT(r, fooArray[3].x == -2);
106 REPORTER_ASSERT(r, fooArray[4].y == -3.0f);
107 REPORTER_ASSERT(r, created == 11);
108 REPORTER_ASSERT(r, destroyed == 0);
109 arena.make<OddAlignment>();
110 }
111 REPORTER_ASSERT(r, created == 11);
112 REPORTER_ASSERT(r, destroyed == 11);
113}
114
115DEF_TEST(ArenaAllocReset, r) {
117 arena.makeArrayDefault<char>(256);
118 arena.reset();
119 arena.reset();
120}
121
122DEF_TEST(ArenaAllocIsEmpty, r) {
123 char storage[1000];
124 for (int arenaSize : {1, 2, 3, 10, 100, 1000}) {
125 for (int alloc1Size : {1, 10, 100, 1000}) {
126 for (int alloc2Size : {1, 10, 100, 1000}) {
127 SkArenaAllocWithReset arena(storage, arenaSize, 1000);
128 REPORTER_ASSERT(r, arena.isEmpty());
129
130 [[maybe_unused]] char* alloc1 = arena.makeArray<char>(alloc1Size);
131 REPORTER_ASSERT(r, !arena.isEmpty());
132
133 [[maybe_unused]] char* alloc2 = arena.makeArray<char>(alloc2Size);
134 REPORTER_ASSERT(r, !arena.isEmpty());
135
136 arena.reset();
137 REPORTER_ASSERT(r, arena.isEmpty());
138 }
139 }
140 }
141}
142
143DEF_TEST(ArenaAllocWithMultipleBlocks, r) {
144 // Make sure that multiple blocks are handled correctly.
145 static int created = 0,
146 destroyed = 0;
147 {
148 struct Node {
149 Node(Node* n) : next(n) { created++; }
150 ~Node() { destroyed++; }
151 Node *next;
152 char filler[64];
153 };
154
155 SkSTArenaAlloc<64> arena;
156 Node* current = nullptr;
157 for (int i = 0; i < 128; i++) {
158 current = arena.make<Node>(current);
159 }
160 }
161 REPORTER_ASSERT(r, created == 128);
162 REPORTER_ASSERT(r, destroyed == 128);
163}
164
165DEF_TEST(ArenaAllocDestructionOrder, r) {
166 // Make sure that objects and blocks are destroyed in the correct order. If they are not,
167 // then there will be a use after free error in asan.
168 static int created = 0,
169 destroyed = 0;
170 {
171 struct Node {
172 Node(Node* n) : next(n) { created++; }
173 ~Node() {
174 destroyed++;
175 if (next) {
176 next->~Node();
177 }
178 }
179 Node *next;
180 };
181
182 SkSTArenaAlloc<64> arena;
183 Node* current = nullptr;
184 for (int i = 0; i < 128; i++) {
185 uint64_t* temp = arena.makeArrayDefault<uint64_t>(sizeof(Node) / sizeof(Node*));
186 current = new (temp)Node(current);
187 }
188 current->~Node();
189 }
190 REPORTER_ASSERT(r, created == 128);
191 REPORTER_ASSERT(r, destroyed == 128);
192
193 {
194 SkSTArenaAlloc<64> arena;
195 auto a = arena.makeInitializedArray<int>(8, [](size_t i ) { return i; });
196 for (size_t i = 0; i < 8; i++) {
197 REPORTER_ASSERT(r, a[i] == (int)i);
198 }
199 }
200}
201
202DEF_TEST(ArenaAllocUnusualAlignment, r) {
203 SkArenaAlloc arena(4096);
204 // Move to a 1 character boundary.
205 arena.make<char>();
206 // Allocate something with interesting alignment.
207 void* ptr = arena.makeBytesAlignedTo(4081, 8);
208 REPORTER_ASSERT(r, ((intptr_t)ptr & 7) == 0);
209}
210
212 {
214 uint32_t lastSize = 1;
215 for (int i = 0; i < 64; i++) {
216 uint32_t size = fibs.nextBlockSize();
217 REPORTER_ASSERT(r, lastSize <= size);
218 lastSize = size;
219 }
220 REPORTER_ASSERT(r, lastSize == 2971215073u);
221 }
222 {
224 uint32_t lastSize = 1;
225 for (int i = 0; i < 64; i++) {
226 uint32_t size = fibs.nextBlockSize();
227 REPORTER_ASSERT(r, lastSize <= size);
228 lastSize = size;
229 REPORTER_ASSERT(r, lastSize <= std::numeric_limits<uint32_t>::max());
230 }
231 REPORTER_ASSERT(r, lastSize == 3524578u * 1024);
232 }
233
234 {
236 uint32_t lastSize = 1;
237 for (int i = 0; i < 64; i++) {
238 uint32_t size = fibs.nextBlockSize();
239 REPORTER_ASSERT(r, lastSize <= size);
240 lastSize = size;
241 REPORTER_ASSERT(r, lastSize <= std::numeric_limits<uint32_t>::max() / 2);
242 }
243 REPORTER_ASSERT(r, lastSize == 1346269u * 1024);
244 }
245}
static float next(float f)
static const SkScalar Y
static const SkScalar X
#define DEF_TEST(name, reporter)
Definition Test.h:312
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
void * makeBytesAlignedTo(size_t size, size_t align)
T * makeArrayDefault(size_t count)
T * makeInitializedArray(size_t count, Initializer initializer)
T * makeArray(size_t count)
auto make(Ctor &&ctor) -> decltype(ctor(nullptr))
struct MyStruct a[10]
Definition dart.idl:29
double y
double x