blob: cb2ae0e5e3f6e8082070e40540f4e78fcd569020 [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
8#include "Test.h"
9#include "SkArenaAlloc.h"
Herb Derby68521702017-02-06 13:03:49 -050010#include "SkRefCnt.h"
Herb Derbyac04fef2017-01-13 17:34:33 -050011
12namespace {
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
Herb Derby593cb942017-01-19 14:28:49 -050030 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
Herb Derby68521702017-02-06 13:03:49 -050050 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
Herb Derbyac04fef2017-01-13 17:34:33 -050059}
60
61struct WithDtor {
62 ~WithDtor() { }
63};
64
65DEF_TEST(ArenaAlloc, r) {
66
67 {
68 created = 0;
69 destroyed = 0;
70
Herb Derbydcbe2c82017-04-14 14:51:27 -040071 SkArenaAlloc arena{0};
Herb Derbyac04fef2017-01-13 17:34:33 -050072 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;
Herb Derby593cb942017-01-19 14:28:49 -050096 char block[64];
Herb Derbyac04fef2017-01-13 17:34:33 -050097 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]};
Herb Derbydcbe2c82017-04-14 14:51:27 -0400124 SkArenaAlloc arena{block.get(), 1024, 0};
Herb Derbyac04fef2017-01-13 17:34:33 -0500125
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);
Herb Derby593cb942017-01-19 14:28:49 -0500146
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);
Herb Derby68521702017-02-06 13:03:49 -0500172
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);
Herb Derbyac04fef2017-01-13 17:34:33 -0500187}