blob: fd16ec7cd7117d7290955d53ede4fd6d85de2f66 [file] [log] [blame]
Herb Derbyac04fef2017-01-13 17:34:33 -05001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/core/SkRefCnt.h"
9#include "include/core/SkTypes.h"
Ben Wagner729a23f2019-05-17 16:29:34 -040010#include "src/core/SkArenaAlloc.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "tests/Test.h"
Ben Wagner1ebeefe2018-03-02 16:59:53 -050012
13#include <memory>
14#include <new>
15#include <type_traits>
Herb Derbyac04fef2017-01-13 17:34:33 -050016
Herb Derbyf52a8112020-12-16 11:17:27 -050017DEF_TEST(ArenaAlloc, r) {
18 static int created = 0,
19 destroyed = 0;
Herb Derbyac04fef2017-01-13 17:34:33 -050020
21 struct Foo {
22 Foo() : x(-2), y(-3.0f) { created++; }
23 Foo(int X, float Y) : x(X), y(Y) { created++; }
24 ~Foo() { destroyed++; }
Herb Derbyac04fef2017-01-13 17:34:33 -050025 int x;
26 float y;
27 };
28
Herb Derbyf52a8112020-12-16 11:17:27 -050029 struct alignas(8) OddAlignment {
30 char buf[10];
Herb Derbyac04fef2017-01-13 17:34:33 -050031 };
32
Herb Derbyf52a8112020-12-16 11:17:27 -050033 created = 0;
34 destroyed = 0;
Herb Derbyac04fef2017-01-13 17:34:33 -050035 {
Herb Derbydcbe2c82017-04-14 14:51:27 -040036 SkArenaAlloc arena{0};
Herb Derbyac04fef2017-01-13 17:34:33 -050037 REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
38 Foo* foo = arena.make<Foo>(3, 4.0f);
39 REPORTER_ASSERT(r, foo->x == 3);
40 REPORTER_ASSERT(r, foo->y == 4.0f);
41 REPORTER_ASSERT(r, created == 1);
42 REPORTER_ASSERT(r, destroyed == 0);
43 arena.makeArrayDefault<int>(10);
44 int* zeroed = arena.makeArray<int>(10);
45 for (int i = 0; i < 10; i++) {
46 REPORTER_ASSERT(r, zeroed[i] == 0);
47 }
48 Foo* fooArray = arena.makeArrayDefault<Foo>(10);
49 REPORTER_ASSERT(r, fooArray[3].x == -2);
50 REPORTER_ASSERT(r, fooArray[4].y == -3.0f);
51 REPORTER_ASSERT(r, created == 11);
52 REPORTER_ASSERT(r, destroyed == 0);
Mike Kleinfb5850f2020-11-09 15:50:37 -060053 arena.make<OddAlignment>();
Herb Derbyac04fef2017-01-13 17:34:33 -050054 }
55 REPORTER_ASSERT(r, created == 11);
56 REPORTER_ASSERT(r, destroyed == 11);
57
Herb Derbyf52a8112020-12-16 11:17:27 -050058 created = 0;
59 destroyed = 0;
Herb Derbyac04fef2017-01-13 17:34:33 -050060 {
Florin Malita14a64302017-05-24 14:53:44 -040061 SkSTArenaAlloc<64> arena;
Herb Derbyac04fef2017-01-13 17:34:33 -050062 REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
63 Foo* foo = arena.make<Foo>(3, 4.0f);
64 REPORTER_ASSERT(r, foo->x == 3);
65 REPORTER_ASSERT(r, foo->y == 4.0f);
66 REPORTER_ASSERT(r, created == 1);
67 REPORTER_ASSERT(r, destroyed == 0);
68 arena.makeArrayDefault<int>(10);
69 int* zeroed = arena.makeArray<int>(10);
70 for (int i = 0; i < 10; i++) {
71 REPORTER_ASSERT(r, zeroed[i] == 0);
72 }
73 Foo* fooArray = arena.makeArrayDefault<Foo>(10);
74 REPORTER_ASSERT(r, fooArray[3].x == -2);
75 REPORTER_ASSERT(r, fooArray[4].y == -3.0f);
76 REPORTER_ASSERT(r, created == 11);
77 REPORTER_ASSERT(r, destroyed == 0);
Mike Kleinfb5850f2020-11-09 15:50:37 -060078 arena.make<OddAlignment>();
Herb Derbyac04fef2017-01-13 17:34:33 -050079 }
80 REPORTER_ASSERT(r, created == 11);
81 REPORTER_ASSERT(r, destroyed == 11);
82
Herb Derbyf52a8112020-12-16 11:17:27 -050083 created = 0;
84 destroyed = 0;
Herb Derbyac04fef2017-01-13 17:34:33 -050085 {
Herb Derbyac04fef2017-01-13 17:34:33 -050086 std::unique_ptr<char[]> block{new char[1024]};
Herb Derbydcbe2c82017-04-14 14:51:27 -040087 SkArenaAlloc arena{block.get(), 1024, 0};
Herb Derbyac04fef2017-01-13 17:34:33 -050088 REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
89 Foo* foo = arena.make<Foo>(3, 4.0f);
90 REPORTER_ASSERT(r, foo->x == 3);
91 REPORTER_ASSERT(r, foo->y == 4.0f);
92 REPORTER_ASSERT(r, created == 1);
93 REPORTER_ASSERT(r, destroyed == 0);
94 arena.makeArrayDefault<int>(10);
95 int* zeroed = arena.makeArray<int>(10);
96 for (int i = 0; i < 10; i++) {
97 REPORTER_ASSERT(r, zeroed[i] == 0);
98 }
99 Foo* fooArray = arena.makeArrayDefault<Foo>(10);
100 REPORTER_ASSERT(r, fooArray[3].x == -2);
101 REPORTER_ASSERT(r, fooArray[4].y == -3.0f);
102 REPORTER_ASSERT(r, created == 11);
103 REPORTER_ASSERT(r, destroyed == 0);
Mike Kleinfb5850f2020-11-09 15:50:37 -0600104 arena.make<OddAlignment>();
Herb Derbyac04fef2017-01-13 17:34:33 -0500105 }
106 REPORTER_ASSERT(r, created == 11);
107 REPORTER_ASSERT(r, destroyed == 11);
Herb Derby593cb942017-01-19 14:28:49 -0500108
109 {
Herb Derby6e2c56f2020-08-01 16:26:04 -0400110 SkSTArenaAllocWithReset<64> arena;
Herb Derby593cb942017-01-19 14:28:49 -0500111 arena.makeArrayDefault<char>(256);
112 arena.reset();
113 arena.reset();
114 }
115
Herb Derbyf52a8112020-12-16 11:17:27 -0500116 // Make sure that multiple blocks are handled correctly.
117 created = 0;
118 destroyed = 0;
Herb Derby593cb942017-01-19 14:28:49 -0500119 {
Herb Derbyf52a8112020-12-16 11:17:27 -0500120 struct Node {
121 Node(Node* n) : next(n) { created++; }
122 ~Node() { destroyed++; }
123 Node *next;
124 char filler[64];
125 };
Herb Derby593cb942017-01-19 14:28:49 -0500126
Herb Derbyf52a8112020-12-16 11:17:27 -0500127 SkSTArenaAlloc<64> arena;
128 Node* current = nullptr;
129 for (int i = 0; i < 128; i++) {
130 current = arena.make<Node>(current);
131 }
132 }
133 REPORTER_ASSERT(r, created == 128);
134 REPORTER_ASSERT(r, destroyed == 128);
135
136 // Make sure that objects and blocks are destroyed in the correct order. If they are not,
137 // then there will be a use after free error in asan.
138 created = 0;
139 destroyed = 0;
140 {
141 struct Node {
142 Node(Node* n) : next(n) { created++; }
143 ~Node() {
144 destroyed++;
145 if (next) {
146 next->~Node();
147 }
148 }
149 Node *next;
150 };
151
152 SkSTArenaAlloc<64> arena;
Herb Derby593cb942017-01-19 14:28:49 -0500153 Node* current = nullptr;
154 for (int i = 0; i < 128; i++) {
155 uint64_t* temp = arena.makeArrayDefault<uint64_t>(sizeof(Node) / sizeof(Node*));
156 current = new (temp)Node(current);
157 }
Herb Derbyf52a8112020-12-16 11:17:27 -0500158 current->~Node();
Herb Derby593cb942017-01-19 14:28:49 -0500159 }
Herb Derbyf52a8112020-12-16 11:17:27 -0500160 REPORTER_ASSERT(r, created == 128);
161 REPORTER_ASSERT(r, destroyed == 128);
Herb Derby593cb942017-01-19 14:28:49 -0500162
Herb Derby8f3963f2020-05-13 14:53:40 -0400163 {
164 SkSTArenaAlloc<64> arena;
165 auto a = arena.makeInitializedArray<int>(8, [](size_t i ) { return i; });
166 for (size_t i = 0; i < 8; i++) {
167 REPORTER_ASSERT(r, a[i] == (int)i);
168 }
169 }
170
Florin Malita26c24ed2020-09-08 14:59:16 -0400171 {
172 SkArenaAlloc arena(4096);
Herb Derbyf52a8112020-12-16 11:17:27 -0500173 // Move to a 1 character boundary.
174 arena.make<char>();
175 // Allocate something with interesting alignment.
176 void* ptr = arena.makeBytesAlignedTo(4081, 8);
177 REPORTER_ASSERT(r, ((intptr_t)ptr & 7) == 0);
Florin Malita26c24ed2020-09-08 14:59:16 -0400178 }
Herb Derbyac04fef2017-01-13 17:34:33 -0500179}
Herb Derby1d895322020-12-16 14:42:40 -0500180
181DEF_TEST(SkFibBlockSizes, r) {
182 {
183 SkFibBlockSizes<std::numeric_limits<uint32_t>::max()> fibs{1, 1};
184 uint32_t lastSize = 1;
185 for (int i = 0; i < 64; i++) {
186 uint32_t size = fibs.nextBlockSize();
187 REPORTER_ASSERT(r, lastSize <= size);
188 lastSize = size;
189 }
190 REPORTER_ASSERT(r, lastSize == 2971215073u);
191 }
192 {
193 SkFibBlockSizes<std::numeric_limits<uint32_t>::max()> fibs{0, 1024};
194 uint32_t lastSize = 1;
195 for (int i = 0; i < 64; i++) {
196 uint32_t size = fibs.nextBlockSize();
197 REPORTER_ASSERT(r, lastSize <= size);
198 lastSize = size;
199 REPORTER_ASSERT(r, lastSize <= std::numeric_limits<uint32_t>::max());
200 }
201 REPORTER_ASSERT(r, lastSize == 3524578u * 1024);
202 }
203
204 {
205 SkFibBlockSizes<std::numeric_limits<uint32_t>::max() / 2> fibs{1024, 0};
206 uint32_t lastSize = 1;
207 for (int i = 0; i < 64; i++) {
208 uint32_t size = fibs.nextBlockSize();
209 REPORTER_ASSERT(r, lastSize <= size);
210 lastSize = size;
211 REPORTER_ASSERT(r, lastSize <= std::numeric_limits<uint32_t>::max() / 2);
212 }
213 REPORTER_ASSERT(r, lastSize == 1346269u * 1024);
214 }
215}