xref: /aosp_15_r20/art/runtime/gc/accounting/space_bitmap_test.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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