Line data Source code
1 : // Copyright 2015 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/heap/spaces.h"
6 : #include "test/unittests/heap/bitmap-test-utils.h"
7 : #include "testing/gtest/include/gtest/gtest.h"
8 :
9 : namespace v8 {
10 : namespace internal {
11 :
12 : const uint32_t kBlackCell = 0xAAAAAAAA;
13 : const uint32_t kWhiteCell = 0x00000000;
14 : const uint32_t kBlackByte = 0xAA;
15 : const uint32_t kWhiteByte = 0x00;
16 :
17 : template <typename T>
18 : using BitmapTest = TestWithBitmap<T>;
19 :
20 : TYPED_TEST_SUITE(BitmapTest, BitmapTypes);
21 :
22 : using NonAtomicBitmapTest =
23 : TestWithBitmap<ConcurrentBitmap<AccessMode::NON_ATOMIC>>;
24 :
25 15418 : TEST_F(NonAtomicBitmapTest, IsZeroInitialized) {
26 : // We require all tests to start from a zero-initialized bitmap. Manually
27 : // verify this invariant here.
28 8193 : for (size_t i = 0; i < Bitmap::kSize; i++) {
29 8192 : EXPECT_EQ(raw_bitmap()[i], kWhiteByte);
30 : }
31 1 : }
32 :
33 15418 : TEST_F(NonAtomicBitmapTest, Cells) {
34 : auto bm = bitmap();
35 1 : bm->cells()[1] = kBlackCell;
36 : uint8_t* raw = raw_bitmap();
37 : int second_cell_base = Bitmap::kBytesPerCell;
38 9 : for (size_t i = 0; i < Bitmap::kBytesPerCell; i++) {
39 8 : EXPECT_EQ(raw[second_cell_base + i], kBlackByte);
40 : }
41 1 : }
42 :
43 15418 : TEST_F(NonAtomicBitmapTest, CellsCount) {
44 : int last_cell_index = bitmap()->CellsCount() - 1;
45 1 : bitmap()->cells()[last_cell_index] = kBlackCell;
46 : // Manually verify on raw memory.
47 : uint8_t* raw = raw_bitmap();
48 8193 : for (size_t i = 0; i < Bitmap::kSize; i++) {
49 : // Last cell should be set.
50 4096 : if (i >= (Bitmap::kSize - Bitmap::kBytesPerCell)) {
51 8 : EXPECT_EQ(raw[i], kBlackByte);
52 : } else {
53 8184 : EXPECT_EQ(raw[i], kWhiteByte);
54 : }
55 : }
56 1 : }
57 :
58 15418 : TEST_F(NonAtomicBitmapTest, IsClean) {
59 : auto bm = bitmap();
60 2 : EXPECT_TRUE(bm->IsClean());
61 1 : bm->cells()[0] = kBlackCell;
62 2 : EXPECT_FALSE(bm->IsClean());
63 1 : }
64 :
65 12338 : TYPED_TEST(BitmapTest, Clear) {
66 : auto bm = this->bitmap();
67 16386 : for (size_t i = 0; i < Bitmap::kSize; i++) {
68 8192 : this->raw_bitmap()[i] = 0xFFu;
69 : }
70 1 : bm->Clear();
71 16386 : for (size_t i = 0; i < Bitmap::kSize; i++) {
72 16384 : EXPECT_EQ(this->raw_bitmap()[i], 0);
73 : }
74 2 : }
75 :
76 12338 : TYPED_TEST(BitmapTest, MarkAllBits) {
77 : auto bm = this->bitmap();
78 1 : bm->MarkAllBits();
79 16386 : for (size_t i = 0; i < Bitmap::kSize; i++) {
80 16384 : EXPECT_EQ(this->raw_bitmap()[i], 0xFF);
81 : }
82 2 : }
83 :
84 12338 : TYPED_TEST(BitmapTest, ClearRange1) {
85 : auto bm = this->bitmap();
86 2 : bm->cells()[0] = kBlackCell;
87 2 : bm->cells()[1] = kBlackCell;
88 2 : bm->cells()[2] = kBlackCell;
89 1 : bm->ClearRange(0, Bitmap::kBitsPerCell + Bitmap::kBitsPerCell / 2);
90 2 : EXPECT_EQ(bm->cells()[0], kWhiteCell);
91 4 : EXPECT_EQ(bm->cells()[1], 0xAAAA0000);
92 4 : EXPECT_EQ(bm->cells()[2], kBlackCell);
93 2 : }
94 :
95 12338 : TYPED_TEST(BitmapTest, ClearRange2) {
96 : auto bm = this->bitmap();
97 2 : bm->cells()[0] = kBlackCell;
98 2 : bm->cells()[1] = kBlackCell;
99 2 : bm->cells()[2] = kBlackCell;
100 1 : bm->ClearRange(Bitmap::kBitsPerCell,
101 : Bitmap::kBitsPerCell + Bitmap::kBitsPerCell / 2);
102 2 : EXPECT_EQ(bm->cells()[0], kBlackCell);
103 4 : EXPECT_EQ(bm->cells()[1], 0xAAAA0000);
104 4 : EXPECT_EQ(bm->cells()[2], kBlackCell);
105 2 : }
106 :
107 12338 : TYPED_TEST(BitmapTest, SetAndClearRange) {
108 : auto bm = this->bitmap();
109 14 : for (int i = 0; i < 3; i++) {
110 6 : bm->SetRange(i, Bitmap::kBitsPerCell + i);
111 6 : CHECK_EQ(bm->cells()[0], 0xFFFFFFFFu << i);
112 6 : CHECK_EQ(bm->cells()[1], (1u << i) - 1);
113 6 : bm->ClearRange(i, Bitmap::kBitsPerCell + i);
114 6 : CHECK_EQ(bm->cells()[0], 0x0u);
115 6 : CHECK_EQ(bm->cells()[1], 0x0u);
116 : }
117 2 : }
118 :
119 : // AllBitsSetInRange() and AllBitsClearInRange() are only used when verifying
120 : // the heap on the main thread so they don't have atomic implementations.
121 15418 : TEST_F(NonAtomicBitmapTest, ClearMultipleRanges) {
122 : auto bm = this->bitmap();
123 :
124 : bm->SetRange(0, Bitmap::kBitsPerCell * 3);
125 1 : CHECK(bm->AllBitsSetInRange(0, Bitmap::kBitsPerCell));
126 :
127 : bm->ClearRange(Bitmap::kBitsPerCell / 2, Bitmap::kBitsPerCell);
128 : bm->ClearRange(Bitmap::kBitsPerCell,
129 : Bitmap::kBitsPerCell + Bitmap::kBitsPerCell / 2);
130 : bm->ClearRange(Bitmap::kBitsPerCell * 2 + 8, Bitmap::kBitsPerCell * 2 + 16);
131 : bm->ClearRange(Bitmap::kBitsPerCell * 2 + 24, Bitmap::kBitsPerCell * 3);
132 :
133 1 : CHECK_EQ(bm->cells()[0], 0xFFFFu);
134 1 : CHECK(bm->AllBitsSetInRange(0, Bitmap::kBitsPerCell / 2));
135 1 : CHECK(
136 : bm->AllBitsClearInRange(Bitmap::kBitsPerCell / 2, Bitmap::kBitsPerCell));
137 :
138 1 : CHECK_EQ(bm->cells()[1], 0xFFFF0000u);
139 1 : CHECK(bm->AllBitsClearInRange(
140 : Bitmap::kBitsPerCell, Bitmap::kBitsPerCell + Bitmap::kBitsPerCell / 2));
141 1 : CHECK(bm->AllBitsSetInRange(Bitmap::kBitsPerCell + Bitmap::kBitsPerCell / 2,
142 : Bitmap::kBitsPerCell * 2));
143 :
144 1 : CHECK_EQ(bm->cells()[2], 0xFF00FFu);
145 1 : CHECK(bm->AllBitsSetInRange(
146 : Bitmap::kBitsPerCell * 2,
147 : Bitmap::kBitsPerCell * 2 + Bitmap::kBitsPerCell / 4));
148 1 : CHECK(bm->AllBitsClearInRange(
149 : Bitmap::kBitsPerCell * 2 + Bitmap::kBitsPerCell / 4,
150 : Bitmap::kBitsPerCell * 2 + Bitmap::kBitsPerCell / 2));
151 1 : CHECK(bm->AllBitsSetInRange(
152 : Bitmap::kBitsPerCell * 2 + Bitmap::kBitsPerCell / 2,
153 : Bitmap::kBitsPerCell * 2 + Bitmap::kBitsPerCell / 2 +
154 : Bitmap::kBitsPerCell / 4));
155 1 : CHECK(bm->AllBitsClearInRange(Bitmap::kBitsPerCell * 2 +
156 : Bitmap::kBitsPerCell / 2 +
157 : Bitmap::kBitsPerCell / 4,
158 : Bitmap::kBitsPerCell * 3));
159 1 : }
160 :
161 : } // namespace internal
162 9249 : } // namespace v8
|