Flutter Engine
The Flutter Engine
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;
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;
242 }
243 REPORTER_ASSERT(r, lastSize == 1346269u * 1024);
244 }
245}
DEF_TEST(ArenaAlloc, r)
static float next(float f)
static const SkScalar Y
Definition: StrokeBench.cpp:55
static const SkScalar X
Definition: StrokeBench.cpp:54
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
void * makeBytesAlignedTo(size_t size, size_t align)
Definition: SkArenaAlloc.h:200
T * makeArrayDefault(size_t count)
Definition: SkArenaAlloc.h:171
T * makeInitializedArray(size_t count, Initializer initializer)
Definition: SkArenaAlloc.h:191
T * makeArray(size_t count)
Definition: SkArenaAlloc.h:181
auto make(Ctor &&ctor) -> decltype(ctor(nullptr))
Definition: SkArenaAlloc.h:120
struct MyStruct a[10]
static float max(float r, float g, float b)
Definition: hsl.cpp:49
Definition: dart.idl:29
double y
double x
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259