Home | History | Annotate | Download | only in tests
      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 {
     17         Foo() : x(-2), y(-3.0f) { created++; }
     18         Foo(int X, float Y) : x(X), y(Y) { created++; }
     19         ~Foo() { destroyed++; }
     20 
     21         int x;
     22         float y;
     23     };
     24 
     25     struct Big {
     26         Big() {}
     27         uint32_t array[128];
     28     };
     29 
     30     struct Node {
     31         Node(Node* n) : next(n) { created++; }
     32         ~Node() {
     33             destroyed++;
     34             if (next) {
     35                 next->~Node();
     36             }
     37         }
     38         Node *next;
     39     };
     40 
     41     struct Start {
     42         ~Start() {
     43             if (start) {
     44                 start->~Node();
     45             }
     46         }
     47         Node* start;
     48     };
     49 
     50     struct FooRefCnt : public SkRefCnt {
     51         FooRefCnt() : x(-2), y(-3.0f) { created++; }
     52         FooRefCnt(int X, float Y) : x(X), y(Y) { created++; }
     53         ~FooRefCnt() { destroyed++; }
     54 
     55         int x;
     56         float y;
     57     };
     58 
     59 }
     60 
     61 struct WithDtor {
     62     ~WithDtor() { }
     63 };
     64 
     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