You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
4.6 KiB
176 lines
4.6 KiB
4 months ago
|
/*
|
||
|
* 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 "SkArenaAlloc.h"
|
||
|
#include "SkRefCnt.h"
|
||
|
#include "SkTypes.h"
|
||
|
#include "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);
|
||
|
|
||
|
}
|