1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2016 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkRefCnt.h" 9cb93a386Sopenharmony_ci#include "include/core/SkTypes.h" 10cb93a386Sopenharmony_ci#include "src/core/SkArenaAlloc.h" 11cb93a386Sopenharmony_ci#include "tests/Test.h" 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_ci#include <memory> 14cb93a386Sopenharmony_ci#include <new> 15cb93a386Sopenharmony_ci#include <type_traits> 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_ciDEF_TEST(ArenaAlloc, r) { 18cb93a386Sopenharmony_ci static int created = 0, 19cb93a386Sopenharmony_ci destroyed = 0; 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_ci struct Foo { 22cb93a386Sopenharmony_ci Foo() : x(-2), y(-3.0f) { created++; } 23cb93a386Sopenharmony_ci Foo(int X, float Y) : x(X), y(Y) { created++; } 24cb93a386Sopenharmony_ci ~Foo() { destroyed++; } 25cb93a386Sopenharmony_ci int x; 26cb93a386Sopenharmony_ci float y; 27cb93a386Sopenharmony_ci }; 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ci struct alignas(8) OddAlignment { 30cb93a386Sopenharmony_ci char buf[10]; 31cb93a386Sopenharmony_ci }; 32cb93a386Sopenharmony_ci 33cb93a386Sopenharmony_ci created = 0; 34cb93a386Sopenharmony_ci destroyed = 0; 35cb93a386Sopenharmony_ci { 36cb93a386Sopenharmony_ci SkArenaAlloc arena{0}; 37cb93a386Sopenharmony_ci REPORTER_ASSERT(r, *arena.make<int>(3) == 3); 38cb93a386Sopenharmony_ci Foo* foo = arena.make<Foo>(3, 4.0f); 39cb93a386Sopenharmony_ci REPORTER_ASSERT(r, foo->x == 3); 40cb93a386Sopenharmony_ci REPORTER_ASSERT(r, foo->y == 4.0f); 41cb93a386Sopenharmony_ci REPORTER_ASSERT(r, created == 1); 42cb93a386Sopenharmony_ci REPORTER_ASSERT(r, destroyed == 0); 43cb93a386Sopenharmony_ci arena.makeArrayDefault<int>(10); 44cb93a386Sopenharmony_ci int* zeroed = arena.makeArray<int>(10); 45cb93a386Sopenharmony_ci for (int i = 0; i < 10; i++) { 46cb93a386Sopenharmony_ci REPORTER_ASSERT(r, zeroed[i] == 0); 47cb93a386Sopenharmony_ci } 48cb93a386Sopenharmony_ci Foo* fooArray = arena.makeArrayDefault<Foo>(10); 49cb93a386Sopenharmony_ci REPORTER_ASSERT(r, fooArray[3].x == -2); 50cb93a386Sopenharmony_ci REPORTER_ASSERT(r, fooArray[4].y == -3.0f); 51cb93a386Sopenharmony_ci REPORTER_ASSERT(r, created == 11); 52cb93a386Sopenharmony_ci REPORTER_ASSERT(r, destroyed == 0); 53cb93a386Sopenharmony_ci arena.make<OddAlignment>(); 54cb93a386Sopenharmony_ci } 55cb93a386Sopenharmony_ci REPORTER_ASSERT(r, created == 11); 56cb93a386Sopenharmony_ci REPORTER_ASSERT(r, destroyed == 11); 57cb93a386Sopenharmony_ci 58cb93a386Sopenharmony_ci created = 0; 59cb93a386Sopenharmony_ci destroyed = 0; 60cb93a386Sopenharmony_ci { 61cb93a386Sopenharmony_ci SkSTArenaAlloc<64> arena; 62cb93a386Sopenharmony_ci REPORTER_ASSERT(r, *arena.make<int>(3) == 3); 63cb93a386Sopenharmony_ci Foo* foo = arena.make<Foo>(3, 4.0f); 64cb93a386Sopenharmony_ci REPORTER_ASSERT(r, foo->x == 3); 65cb93a386Sopenharmony_ci REPORTER_ASSERT(r, foo->y == 4.0f); 66cb93a386Sopenharmony_ci REPORTER_ASSERT(r, created == 1); 67cb93a386Sopenharmony_ci REPORTER_ASSERT(r, destroyed == 0); 68cb93a386Sopenharmony_ci arena.makeArrayDefault<int>(10); 69cb93a386Sopenharmony_ci int* zeroed = arena.makeArray<int>(10); 70cb93a386Sopenharmony_ci for (int i = 0; i < 10; i++) { 71cb93a386Sopenharmony_ci REPORTER_ASSERT(r, zeroed[i] == 0); 72cb93a386Sopenharmony_ci } 73cb93a386Sopenharmony_ci Foo* fooArray = arena.makeArrayDefault<Foo>(10); 74cb93a386Sopenharmony_ci REPORTER_ASSERT(r, fooArray[3].x == -2); 75cb93a386Sopenharmony_ci REPORTER_ASSERT(r, fooArray[4].y == -3.0f); 76cb93a386Sopenharmony_ci REPORTER_ASSERT(r, created == 11); 77cb93a386Sopenharmony_ci REPORTER_ASSERT(r, destroyed == 0); 78cb93a386Sopenharmony_ci arena.make<OddAlignment>(); 79cb93a386Sopenharmony_ci } 80cb93a386Sopenharmony_ci REPORTER_ASSERT(r, created == 11); 81cb93a386Sopenharmony_ci REPORTER_ASSERT(r, destroyed == 11); 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_ci created = 0; 84cb93a386Sopenharmony_ci destroyed = 0; 85cb93a386Sopenharmony_ci { 86cb93a386Sopenharmony_ci std::unique_ptr<char[]> block{new char[1024]}; 87cb93a386Sopenharmony_ci SkArenaAlloc arena{block.get(), 1024, 0}; 88cb93a386Sopenharmony_ci REPORTER_ASSERT(r, *arena.make<int>(3) == 3); 89cb93a386Sopenharmony_ci Foo* foo = arena.make<Foo>(3, 4.0f); 90cb93a386Sopenharmony_ci REPORTER_ASSERT(r, foo->x == 3); 91cb93a386Sopenharmony_ci REPORTER_ASSERT(r, foo->y == 4.0f); 92cb93a386Sopenharmony_ci REPORTER_ASSERT(r, created == 1); 93cb93a386Sopenharmony_ci REPORTER_ASSERT(r, destroyed == 0); 94cb93a386Sopenharmony_ci arena.makeArrayDefault<int>(10); 95cb93a386Sopenharmony_ci int* zeroed = arena.makeArray<int>(10); 96cb93a386Sopenharmony_ci for (int i = 0; i < 10; i++) { 97cb93a386Sopenharmony_ci REPORTER_ASSERT(r, zeroed[i] == 0); 98cb93a386Sopenharmony_ci } 99cb93a386Sopenharmony_ci Foo* fooArray = arena.makeArrayDefault<Foo>(10); 100cb93a386Sopenharmony_ci REPORTER_ASSERT(r, fooArray[3].x == -2); 101cb93a386Sopenharmony_ci REPORTER_ASSERT(r, fooArray[4].y == -3.0f); 102cb93a386Sopenharmony_ci REPORTER_ASSERT(r, created == 11); 103cb93a386Sopenharmony_ci REPORTER_ASSERT(r, destroyed == 0); 104cb93a386Sopenharmony_ci arena.make<OddAlignment>(); 105cb93a386Sopenharmony_ci } 106cb93a386Sopenharmony_ci REPORTER_ASSERT(r, created == 11); 107cb93a386Sopenharmony_ci REPORTER_ASSERT(r, destroyed == 11); 108cb93a386Sopenharmony_ci 109cb93a386Sopenharmony_ci { 110cb93a386Sopenharmony_ci SkSTArenaAllocWithReset<64> arena; 111cb93a386Sopenharmony_ci arena.makeArrayDefault<char>(256); 112cb93a386Sopenharmony_ci arena.reset(); 113cb93a386Sopenharmony_ci arena.reset(); 114cb93a386Sopenharmony_ci } 115cb93a386Sopenharmony_ci 116cb93a386Sopenharmony_ci // Make sure that multiple blocks are handled correctly. 117cb93a386Sopenharmony_ci created = 0; 118cb93a386Sopenharmony_ci destroyed = 0; 119cb93a386Sopenharmony_ci { 120cb93a386Sopenharmony_ci struct Node { 121cb93a386Sopenharmony_ci Node(Node* n) : next(n) { created++; } 122cb93a386Sopenharmony_ci ~Node() { destroyed++; } 123cb93a386Sopenharmony_ci Node *next; 124cb93a386Sopenharmony_ci char filler[64]; 125cb93a386Sopenharmony_ci }; 126cb93a386Sopenharmony_ci 127cb93a386Sopenharmony_ci SkSTArenaAlloc<64> arena; 128cb93a386Sopenharmony_ci Node* current = nullptr; 129cb93a386Sopenharmony_ci for (int i = 0; i < 128; i++) { 130cb93a386Sopenharmony_ci current = arena.make<Node>(current); 131cb93a386Sopenharmony_ci } 132cb93a386Sopenharmony_ci } 133cb93a386Sopenharmony_ci REPORTER_ASSERT(r, created == 128); 134cb93a386Sopenharmony_ci REPORTER_ASSERT(r, destroyed == 128); 135cb93a386Sopenharmony_ci 136cb93a386Sopenharmony_ci // Make sure that objects and blocks are destroyed in the correct order. If they are not, 137cb93a386Sopenharmony_ci // then there will be a use after free error in asan. 138cb93a386Sopenharmony_ci created = 0; 139cb93a386Sopenharmony_ci destroyed = 0; 140cb93a386Sopenharmony_ci { 141cb93a386Sopenharmony_ci struct Node { 142cb93a386Sopenharmony_ci Node(Node* n) : next(n) { created++; } 143cb93a386Sopenharmony_ci ~Node() { 144cb93a386Sopenharmony_ci destroyed++; 145cb93a386Sopenharmony_ci if (next) { 146cb93a386Sopenharmony_ci next->~Node(); 147cb93a386Sopenharmony_ci } 148cb93a386Sopenharmony_ci } 149cb93a386Sopenharmony_ci Node *next; 150cb93a386Sopenharmony_ci }; 151cb93a386Sopenharmony_ci 152cb93a386Sopenharmony_ci SkSTArenaAlloc<64> arena; 153cb93a386Sopenharmony_ci Node* current = nullptr; 154cb93a386Sopenharmony_ci for (int i = 0; i < 128; i++) { 155cb93a386Sopenharmony_ci uint64_t* temp = arena.makeArrayDefault<uint64_t>(sizeof(Node) / sizeof(Node*)); 156cb93a386Sopenharmony_ci current = new (temp)Node(current); 157cb93a386Sopenharmony_ci } 158cb93a386Sopenharmony_ci current->~Node(); 159cb93a386Sopenharmony_ci } 160cb93a386Sopenharmony_ci REPORTER_ASSERT(r, created == 128); 161cb93a386Sopenharmony_ci REPORTER_ASSERT(r, destroyed == 128); 162cb93a386Sopenharmony_ci 163cb93a386Sopenharmony_ci { 164cb93a386Sopenharmony_ci SkSTArenaAlloc<64> arena; 165cb93a386Sopenharmony_ci auto a = arena.makeInitializedArray<int>(8, [](size_t i ) { return i; }); 166cb93a386Sopenharmony_ci for (size_t i = 0; i < 8; i++) { 167cb93a386Sopenharmony_ci REPORTER_ASSERT(r, a[i] == (int)i); 168cb93a386Sopenharmony_ci } 169cb93a386Sopenharmony_ci } 170cb93a386Sopenharmony_ci 171cb93a386Sopenharmony_ci { 172cb93a386Sopenharmony_ci SkArenaAlloc arena(4096); 173cb93a386Sopenharmony_ci // Move to a 1 character boundary. 174cb93a386Sopenharmony_ci arena.make<char>(); 175cb93a386Sopenharmony_ci // Allocate something with interesting alignment. 176cb93a386Sopenharmony_ci void* ptr = arena.makeBytesAlignedTo(4081, 8); 177cb93a386Sopenharmony_ci REPORTER_ASSERT(r, ((intptr_t)ptr & 7) == 0); 178cb93a386Sopenharmony_ci } 179cb93a386Sopenharmony_ci} 180cb93a386Sopenharmony_ci 181cb93a386Sopenharmony_ciDEF_TEST(SkFibBlockSizes, r) { 182cb93a386Sopenharmony_ci { 183cb93a386Sopenharmony_ci SkFibBlockSizes<std::numeric_limits<uint32_t>::max()> fibs{1, 1}; 184cb93a386Sopenharmony_ci uint32_t lastSize = 1; 185cb93a386Sopenharmony_ci for (int i = 0; i < 64; i++) { 186cb93a386Sopenharmony_ci uint32_t size = fibs.nextBlockSize(); 187cb93a386Sopenharmony_ci REPORTER_ASSERT(r, lastSize <= size); 188cb93a386Sopenharmony_ci lastSize = size; 189cb93a386Sopenharmony_ci } 190cb93a386Sopenharmony_ci REPORTER_ASSERT(r, lastSize == 2971215073u); 191cb93a386Sopenharmony_ci } 192cb93a386Sopenharmony_ci { 193cb93a386Sopenharmony_ci SkFibBlockSizes<std::numeric_limits<uint32_t>::max()> fibs{0, 1024}; 194cb93a386Sopenharmony_ci uint32_t lastSize = 1; 195cb93a386Sopenharmony_ci for (int i = 0; i < 64; i++) { 196cb93a386Sopenharmony_ci uint32_t size = fibs.nextBlockSize(); 197cb93a386Sopenharmony_ci REPORTER_ASSERT(r, lastSize <= size); 198cb93a386Sopenharmony_ci lastSize = size; 199cb93a386Sopenharmony_ci REPORTER_ASSERT(r, lastSize <= std::numeric_limits<uint32_t>::max()); 200cb93a386Sopenharmony_ci } 201cb93a386Sopenharmony_ci REPORTER_ASSERT(r, lastSize == 3524578u * 1024); 202cb93a386Sopenharmony_ci } 203cb93a386Sopenharmony_ci 204cb93a386Sopenharmony_ci { 205cb93a386Sopenharmony_ci SkFibBlockSizes<std::numeric_limits<uint32_t>::max() / 2> fibs{1024, 0}; 206cb93a386Sopenharmony_ci uint32_t lastSize = 1; 207cb93a386Sopenharmony_ci for (int i = 0; i < 64; i++) { 208cb93a386Sopenharmony_ci uint32_t size = fibs.nextBlockSize(); 209cb93a386Sopenharmony_ci REPORTER_ASSERT(r, lastSize <= size); 210cb93a386Sopenharmony_ci lastSize = size; 211cb93a386Sopenharmony_ci REPORTER_ASSERT(r, lastSize <= std::numeric_limits<uint32_t>::max() / 2); 212cb93a386Sopenharmony_ci } 213cb93a386Sopenharmony_ci REPORTER_ASSERT(r, lastSize == 1346269u * 1024); 214cb93a386Sopenharmony_ci } 215cb93a386Sopenharmony_ci} 216