blob: 0a00f00935de19c3a5ec3bb78b23d01ed091dd5d [file] [log] [blame]
Mike Klein58b13062016-11-11 10:38:49 -05001/*
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 "SkFixedAlloc.h"
10
11namespace {
12
Mike Klein526525a2016-11-15 17:58:33 +000013 static int created, destroyed;
Mike Klein58b13062016-11-11 10:38:49 -050014
15 struct Foo {
16 Foo(int X, float Y) : x(X), y(Y) { created++; }
Mike Klein526525a2016-11-15 17:58:33 +000017 ~Foo() { destroyed++; }
Mike Klein58b13062016-11-11 10:38:49 -050018
19 int x;
20 float y;
21 };
22
23 struct Big {
24 Big() {}
25 uint32_t array[128];
26 };
27
28}
29
30DEF_TEST(FixedAlloc, r) {
31 // Basic mechanics.
32 {
33 uint8_t buf[128];
34 SkFixedAlloc fa(buf, sizeof(buf));
35
36 Foo* foo = fa.make<Foo>(3, 4.0f);
37 REPORTER_ASSERT(r, foo);
38 REPORTER_ASSERT(r, foo->x == 3);
39 REPORTER_ASSERT(r, foo->y == 4.0f);
40 REPORTER_ASSERT(r, created == 1);
Mike Klein526525a2016-11-15 17:58:33 +000041 REPORTER_ASSERT(r, destroyed == 0);
Mike Klein58b13062016-11-11 10:38:49 -050042
43 Foo* bar = fa.make<Foo>(8, 1.0f);
44 REPORTER_ASSERT(r, bar);
45 REPORTER_ASSERT(r, bar->x == 8);
46 REPORTER_ASSERT(r, bar->y == 1.0f);
47 REPORTER_ASSERT(r, created == 2);
Mike Klein526525a2016-11-15 17:58:33 +000048 REPORTER_ASSERT(r, destroyed == 0);
Mike Klein58b13062016-11-11 10:38:49 -050049
50 fa.undo();
Mike Klein526525a2016-11-15 17:58:33 +000051 REPORTER_ASSERT(r, created == 2);
52 REPORTER_ASSERT(r, destroyed == 1);
Mike Klein58b13062016-11-11 10:38:49 -050053 }
Mike Klein526525a2016-11-15 17:58:33 +000054 REPORTER_ASSERT(r, created == 2);
55 REPORTER_ASSERT(r, destroyed == 2);
Mike Klein58b13062016-11-11 10:38:49 -050056
57 {
58 // Test alignment gurantees.
59 uint8_t buf[64];
60 SkFixedAlloc fa(buf+3, sizeof(buf)-3);
61
62 Foo* foo = fa.make<Foo>(3, 4.0f);
63 REPORTER_ASSERT(r, SkIsAlign4((uintptr_t)foo));
64 REPORTER_ASSERT(r, created == 3);
Mike Klein526525a2016-11-15 17:58:33 +000065 REPORTER_ASSERT(r, destroyed == 2);
Mike Klein58b13062016-11-11 10:38:49 -050066
67 // Might as well test reset() while we're at it.
68 fa.reset();
Mike Klein526525a2016-11-15 17:58:33 +000069 REPORTER_ASSERT(r, created == 3);
70 REPORTER_ASSERT(r, destroyed == 3);
Mike Klein58b13062016-11-11 10:38:49 -050071 }
Mike Klein526525a2016-11-15 17:58:33 +000072 REPORTER_ASSERT(r, created == 3);
73 REPORTER_ASSERT(r, destroyed == 3);
Mike Klein58b13062016-11-11 10:38:49 -050074}
75
76DEF_TEST(FallbackAlloc, r) {
77 // SkFixedAlloc will eventually fail when it runs out of space in its buffer.
78 int buf[32];
79 SkFixedAlloc fixed(buf, sizeof(buf));
80 bool fixed_failed = false;
81 for (int i = 0; i < 32; i++) {
Mike Klein526525a2016-11-15 17:58:33 +000082 // (Remember, there is some overhead to each make() call.)
83 fixed_failed = fixed_failed || (fixed.make<int>(i) == nullptr);
Mike Klein58b13062016-11-11 10:38:49 -050084 }
85 REPORTER_ASSERT(r, fixed_failed);
86
87
88 // SkFallbackAlloc will always succeed, using the heap as required.
89 fixed.reset();
90 SkFallbackAlloc fallback(&fixed);
91
92 bool fallback_failed = false;
93 for (int i = 0; i < 32; i++) {
Mike Klein526525a2016-11-15 17:58:33 +000094 fallback_failed = fallback_failed || (fallback.make<int>(i) == nullptr);
Mike Klein58b13062016-11-11 10:38:49 -050095 }
96 REPORTER_ASSERT(r, !fallback_failed);
97
98
99 // Test small, big, small allocations to make sure once we go to the heap we stay there.
100 fallback.reset();
101 auto smallA = fallback.make<int>(2);
102 auto big = fallback.make<Big>();
103 auto smallB = fallback.make<int>(3);
104
105 auto in_buf = [&](void* ptr) {
106 return (uintptr_t)(buf+0 ) <= (uintptr_t)ptr
107 && (uintptr_t)(buf+32) > (uintptr_t)ptr;
108 };
109
110 REPORTER_ASSERT(r, in_buf(smallA));
111 REPORTER_ASSERT(r, !in_buf(big));
112 REPORTER_ASSERT(r, !in_buf(smallB));
113}