blob: e7059f9eeae2d8dd7b230183cc0a89aa6e9e3f0e [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
17namespace {
18
19 static int created, destroyed;
20
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++; }
25
26 int x;
27 float y;
28 };
29
30 struct Big {
31 Big() {}
32 uint32_t array[128];
33 };
34
Herb Derby593cb942017-01-19 14:28:49 -050035 struct Node {
36 Node(Node* n) : next(n) { created++; }
37 ~Node() {
38 destroyed++;
39 if (next) {
40 next->~Node();
41 }
42 }
43 Node *next;
44 };
45
46 struct Start {
47 ~Start() {
48 if (start) {
49 start->~Node();
50 }
51 }
52 Node* start;
53 };
54
Herb Derby68521702017-02-06 13:03:49 -050055 struct FooRefCnt : public SkRefCnt {
56 FooRefCnt() : x(-2), y(-3.0f) { created++; }
57 FooRefCnt(int X, float Y) : x(X), y(Y) { created++; }
58 ~FooRefCnt() { destroyed++; }
59
60 int x;
61 float y;
62 };
63
Herb Derbyac04fef2017-01-13 17:34:33 -050064}
65
66struct WithDtor {
67 ~WithDtor() { }
68};
69
70DEF_TEST(ArenaAlloc, r) {
71
72 {
73 created = 0;
74 destroyed = 0;
75
Herb Derbydcbe2c82017-04-14 14:51:27 -040076 SkArenaAlloc arena{0};
Herb Derbyac04fef2017-01-13 17:34:33 -050077 REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
78 Foo* foo = arena.make<Foo>(3, 4.0f);
79 REPORTER_ASSERT(r, foo->x == 3);
80 REPORTER_ASSERT(r, foo->y == 4.0f);
81 REPORTER_ASSERT(r, created == 1);
82 REPORTER_ASSERT(r, destroyed == 0);
83 arena.makeArrayDefault<int>(10);
84 int* zeroed = arena.makeArray<int>(10);
85 for (int i = 0; i < 10; i++) {
86 REPORTER_ASSERT(r, zeroed[i] == 0);
87 }
88 Foo* fooArray = arena.makeArrayDefault<Foo>(10);
89 REPORTER_ASSERT(r, fooArray[3].x == -2);
90 REPORTER_ASSERT(r, fooArray[4].y == -3.0f);
91 REPORTER_ASSERT(r, created == 11);
92 REPORTER_ASSERT(r, destroyed == 0);
93 arena.make<typename std::aligned_storage<10,8>::type>();
94 }
95 REPORTER_ASSERT(r, created == 11);
96 REPORTER_ASSERT(r, destroyed == 11);
97
98 {
99 created = 0;
100 destroyed = 0;
Florin Malita14a64302017-05-24 14:53:44 -0400101 SkSTArenaAlloc<64> arena;
Herb Derbyac04fef2017-01-13 17:34:33 -0500102
103 REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
104 Foo* foo = arena.make<Foo>(3, 4.0f);
105 REPORTER_ASSERT(r, foo->x == 3);
106 REPORTER_ASSERT(r, foo->y == 4.0f);
107 REPORTER_ASSERT(r, created == 1);
108 REPORTER_ASSERT(r, destroyed == 0);
109 arena.makeArrayDefault<int>(10);
110 int* zeroed = arena.makeArray<int>(10);
111 for (int i = 0; i < 10; i++) {
112 REPORTER_ASSERT(r, zeroed[i] == 0);
113 }
114 Foo* fooArray = arena.makeArrayDefault<Foo>(10);
115 REPORTER_ASSERT(r, fooArray[3].x == -2);
116 REPORTER_ASSERT(r, fooArray[4].y == -3.0f);
117 REPORTER_ASSERT(r, created == 11);
118 REPORTER_ASSERT(r, destroyed == 0);
119 arena.make<typename std::aligned_storage<10,8>::type>();
120 }
121 REPORTER_ASSERT(r, created == 11);
122 REPORTER_ASSERT(r, destroyed == 11);
123
124 {
125 created = 0;
126 destroyed = 0;
127 std::unique_ptr<char[]> block{new char[1024]};
Herb Derbydcbe2c82017-04-14 14:51:27 -0400128 SkArenaAlloc arena{block.get(), 1024, 0};
Herb Derbyac04fef2017-01-13 17:34:33 -0500129
130 REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
131 Foo* foo = arena.make<Foo>(3, 4.0f);
132 REPORTER_ASSERT(r, foo->x == 3);
133 REPORTER_ASSERT(r, foo->y == 4.0f);
134 REPORTER_ASSERT(r, created == 1);
135 REPORTER_ASSERT(r, destroyed == 0);
136 arena.makeArrayDefault<int>(10);
137 int* zeroed = arena.makeArray<int>(10);
138 for (int i = 0; i < 10; i++) {
139 REPORTER_ASSERT(r, zeroed[i] == 0);
140 }
141 Foo* fooArray = arena.makeArrayDefault<Foo>(10);
142 REPORTER_ASSERT(r, fooArray[3].x == -2);
143 REPORTER_ASSERT(r, fooArray[4].y == -3.0f);
144 REPORTER_ASSERT(r, created == 11);
145 REPORTER_ASSERT(r, destroyed == 0);
146 arena.make<typename std::aligned_storage<10,8>::type>();
147 }
148 REPORTER_ASSERT(r, created == 11);
149 REPORTER_ASSERT(r, destroyed == 11);
Herb Derby593cb942017-01-19 14:28:49 -0500150
151 {
Florin Malita14a64302017-05-24 14:53:44 -0400152 SkSTArenaAlloc<64> arena;
Herb Derby593cb942017-01-19 14:28:49 -0500153 arena.makeArrayDefault<char>(256);
154 arena.reset();
155 arena.reset();
156 }
157
158 {
159 created = 0;
160 destroyed = 0;
Florin Malita14a64302017-05-24 14:53:44 -0400161 SkSTArenaAlloc<64> arena;
Herb Derby593cb942017-01-19 14:28:49 -0500162
163 Start start;
164 Node* current = nullptr;
165 for (int i = 0; i < 128; i++) {
166 uint64_t* temp = arena.makeArrayDefault<uint64_t>(sizeof(Node) / sizeof(Node*));
167 current = new (temp)Node(current);
168 }
169 start.start = current;
170 }
171
172 REPORTER_ASSERT(r, created == 128);
173 REPORTER_ASSERT(r, destroyed == 128);
Herb Derby68521702017-02-06 13:03:49 -0500174
Herb Derbyac04fef2017-01-13 17:34:33 -0500175}