ArenaAllocTest.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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. #include "include/core/SkRefCnt.h"
  8. #include "include/core/SkTypes.h"
  9. #include "src/core/SkArenaAlloc.h"
  10. #include "tests/Test.h"
  11. #include <memory>
  12. #include <new>
  13. #include <type_traits>
  14. namespace {
  15. static int created, destroyed;
  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. int x;
  21. float y;
  22. };
  23. struct Big {
  24. Big() {}
  25. uint32_t array[128];
  26. };
  27. struct Node {
  28. Node(Node* n) : next(n) { created++; }
  29. ~Node() {
  30. destroyed++;
  31. if (next) {
  32. next->~Node();
  33. }
  34. }
  35. Node *next;
  36. };
  37. struct Start {
  38. ~Start() {
  39. if (start) {
  40. start->~Node();
  41. }
  42. }
  43. Node* start;
  44. };
  45. struct FooRefCnt : public SkRefCnt {
  46. FooRefCnt() : x(-2), y(-3.0f) { created++; }
  47. FooRefCnt(int X, float Y) : x(X), y(Y) { created++; }
  48. ~FooRefCnt() { destroyed++; }
  49. int x;
  50. float y;
  51. };
  52. }
  53. struct WithDtor {
  54. ~WithDtor() { }
  55. };
  56. DEF_TEST(ArenaAlloc, r) {
  57. {
  58. created = 0;
  59. destroyed = 0;
  60. SkArenaAlloc arena{0};
  61. REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
  62. Foo* foo = arena.make<Foo>(3, 4.0f);
  63. REPORTER_ASSERT(r, foo->x == 3);
  64. REPORTER_ASSERT(r, foo->y == 4.0f);
  65. REPORTER_ASSERT(r, created == 1);
  66. REPORTER_ASSERT(r, destroyed == 0);
  67. arena.makeArrayDefault<int>(10);
  68. int* zeroed = arena.makeArray<int>(10);
  69. for (int i = 0; i < 10; i++) {
  70. REPORTER_ASSERT(r, zeroed[i] == 0);
  71. }
  72. Foo* fooArray = arena.makeArrayDefault<Foo>(10);
  73. REPORTER_ASSERT(r, fooArray[3].x == -2);
  74. REPORTER_ASSERT(r, fooArray[4].y == -3.0f);
  75. REPORTER_ASSERT(r, created == 11);
  76. REPORTER_ASSERT(r, destroyed == 0);
  77. arena.make<typename std::aligned_storage<10,8>::type>();
  78. }
  79. REPORTER_ASSERT(r, created == 11);
  80. REPORTER_ASSERT(r, destroyed == 11);
  81. {
  82. created = 0;
  83. destroyed = 0;
  84. SkSTArenaAlloc<64> arena;
  85. REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
  86. Foo* foo = arena.make<Foo>(3, 4.0f);
  87. REPORTER_ASSERT(r, foo->x == 3);
  88. REPORTER_ASSERT(r, foo->y == 4.0f);
  89. REPORTER_ASSERT(r, created == 1);
  90. REPORTER_ASSERT(r, destroyed == 0);
  91. arena.makeArrayDefault<int>(10);
  92. int* zeroed = arena.makeArray<int>(10);
  93. for (int i = 0; i < 10; i++) {
  94. REPORTER_ASSERT(r, zeroed[i] == 0);
  95. }
  96. Foo* fooArray = arena.makeArrayDefault<Foo>(10);
  97. REPORTER_ASSERT(r, fooArray[3].x == -2);
  98. REPORTER_ASSERT(r, fooArray[4].y == -3.0f);
  99. REPORTER_ASSERT(r, created == 11);
  100. REPORTER_ASSERT(r, destroyed == 0);
  101. arena.make<typename std::aligned_storage<10,8>::type>();
  102. }
  103. REPORTER_ASSERT(r, created == 11);
  104. REPORTER_ASSERT(r, destroyed == 11);
  105. {
  106. created = 0;
  107. destroyed = 0;
  108. std::unique_ptr<char[]> block{new char[1024]};
  109. SkArenaAlloc arena{block.get(), 1024, 0};
  110. REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
  111. Foo* foo = arena.make<Foo>(3, 4.0f);
  112. REPORTER_ASSERT(r, foo->x == 3);
  113. REPORTER_ASSERT(r, foo->y == 4.0f);
  114. REPORTER_ASSERT(r, created == 1);
  115. REPORTER_ASSERT(r, destroyed == 0);
  116. arena.makeArrayDefault<int>(10);
  117. int* zeroed = arena.makeArray<int>(10);
  118. for (int i = 0; i < 10; i++) {
  119. REPORTER_ASSERT(r, zeroed[i] == 0);
  120. }
  121. Foo* fooArray = arena.makeArrayDefault<Foo>(10);
  122. REPORTER_ASSERT(r, fooArray[3].x == -2);
  123. REPORTER_ASSERT(r, fooArray[4].y == -3.0f);
  124. REPORTER_ASSERT(r, created == 11);
  125. REPORTER_ASSERT(r, destroyed == 0);
  126. arena.make<typename std::aligned_storage<10,8>::type>();
  127. }
  128. REPORTER_ASSERT(r, created == 11);
  129. REPORTER_ASSERT(r, destroyed == 11);
  130. {
  131. SkSTArenaAlloc<64> arena;
  132. arena.makeArrayDefault<char>(256);
  133. arena.reset();
  134. arena.reset();
  135. }
  136. {
  137. created = 0;
  138. destroyed = 0;
  139. SkSTArenaAlloc<64> arena;
  140. Start start;
  141. Node* current = nullptr;
  142. for (int i = 0; i < 128; i++) {
  143. uint64_t* temp = arena.makeArrayDefault<uint64_t>(sizeof(Node) / sizeof(Node*));
  144. current = new (temp)Node(current);
  145. }
  146. start.start = current;
  147. }
  148. REPORTER_ASSERT(r, created == 128);
  149. REPORTER_ASSERT(r, destroyed == 128);
  150. }