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 {
Foo__anondec7cbec0111::Foo17 Foo() : x(-2), y(-3.0f) { created++; }
Foo__anondec7cbec0111::Foo18 Foo(int X, float Y) : x(X), y(Y) { created++; }
~Foo__anondec7cbec0111::Foo19 ~Foo() { destroyed++; }
20
21 int x;
22 float y;
23 };
24
25 struct Big {
Big__anondec7cbec0111::Big26 Big() {}
27 uint32_t array[128];
28 };
29
30 struct Node {
Node__anondec7cbec0111::Node31 Node(Node* n) : next(n) { created++; }
~Node__anondec7cbec0111::Node32 ~Node() {
33 destroyed++;
34 if (next) {
35 next->~Node();
36 }
37 }
38 Node *next;
39 };
40
41 struct Start {
~Start__anondec7cbec0111::Start42 ~Start() {
43 if (start) {
44 start->~Node();
45 }
46 }
47 Node* start;
48 };
49
50 struct FooRefCnt : public SkRefCnt {
FooRefCnt__anondec7cbec0111::FooRefCnt51 FooRefCnt() : x(-2), y(-3.0f) { created++; }
FooRefCnt__anondec7cbec0111::FooRefCnt52 FooRefCnt(int X, float Y) : x(X), y(Y) { created++; }
~FooRefCnt__anondec7cbec0111::FooRefCnt53 ~FooRefCnt() { destroyed++; }
54
55 int x;
56 float y;
57 };
58
59 }
60
61 struct WithDtor {
~WithDtorWithDtor62 ~WithDtor() { }
63 };
64
DEF_TEST(ArenaAlloc,r)65 DEF_TEST(ArenaAlloc, r) {
66
67 {
68 created = 0;
69 destroyed = 0;
70
71 SkArenaAlloc arena{nullptr, 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 char block[64];
97 SkArenaAlloc arena{block};
98
99 REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
100 Foo* foo = arena.make<Foo>(3, 4.0f);
101 REPORTER_ASSERT(r, foo->x == 3);
102 REPORTER_ASSERT(r, foo->y == 4.0f);
103 REPORTER_ASSERT(r, created == 1);
104 REPORTER_ASSERT(r, destroyed == 0);
105 arena.makeArrayDefault<int>(10);
106 int* zeroed = arena.makeArray<int>(10);
107 for (int i = 0; i < 10; i++) {
108 REPORTER_ASSERT(r, zeroed[i] == 0);
109 }
110 Foo* fooArray = arena.makeArrayDefault<Foo>(10);
111 REPORTER_ASSERT(r, fooArray[3].x == -2);
112 REPORTER_ASSERT(r, fooArray[4].y == -3.0f);
113 REPORTER_ASSERT(r, created == 11);
114 REPORTER_ASSERT(r, destroyed == 0);
115 arena.make<typename std::aligned_storage<10,8>::type>();
116 }
117 REPORTER_ASSERT(r, created == 11);
118 REPORTER_ASSERT(r, destroyed == 11);
119
120 {
121 created = 0;
122 destroyed = 0;
123 std::unique_ptr<char[]> block{new char[1024]};
124 SkArenaAlloc arena{block.get(), 1024};
125
126 REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
127 Foo* foo = arena.make<Foo>(3, 4.0f);
128 REPORTER_ASSERT(r, foo->x == 3);
129 REPORTER_ASSERT(r, foo->y == 4.0f);
130 REPORTER_ASSERT(r, created == 1);
131 REPORTER_ASSERT(r, destroyed == 0);
132 arena.makeArrayDefault<int>(10);
133 int* zeroed = arena.makeArray<int>(10);
134 for (int i = 0; i < 10; i++) {
135 REPORTER_ASSERT(r, zeroed[i] == 0);
136 }
137 Foo* fooArray = arena.makeArrayDefault<Foo>(10);
138 REPORTER_ASSERT(r, fooArray[3].x == -2);
139 REPORTER_ASSERT(r, fooArray[4].y == -3.0f);
140 REPORTER_ASSERT(r, created == 11);
141 REPORTER_ASSERT(r, destroyed == 0);
142 arena.make<typename std::aligned_storage<10,8>::type>();
143 }
144 REPORTER_ASSERT(r, created == 11);
145 REPORTER_ASSERT(r, destroyed == 11);
146
147 {
148 char storage[64];
149 SkArenaAlloc arena{storage};
150 arena.makeArrayDefault<char>(256);
151 arena.reset();
152 arena.reset();
153 }
154
155 {
156 created = 0;
157 destroyed = 0;
158 char storage[64];
159 SkArenaAlloc arena{storage};
160
161 Start start;
162 Node* current = nullptr;
163 for (int i = 0; i < 128; i++) {
164 uint64_t* temp = arena.makeArrayDefault<uint64_t>(sizeof(Node) / sizeof(Node*));
165 current = new (temp)Node(current);
166 }
167 start.start = current;
168 }
169
170 REPORTER_ASSERT(r, created == 128);
171 REPORTER_ASSERT(r, destroyed == 128);
172
173 {
174 created = 0;
175 destroyed = 0;
176 char storage[64];
177 SkArenaAlloc arena{storage};
178
179 sk_sp<FooRefCnt> f = arena.makeSkSp<FooRefCnt>(4, 5.0f);
180 REPORTER_ASSERT(r, f->x == 4);
181 REPORTER_ASSERT(r, f->y == 5.0f);
182 REPORTER_ASSERT(r, created == 1);
183 REPORTER_ASSERT(r, destroyed == 0);
184 }
185 REPORTER_ASSERT(r, created == 1);
186 REPORTER_ASSERT(r, destroyed == 1);
187 }
188