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