1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2012 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #include "space_bitmap.h"
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker #include <stdint.h>
20*795d594fSAndroid Build Coastguard Worker #include <memory>
21*795d594fSAndroid Build Coastguard Worker
22*795d594fSAndroid Build Coastguard Worker #include "base/mutex.h"
23*795d594fSAndroid Build Coastguard Worker #include "common_runtime_test.h"
24*795d594fSAndroid Build Coastguard Worker #include "gc/space/large_object_space.h"
25*795d594fSAndroid Build Coastguard Worker #include "runtime_globals.h"
26*795d594fSAndroid Build Coastguard Worker #include "space_bitmap-inl.h"
27*795d594fSAndroid Build Coastguard Worker
28*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
29*795d594fSAndroid Build Coastguard Worker namespace gc {
30*795d594fSAndroid Build Coastguard Worker namespace accounting {
31*795d594fSAndroid Build Coastguard Worker
32*795d594fSAndroid Build Coastguard Worker // SpaceBitmapTest is a CommonRuntimeTest as the test requires runtime to be initialized to enable
33*795d594fSAndroid Build Coastguard Worker // access to space::LargeObjectSpace::ObjectAlignment().
34*795d594fSAndroid Build Coastguard Worker template <typename T>
35*795d594fSAndroid Build Coastguard Worker class SpaceBitmapTest : public CommonRuntimeTest {};
36*795d594fSAndroid Build Coastguard Worker
37*795d594fSAndroid Build Coastguard Worker // Main test parameters. For each test case, we pair together a SpaceBitmap
38*795d594fSAndroid Build Coastguard Worker // implementation with an object alignment. The object alignment may be larger
39*795d594fSAndroid Build Coastguard Worker // than the underlying SpaceBitmap alignment.
40*795d594fSAndroid Build Coastguard Worker template <typename T, size_t kAlignment>
41*795d594fSAndroid Build Coastguard Worker struct SpaceBitmapTestType {
42*795d594fSAndroid Build Coastguard Worker using SpaceBitmap = T;
GetObjectAlignmentart::gc::accounting::SpaceBitmapTestType43*795d594fSAndroid Build Coastguard Worker static constexpr size_t GetObjectAlignment() {
44*795d594fSAndroid Build Coastguard Worker return kAlignment;
45*795d594fSAndroid Build Coastguard Worker }
46*795d594fSAndroid Build Coastguard Worker };
47*795d594fSAndroid Build Coastguard Worker
48*795d594fSAndroid Build Coastguard Worker // This is a special case where object alignment is chosen to be the large-object
49*795d594fSAndroid Build Coastguard Worker // alignment determined at runtime.
50*795d594fSAndroid Build Coastguard Worker template <typename T>
51*795d594fSAndroid Build Coastguard Worker struct SpaceBitmapTestPageSizeType {
52*795d594fSAndroid Build Coastguard Worker using SpaceBitmap = T;
GetObjectAlignmentart::gc::accounting::SpaceBitmapTestPageSizeType53*795d594fSAndroid Build Coastguard Worker static size_t GetObjectAlignment() {
54*795d594fSAndroid Build Coastguard Worker return space::LargeObjectSpace::ObjectAlignment();
55*795d594fSAndroid Build Coastguard Worker }
56*795d594fSAndroid Build Coastguard Worker };
57*795d594fSAndroid Build Coastguard Worker
58*795d594fSAndroid Build Coastguard Worker using SpaceBitmapTestTypes =
59*795d594fSAndroid Build Coastguard Worker ::testing::Types<SpaceBitmapTestType<ContinuousSpaceBitmap, kObjectAlignment>,
60*795d594fSAndroid Build Coastguard Worker // Large objects are aligned to the OS page size, try
61*795d594fSAndroid Build Coastguard Worker // different supported values, including the current
62*795d594fSAndroid Build Coastguard Worker // runtime page size.
63*795d594fSAndroid Build Coastguard Worker SpaceBitmapTestType<LargeObjectBitmap, kMinPageSize>,
64*795d594fSAndroid Build Coastguard Worker SpaceBitmapTestPageSizeType<LargeObjectBitmap>,
65*795d594fSAndroid Build Coastguard Worker SpaceBitmapTestType<LargeObjectBitmap, kMaxPageSize>>;
66*795d594fSAndroid Build Coastguard Worker
67*795d594fSAndroid Build Coastguard Worker TYPED_TEST_CASE(SpaceBitmapTest, SpaceBitmapTestTypes);
68*795d594fSAndroid Build Coastguard Worker
TYPED_TEST(SpaceBitmapTest,Init)69*795d594fSAndroid Build Coastguard Worker TYPED_TEST(SpaceBitmapTest, Init) {
70*795d594fSAndroid Build Coastguard Worker uint8_t* heap_begin = reinterpret_cast<uint8_t*>(0x10000000);
71*795d594fSAndroid Build Coastguard Worker size_t heap_capacity = 16 * MB;
72*795d594fSAndroid Build Coastguard Worker auto space_bitmap(TypeParam::SpaceBitmap::Create("test bitmap", heap_begin, heap_capacity));
73*795d594fSAndroid Build Coastguard Worker EXPECT_TRUE(space_bitmap.IsValid());
74*795d594fSAndroid Build Coastguard Worker }
75*795d594fSAndroid Build Coastguard Worker
76*795d594fSAndroid Build Coastguard Worker template <typename SpaceBitmap>
77*795d594fSAndroid Build Coastguard Worker class BitmapVerify {
78*795d594fSAndroid Build Coastguard Worker public:
BitmapVerify(SpaceBitmap * bitmap,const mirror::Object * begin,const mirror::Object * end)79*795d594fSAndroid Build Coastguard Worker BitmapVerify(SpaceBitmap* bitmap, const mirror::Object* begin,
80*795d594fSAndroid Build Coastguard Worker const mirror::Object* end)
81*795d594fSAndroid Build Coastguard Worker : bitmap_(bitmap),
82*795d594fSAndroid Build Coastguard Worker begin_(begin),
83*795d594fSAndroid Build Coastguard Worker end_(end) {}
84*795d594fSAndroid Build Coastguard Worker
operator ()(const mirror::Object * obj)85*795d594fSAndroid Build Coastguard Worker void operator()(const mirror::Object* obj) {
86*795d594fSAndroid Build Coastguard Worker EXPECT_TRUE(obj >= begin_);
87*795d594fSAndroid Build Coastguard Worker EXPECT_TRUE(obj <= end_);
88*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(bitmap_->Test(obj), ((reinterpret_cast<uintptr_t>(obj) & 0xF) != 0));
89*795d594fSAndroid Build Coastguard Worker }
90*795d594fSAndroid Build Coastguard Worker
91*795d594fSAndroid Build Coastguard Worker SpaceBitmap* const bitmap_;
92*795d594fSAndroid Build Coastguard Worker const mirror::Object* begin_;
93*795d594fSAndroid Build Coastguard Worker const mirror::Object* end_;
94*795d594fSAndroid Build Coastguard Worker };
95*795d594fSAndroid Build Coastguard Worker
TYPED_TEST(SpaceBitmapTest,ScanRange)96*795d594fSAndroid Build Coastguard Worker TYPED_TEST(SpaceBitmapTest, ScanRange) {
97*795d594fSAndroid Build Coastguard Worker uint8_t* heap_begin = reinterpret_cast<uint8_t*>(0x10000000);
98*795d594fSAndroid Build Coastguard Worker size_t heap_capacity = 16 * MB;
99*795d594fSAndroid Build Coastguard Worker const size_t gObjectAlignment = TypeParam::GetObjectAlignment();
100*795d594fSAndroid Build Coastguard Worker
101*795d594fSAndroid Build Coastguard Worker auto space_bitmap(TypeParam::SpaceBitmap::Create("test bitmap", heap_begin, heap_capacity));
102*795d594fSAndroid Build Coastguard Worker EXPECT_TRUE(space_bitmap.IsValid());
103*795d594fSAndroid Build Coastguard Worker
104*795d594fSAndroid Build Coastguard Worker // Set all the odd bits in the first BitsPerIntPtrT * 3 to one.
105*795d594fSAndroid Build Coastguard Worker for (size_t j = 0; j < kBitsPerIntPtrT * 3; ++j) {
106*795d594fSAndroid Build Coastguard Worker const mirror::Object* obj =
107*795d594fSAndroid Build Coastguard Worker reinterpret_cast<mirror::Object*>(heap_begin + j * gObjectAlignment);
108*795d594fSAndroid Build Coastguard Worker if (reinterpret_cast<uintptr_t>(obj) & 0xF) {
109*795d594fSAndroid Build Coastguard Worker space_bitmap.Set(obj);
110*795d594fSAndroid Build Coastguard Worker }
111*795d594fSAndroid Build Coastguard Worker }
112*795d594fSAndroid Build Coastguard Worker // Try every possible starting bit in the first word. Then for each starting bit, try each
113*795d594fSAndroid Build Coastguard Worker // possible length up to a maximum of `kBitsPerIntPtrT * 2 - 1` bits.
114*795d594fSAndroid Build Coastguard Worker // This handles all the cases, having runs which start and end on the same word, and different
115*795d594fSAndroid Build Coastguard Worker // words.
116*795d594fSAndroid Build Coastguard Worker for (size_t i = 0; i < static_cast<size_t>(kBitsPerIntPtrT); ++i) {
117*795d594fSAndroid Build Coastguard Worker mirror::Object* start =
118*795d594fSAndroid Build Coastguard Worker reinterpret_cast<mirror::Object*>(heap_begin + i * gObjectAlignment);
119*795d594fSAndroid Build Coastguard Worker for (size_t j = 0; j < static_cast<size_t>(kBitsPerIntPtrT * 2); ++j) {
120*795d594fSAndroid Build Coastguard Worker mirror::Object* end =
121*795d594fSAndroid Build Coastguard Worker reinterpret_cast<mirror::Object*>(heap_begin + (i + j) * gObjectAlignment);
122*795d594fSAndroid Build Coastguard Worker BitmapVerify(&space_bitmap, start, end);
123*795d594fSAndroid Build Coastguard Worker }
124*795d594fSAndroid Build Coastguard Worker }
125*795d594fSAndroid Build Coastguard Worker }
126*795d594fSAndroid Build Coastguard Worker
TYPED_TEST(SpaceBitmapTest,ClearRange)127*795d594fSAndroid Build Coastguard Worker TYPED_TEST(SpaceBitmapTest, ClearRange) {
128*795d594fSAndroid Build Coastguard Worker const size_t page_size = MemMap::GetPageSize();
129*795d594fSAndroid Build Coastguard Worker uint8_t* heap_begin = reinterpret_cast<uint8_t*>(0x10000000);
130*795d594fSAndroid Build Coastguard Worker size_t heap_capacity = 16 * MB;
131*795d594fSAndroid Build Coastguard Worker const size_t gObjectAlignment = TypeParam::GetObjectAlignment();
132*795d594fSAndroid Build Coastguard Worker
133*795d594fSAndroid Build Coastguard Worker auto bitmap(TypeParam::SpaceBitmap::Create("test bitmap", heap_begin, heap_capacity));
134*795d594fSAndroid Build Coastguard Worker EXPECT_TRUE(bitmap.IsValid());
135*795d594fSAndroid Build Coastguard Worker
136*795d594fSAndroid Build Coastguard Worker // Set all of the bits in the bitmap.
137*795d594fSAndroid Build Coastguard Worker for (size_t j = 0; j < heap_capacity; j += gObjectAlignment) {
138*795d594fSAndroid Build Coastguard Worker const mirror::Object* obj = reinterpret_cast<mirror::Object*>(heap_begin + j);
139*795d594fSAndroid Build Coastguard Worker bitmap.Set(obj);
140*795d594fSAndroid Build Coastguard Worker }
141*795d594fSAndroid Build Coastguard Worker
142*795d594fSAndroid Build Coastguard Worker std::vector<std::pair<uintptr_t, uintptr_t>> ranges = {
143*795d594fSAndroid Build Coastguard Worker {0, RoundUp(10 * KB, gObjectAlignment) + gObjectAlignment},
144*795d594fSAndroid Build Coastguard Worker {gObjectAlignment, gObjectAlignment},
145*795d594fSAndroid Build Coastguard Worker {gObjectAlignment, 2 * gObjectAlignment},
146*795d594fSAndroid Build Coastguard Worker {gObjectAlignment, 5 * gObjectAlignment},
147*795d594fSAndroid Build Coastguard Worker {RoundUp(1 * KB, gObjectAlignment) + gObjectAlignment,
148*795d594fSAndroid Build Coastguard Worker RoundUp(2 * KB, gObjectAlignment) + 5 * gObjectAlignment},
149*795d594fSAndroid Build Coastguard Worker };
150*795d594fSAndroid Build Coastguard Worker // Try clearing a few ranges.
151*795d594fSAndroid Build Coastguard Worker for (const std::pair<uintptr_t, uintptr_t>& range : ranges) {
152*795d594fSAndroid Build Coastguard Worker const mirror::Object* obj_begin = reinterpret_cast<mirror::Object*>(heap_begin + range.first);
153*795d594fSAndroid Build Coastguard Worker const mirror::Object* obj_end = reinterpret_cast<mirror::Object*>(heap_begin + range.second);
154*795d594fSAndroid Build Coastguard Worker bitmap.ClearRange(obj_begin, obj_end);
155*795d594fSAndroid Build Coastguard Worker // Boundaries should still be marked.
156*795d594fSAndroid Build Coastguard Worker for (uintptr_t i = 0; i < range.first; i += gObjectAlignment) {
157*795d594fSAndroid Build Coastguard Worker EXPECT_TRUE(bitmap.Test(reinterpret_cast<mirror::Object*>(heap_begin + i)));
158*795d594fSAndroid Build Coastguard Worker }
159*795d594fSAndroid Build Coastguard Worker for (uintptr_t i = range.second; i < range.second + page_size; i += gObjectAlignment) {
160*795d594fSAndroid Build Coastguard Worker EXPECT_TRUE(bitmap.Test(reinterpret_cast<mirror::Object*>(heap_begin + i)));
161*795d594fSAndroid Build Coastguard Worker }
162*795d594fSAndroid Build Coastguard Worker // Everything inside should be cleared.
163*795d594fSAndroid Build Coastguard Worker for (uintptr_t i = range.first; i < range.second; i += gObjectAlignment) {
164*795d594fSAndroid Build Coastguard Worker EXPECT_FALSE(bitmap.Test(reinterpret_cast<mirror::Object*>(heap_begin + i)));
165*795d594fSAndroid Build Coastguard Worker bitmap.Set(reinterpret_cast<mirror::Object*>(heap_begin + i));
166*795d594fSAndroid Build Coastguard Worker }
167*795d594fSAndroid Build Coastguard Worker }
168*795d594fSAndroid Build Coastguard Worker }
169*795d594fSAndroid Build Coastguard Worker
170*795d594fSAndroid Build Coastguard Worker
171*795d594fSAndroid Build Coastguard Worker class SimpleCounter {
172*795d594fSAndroid Build Coastguard Worker public:
SimpleCounter(size_t * counter)173*795d594fSAndroid Build Coastguard Worker explicit SimpleCounter(size_t* counter) : count_(counter) {}
174*795d594fSAndroid Build Coastguard Worker
operator ()(mirror::Object * obj) const175*795d594fSAndroid Build Coastguard Worker void operator()([[maybe_unused]] mirror::Object* obj) const { (*count_)++; }
176*795d594fSAndroid Build Coastguard Worker
177*795d594fSAndroid Build Coastguard Worker size_t* const count_;
178*795d594fSAndroid Build Coastguard Worker };
179*795d594fSAndroid Build Coastguard Worker
180*795d594fSAndroid Build Coastguard Worker class RandGen {
181*795d594fSAndroid Build Coastguard Worker public:
RandGen(uint32_t seed)182*795d594fSAndroid Build Coastguard Worker explicit RandGen(uint32_t seed) : val_(seed) {}
183*795d594fSAndroid Build Coastguard Worker
next()184*795d594fSAndroid Build Coastguard Worker uint32_t next() {
185*795d594fSAndroid Build Coastguard Worker val_ = val_ * 48271 % 2147483647 + 13;
186*795d594fSAndroid Build Coastguard Worker return val_;
187*795d594fSAndroid Build Coastguard Worker }
188*795d594fSAndroid Build Coastguard Worker
189*795d594fSAndroid Build Coastguard Worker uint32_t val_;
190*795d594fSAndroid Build Coastguard Worker };
191*795d594fSAndroid Build Coastguard Worker
192*795d594fSAndroid Build Coastguard Worker template <typename SpaceBitmap, typename TestFn>
RunTest(size_t alignment,TestFn && fn)193*795d594fSAndroid Build Coastguard Worker static void RunTest(size_t alignment, TestFn&& fn) NO_THREAD_SAFETY_ANALYSIS {
194*795d594fSAndroid Build Coastguard Worker uint8_t* heap_begin = reinterpret_cast<uint8_t*>(0x10000000);
195*795d594fSAndroid Build Coastguard Worker size_t heap_capacity = 16 * MB;
196*795d594fSAndroid Build Coastguard Worker
197*795d594fSAndroid Build Coastguard Worker // Seed with 0x1234 for reproducability.
198*795d594fSAndroid Build Coastguard Worker RandGen r(0x1234);
199*795d594fSAndroid Build Coastguard Worker
200*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 5 ; ++i) {
201*795d594fSAndroid Build Coastguard Worker SpaceBitmap space_bitmap(SpaceBitmap::Create("test bitmap", heap_begin, heap_capacity));
202*795d594fSAndroid Build Coastguard Worker
203*795d594fSAndroid Build Coastguard Worker for (int j = 0; j < 10000; ++j) {
204*795d594fSAndroid Build Coastguard Worker size_t offset = RoundDown(r.next() % heap_capacity, alignment);
205*795d594fSAndroid Build Coastguard Worker bool set = r.next() % 2 == 1;
206*795d594fSAndroid Build Coastguard Worker
207*795d594fSAndroid Build Coastguard Worker if (set) {
208*795d594fSAndroid Build Coastguard Worker space_bitmap.Set(reinterpret_cast<mirror::Object*>(heap_begin + offset));
209*795d594fSAndroid Build Coastguard Worker } else {
210*795d594fSAndroid Build Coastguard Worker space_bitmap.Clear(reinterpret_cast<mirror::Object*>(heap_begin + offset));
211*795d594fSAndroid Build Coastguard Worker }
212*795d594fSAndroid Build Coastguard Worker }
213*795d594fSAndroid Build Coastguard Worker
214*795d594fSAndroid Build Coastguard Worker for (int j = 0; j < 50; ++j) {
215*795d594fSAndroid Build Coastguard Worker const size_t offset = RoundDown(r.next() % heap_capacity, alignment);
216*795d594fSAndroid Build Coastguard Worker const size_t remain = heap_capacity - offset;
217*795d594fSAndroid Build Coastguard Worker const size_t end = offset + RoundDown(r.next() % (remain + 1), alignment);
218*795d594fSAndroid Build Coastguard Worker
219*795d594fSAndroid Build Coastguard Worker size_t manual = 0;
220*795d594fSAndroid Build Coastguard Worker for (uintptr_t k = offset; k < end; k += alignment) {
221*795d594fSAndroid Build Coastguard Worker if (space_bitmap.Test(reinterpret_cast<mirror::Object*>(heap_begin + k))) {
222*795d594fSAndroid Build Coastguard Worker manual++;
223*795d594fSAndroid Build Coastguard Worker }
224*795d594fSAndroid Build Coastguard Worker }
225*795d594fSAndroid Build Coastguard Worker
226*795d594fSAndroid Build Coastguard Worker uintptr_t range_begin = reinterpret_cast<uintptr_t>(heap_begin) + offset;
227*795d594fSAndroid Build Coastguard Worker uintptr_t range_end = reinterpret_cast<uintptr_t>(heap_begin) + end;
228*795d594fSAndroid Build Coastguard Worker
229*795d594fSAndroid Build Coastguard Worker fn(&space_bitmap, range_begin, range_end, manual);
230*795d594fSAndroid Build Coastguard Worker }
231*795d594fSAndroid Build Coastguard Worker }
232*795d594fSAndroid Build Coastguard Worker }
233*795d594fSAndroid Build Coastguard Worker
TYPED_TEST(SpaceBitmapTest,VisitorAlignment)234*795d594fSAndroid Build Coastguard Worker TYPED_TEST(SpaceBitmapTest, VisitorAlignment) {
235*795d594fSAndroid Build Coastguard Worker using SpaceBitmap = typename TypeParam::SpaceBitmap;
236*795d594fSAndroid Build Coastguard Worker auto count_test_fn = [](SpaceBitmap* space_bitmap,
237*795d594fSAndroid Build Coastguard Worker uintptr_t range_begin,
238*795d594fSAndroid Build Coastguard Worker uintptr_t range_end,
239*795d594fSAndroid Build Coastguard Worker size_t manual_count) {
240*795d594fSAndroid Build Coastguard Worker size_t count = 0;
241*795d594fSAndroid Build Coastguard Worker auto count_fn = [&count]([[maybe_unused]] mirror::Object* obj) { count++; };
242*795d594fSAndroid Build Coastguard Worker space_bitmap->VisitMarkedRange(range_begin, range_end, count_fn);
243*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(count, manual_count);
244*795d594fSAndroid Build Coastguard Worker };
245*795d594fSAndroid Build Coastguard Worker RunTest<SpaceBitmap>(TypeParam::GetObjectAlignment(), count_test_fn);
246*795d594fSAndroid Build Coastguard Worker }
247*795d594fSAndroid Build Coastguard Worker
TYPED_TEST(SpaceBitmapTest,OrderAlignment)248*795d594fSAndroid Build Coastguard Worker TYPED_TEST(SpaceBitmapTest, OrderAlignment) {
249*795d594fSAndroid Build Coastguard Worker using SpaceBitmap = typename TypeParam::SpaceBitmap;
250*795d594fSAndroid Build Coastguard Worker auto order_test_fn = [](SpaceBitmap* space_bitmap,
251*795d594fSAndroid Build Coastguard Worker uintptr_t range_begin,
252*795d594fSAndroid Build Coastguard Worker uintptr_t range_end,
253*795d594fSAndroid Build Coastguard Worker size_t manual_count)
254*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
255*795d594fSAndroid Build Coastguard Worker mirror::Object* last_ptr = nullptr;
256*795d594fSAndroid Build Coastguard Worker auto order_check = [&last_ptr](mirror::Object* obj) {
257*795d594fSAndroid Build Coastguard Worker EXPECT_LT(last_ptr, obj);
258*795d594fSAndroid Build Coastguard Worker last_ptr = obj;
259*795d594fSAndroid Build Coastguard Worker };
260*795d594fSAndroid Build Coastguard Worker
261*795d594fSAndroid Build Coastguard Worker // Test complete walk.
262*795d594fSAndroid Build Coastguard Worker space_bitmap->Walk(order_check);
263*795d594fSAndroid Build Coastguard Worker if (manual_count > 0) {
264*795d594fSAndroid Build Coastguard Worker EXPECT_NE(nullptr, last_ptr);
265*795d594fSAndroid Build Coastguard Worker }
266*795d594fSAndroid Build Coastguard Worker
267*795d594fSAndroid Build Coastguard Worker // Test range.
268*795d594fSAndroid Build Coastguard Worker last_ptr = nullptr;
269*795d594fSAndroid Build Coastguard Worker space_bitmap->VisitMarkedRange(range_begin, range_end, order_check);
270*795d594fSAndroid Build Coastguard Worker if (manual_count > 0) {
271*795d594fSAndroid Build Coastguard Worker EXPECT_NE(nullptr, last_ptr);
272*795d594fSAndroid Build Coastguard Worker }
273*795d594fSAndroid Build Coastguard Worker };
274*795d594fSAndroid Build Coastguard Worker RunTest<SpaceBitmap>(TypeParam::GetObjectAlignment(), order_test_fn);
275*795d594fSAndroid Build Coastguard Worker }
276*795d594fSAndroid Build Coastguard Worker
277*795d594fSAndroid Build Coastguard Worker } // namespace accounting
278*795d594fSAndroid Build Coastguard Worker } // namespace gc
279*795d594fSAndroid Build Coastguard Worker } // namespace art
280