| /* | |
| * Copyright 2016 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "include/core/SkRefCnt.h" | |
| #include "include/core/SkTypes.h" | |
| #include "src/core/SkArenaAlloc.h" | |
| #include "tests/Test.h" | |
| #include <memory> | |
| #include <new> | |
| #include <type_traits> | |
| namespace { | |
| static int created, destroyed; | |
| struct Foo { | |
| Foo() : x(-2), y(-3.0f) { created++; } | |
| Foo(int X, float Y) : x(X), y(Y) { created++; } | |
| ~Foo() { destroyed++; } | |
| int x; | |
| float y; | |
| }; | |
| struct Big { | |
| Big() {} | |
| uint32_t array[128]; | |
| }; | |
| struct Node { | |
| Node(Node* n) : next(n) { created++; } | |
| ~Node() { | |
| destroyed++; | |
| if (next) { | |
| next->~Node(); | |
| } | |
| } | |
| Node *next; | |
| }; | |
| struct Start { | |
| ~Start() { | |
| if (start) { | |
| start->~Node(); | |
| } | |
| } | |
| Node* start; | |
| }; | |
| struct FooRefCnt : public SkRefCnt { | |
| FooRefCnt() : x(-2), y(-3.0f) { created++; } | |
| FooRefCnt(int X, float Y) : x(X), y(Y) { created++; } | |
| ~FooRefCnt() { destroyed++; } | |
| int x; | |
| float y; | |
| }; | |
| } | |
| struct WithDtor { | |
| ~WithDtor() { } | |
| }; | |
| DEF_TEST(ArenaAlloc, r) { | |
| { | |
| created = 0; | |
| destroyed = 0; | |
| SkArenaAlloc arena{0}; | |
| REPORTER_ASSERT(r, *arena.make<int>(3) == 3); | |
| Foo* foo = arena.make<Foo>(3, 4.0f); | |
| REPORTER_ASSERT(r, foo->x == 3); | |
| REPORTER_ASSERT(r, foo->y == 4.0f); | |
| REPORTER_ASSERT(r, created == 1); | |
| REPORTER_ASSERT(r, destroyed == 0); | |
| arena.makeArrayDefault<int>(10); | |
| int* zeroed = arena.makeArray<int>(10); | |
| for (int i = 0; i < 10; i++) { | |
| REPORTER_ASSERT(r, zeroed[i] == 0); | |
| } | |
| Foo* fooArray = arena.makeArrayDefault<Foo>(10); | |
| REPORTER_ASSERT(r, fooArray[3].x == -2); | |
| REPORTER_ASSERT(r, fooArray[4].y == -3.0f); | |
| REPORTER_ASSERT(r, created == 11); | |
| REPORTER_ASSERT(r, destroyed == 0); | |
| arena.make<typename std::aligned_storage<10,8>::type>(); | |
| } | |
| REPORTER_ASSERT(r, created == 11); | |
| REPORTER_ASSERT(r, destroyed == 11); | |
| { | |
| created = 0; | |
| destroyed = 0; | |
| SkSTArenaAlloc<64> arena; | |
| REPORTER_ASSERT(r, *arena.make<int>(3) == 3); | |
| Foo* foo = arena.make<Foo>(3, 4.0f); | |
| REPORTER_ASSERT(r, foo->x == 3); | |
| REPORTER_ASSERT(r, foo->y == 4.0f); | |
| REPORTER_ASSERT(r, created == 1); | |
| REPORTER_ASSERT(r, destroyed == 0); | |
| arena.makeArrayDefault<int>(10); | |
| int* zeroed = arena.makeArray<int>(10); | |
| for (int i = 0; i < 10; i++) { | |
| REPORTER_ASSERT(r, zeroed[i] == 0); | |
| } | |
| Foo* fooArray = arena.makeArrayDefault<Foo>(10); | |
| REPORTER_ASSERT(r, fooArray[3].x == -2); | |
| REPORTER_ASSERT(r, fooArray[4].y == -3.0f); | |
| REPORTER_ASSERT(r, created == 11); | |
| REPORTER_ASSERT(r, destroyed == 0); | |
| arena.make<typename std::aligned_storage<10,8>::type>(); | |
| } | |
| REPORTER_ASSERT(r, created == 11); | |
| REPORTER_ASSERT(r, destroyed == 11); | |
| { | |
| created = 0; | |
| destroyed = 0; | |
| std::unique_ptr<char[]> block{new char[1024]}; | |
| SkArenaAlloc arena{block.get(), 1024, 0}; | |
| REPORTER_ASSERT(r, *arena.make<int>(3) == 3); | |
| Foo* foo = arena.make<Foo>(3, 4.0f); | |
| REPORTER_ASSERT(r, foo->x == 3); | |
| REPORTER_ASSERT(r, foo->y == 4.0f); | |
| REPORTER_ASSERT(r, created == 1); | |
| REPORTER_ASSERT(r, destroyed == 0); | |
| arena.makeArrayDefault<int>(10); | |
| int* zeroed = arena.makeArray<int>(10); | |
| for (int i = 0; i < 10; i++) { | |
| REPORTER_ASSERT(r, zeroed[i] == 0); | |
| } | |
| Foo* fooArray = arena.makeArrayDefault<Foo>(10); | |
| REPORTER_ASSERT(r, fooArray[3].x == -2); | |
| REPORTER_ASSERT(r, fooArray[4].y == -3.0f); | |
| REPORTER_ASSERT(r, created == 11); | |
| REPORTER_ASSERT(r, destroyed == 0); | |
| arena.make<typename std::aligned_storage<10,8>::type>(); | |
| } | |
| REPORTER_ASSERT(r, created == 11); | |
| REPORTER_ASSERT(r, destroyed == 11); | |
| { | |
| SkSTArenaAlloc<64> arena; | |
| arena.makeArrayDefault<char>(256); | |
| arena.reset(); | |
| arena.reset(); | |
| } | |
| { | |
| created = 0; | |
| destroyed = 0; | |
| SkSTArenaAlloc<64> arena; | |
| Start start; | |
| Node* current = nullptr; | |
| for (int i = 0; i < 128; i++) { | |
| uint64_t* temp = arena.makeArrayDefault<uint64_t>(sizeof(Node) / sizeof(Node*)); | |
| current = new (temp)Node(current); | |
| } | |
| start.start = current; | |
| } | |
| REPORTER_ASSERT(r, created == 128); | |
| REPORTER_ASSERT(r, destroyed == 128); | |
| } |