blob: 0836b0c49f8f14ce4777d49e0dee21f03b2c0d25 [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"
10
11namespace {
12
13 static int created, destroyed;
14
15 struct Foo {
16 Foo() : x(-2), y(-3.0f) { created++; }
17 Foo(int X, float Y) : x(X), y(Y) { created++; }
18 ~Foo() { destroyed++; }
19
20 int x;
21 float y;
22 };
23
24 struct Big {
25 Big() {}
26 uint32_t array[128];
27 };
28
Herb Derby593cb942017-01-19 14:28:49 -050029 struct Node {
30 Node(Node* n) : next(n) { created++; }
31 ~Node() {
32 destroyed++;
33 if (next) {
34 next->~Node();
35 }
36 }
37 Node *next;
38 };
39
40 struct Start {
41 ~Start() {
42 if (start) {
43 start->~Node();
44 }
45 }
46 Node* start;
47 };
48
Herb Derbyac04fef2017-01-13 17:34:33 -050049}
50
51struct WithDtor {
52 ~WithDtor() { }
53};
54
55DEF_TEST(ArenaAlloc, r) {
56
57 {
58 created = 0;
59 destroyed = 0;
60
61 SkArenaAlloc arena{nullptr, 0};
62 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);
78 arena.make<typename std::aligned_storage<10,8>::type>();
79 }
80 REPORTER_ASSERT(r, created == 11);
81 REPORTER_ASSERT(r, destroyed == 11);
82
83 {
84 created = 0;
85 destroyed = 0;
Herb Derby593cb942017-01-19 14:28:49 -050086 char block[64];
Herb Derbyac04fef2017-01-13 17:34:33 -050087 SkArenaAlloc arena{block};
88
89 REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
90 Foo* foo = arena.make<Foo>(3, 4.0f);
91 REPORTER_ASSERT(r, foo->x == 3);
92 REPORTER_ASSERT(r, foo->y == 4.0f);
93 REPORTER_ASSERT(r, created == 1);
94 REPORTER_ASSERT(r, destroyed == 0);
95 arena.makeArrayDefault<int>(10);
96 int* zeroed = arena.makeArray<int>(10);
97 for (int i = 0; i < 10; i++) {
98 REPORTER_ASSERT(r, zeroed[i] == 0);
99 }
100 Foo* fooArray = arena.makeArrayDefault<Foo>(10);
101 REPORTER_ASSERT(r, fooArray[3].x == -2);
102 REPORTER_ASSERT(r, fooArray[4].y == -3.0f);
103 REPORTER_ASSERT(r, created == 11);
104 REPORTER_ASSERT(r, destroyed == 0);
105 arena.make<typename std::aligned_storage<10,8>::type>();
106 }
107 REPORTER_ASSERT(r, created == 11);
108 REPORTER_ASSERT(r, destroyed == 11);
109
110 {
111 created = 0;
112 destroyed = 0;
113 std::unique_ptr<char[]> block{new char[1024]};
114 SkArenaAlloc arena{block.get(), 1024};
115
116 REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
117 Foo* foo = arena.make<Foo>(3, 4.0f);
118 REPORTER_ASSERT(r, foo->x == 3);
119 REPORTER_ASSERT(r, foo->y == 4.0f);
120 REPORTER_ASSERT(r, created == 1);
121 REPORTER_ASSERT(r, destroyed == 0);
122 arena.makeArrayDefault<int>(10);
123 int* zeroed = arena.makeArray<int>(10);
124 for (int i = 0; i < 10; i++) {
125 REPORTER_ASSERT(r, zeroed[i] == 0);
126 }
127 Foo* fooArray = arena.makeArrayDefault<Foo>(10);
128 REPORTER_ASSERT(r, fooArray[3].x == -2);
129 REPORTER_ASSERT(r, fooArray[4].y == -3.0f);
130 REPORTER_ASSERT(r, created == 11);
131 REPORTER_ASSERT(r, destroyed == 0);
132 arena.make<typename std::aligned_storage<10,8>::type>();
133 }
134 REPORTER_ASSERT(r, created == 11);
135 REPORTER_ASSERT(r, destroyed == 11);
Herb Derby593cb942017-01-19 14:28:49 -0500136
137 {
138 char storage[64];
139 SkArenaAlloc arena{storage};
140 arena.makeArrayDefault<char>(256);
141 arena.reset();
142 arena.reset();
143 }
144
145 {
146 created = 0;
147 destroyed = 0;
148 char storage[64];
149 SkArenaAlloc arena{storage};
150
151 Start start;
152 Node* current = nullptr;
153 for (int i = 0; i < 128; i++) {
154 uint64_t* temp = arena.makeArrayDefault<uint64_t>(sizeof(Node) / sizeof(Node*));
155 current = new (temp)Node(current);
156 }
157 start.start = current;
158 }
159
160 REPORTER_ASSERT(r, created == 128);
161 REPORTER_ASSERT(r, destroyed == 128);
Herb Derbyac04fef2017-01-13 17:34:33 -0500162}