1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "space_bitmap.h" 18 19 #include <stdint.h> 20 #include <memory> 21 22 #include "common_runtime_test.h" 23 #include "globals.h" 24 #include "space_bitmap-inl.h" 25 26 namespace art { 27 namespace gc { 28 namespace accounting { 29 30 class SpaceBitmapTest : public CommonRuntimeTest {}; 31 32 TEST_F(SpaceBitmapTest, Init) { 33 uint8_t* heap_begin = reinterpret_cast<uint8_t*>(0x10000000); 34 size_t heap_capacity = 16 * MB; 35 std::unique_ptr<ContinuousSpaceBitmap> space_bitmap( 36 ContinuousSpaceBitmap::Create("test bitmap", heap_begin, heap_capacity)); 37 EXPECT_TRUE(space_bitmap.get() != nullptr); 38 } 39 40 class BitmapVerify { 41 public: 42 BitmapVerify(ContinuousSpaceBitmap* bitmap, const mirror::Object* begin, 43 const mirror::Object* end) 44 : bitmap_(bitmap), 45 begin_(begin), 46 end_(end) {} 47 48 void operator()(const mirror::Object* obj) { 49 EXPECT_TRUE(obj >= begin_); 50 EXPECT_TRUE(obj <= end_); 51 EXPECT_EQ(bitmap_->Test(obj), ((reinterpret_cast<uintptr_t>(obj) & 0xF) != 0)); 52 } 53 54 ContinuousSpaceBitmap* const bitmap_; 55 const mirror::Object* begin_; 56 const mirror::Object* end_; 57 }; 58 59 TEST_F(SpaceBitmapTest, ScanRange) { 60 uint8_t* heap_begin = reinterpret_cast<uint8_t*>(0x10000000); 61 size_t heap_capacity = 16 * MB; 62 63 std::unique_ptr<ContinuousSpaceBitmap> space_bitmap( 64 ContinuousSpaceBitmap::Create("test bitmap", heap_begin, heap_capacity)); 65 EXPECT_TRUE(space_bitmap.get() != nullptr); 66 67 // Set all the odd bits in the first BitsPerIntPtrT * 3 to one. 68 for (size_t j = 0; j < kBitsPerIntPtrT * 3; ++j) { 69 const mirror::Object* obj = 70 reinterpret_cast<mirror::Object*>(heap_begin + j * kObjectAlignment); 71 if (reinterpret_cast<uintptr_t>(obj) & 0xF) { 72 space_bitmap->Set(obj); 73 } 74 } 75 // Try every possible starting bit in the first word. Then for each starting bit, try each 76 // possible length up to a maximum of kBitsPerWord * 2 - 1 bits. 77 // This handles all the cases, having runs which start and end on the same word, and different 78 // words. 79 for (size_t i = 0; i < static_cast<size_t>(kBitsPerIntPtrT); ++i) { 80 mirror::Object* start = 81 reinterpret_cast<mirror::Object*>(heap_begin + i * kObjectAlignment); 82 for (size_t j = 0; j < static_cast<size_t>(kBitsPerIntPtrT * 2); ++j) { 83 mirror::Object* end = 84 reinterpret_cast<mirror::Object*>(heap_begin + (i + j) * kObjectAlignment); 85 BitmapVerify(space_bitmap.get(), start, end); 86 } 87 } 88 } 89 90 class SimpleCounter { 91 public: 92 explicit SimpleCounter(size_t* counter) : count_(counter) {} 93 94 void operator()(mirror::Object* obj ATTRIBUTE_UNUSED) const { 95 (*count_)++; 96 } 97 98 size_t* const count_; 99 }; 100 101 class RandGen { 102 public: 103 explicit RandGen(uint32_t seed) : val_(seed) {} 104 105 uint32_t next() { 106 val_ = val_ * 48271 % 2147483647; 107 return val_; 108 } 109 110 uint32_t val_; 111 }; 112 113 template <size_t kAlignment> 114 void RunTest() NO_THREAD_SAFETY_ANALYSIS { 115 uint8_t* heap_begin = reinterpret_cast<uint8_t*>(0x10000000); 116 size_t heap_capacity = 16 * MB; 117 118 // Seed with 0x1234 for reproducability. 119 RandGen r(0x1234); 120 121 122 for (int i = 0; i < 5 ; ++i) { 123 std::unique_ptr<ContinuousSpaceBitmap> space_bitmap( 124 ContinuousSpaceBitmap::Create("test bitmap", heap_begin, heap_capacity)); 125 126 for (int j = 0; j < 10000; ++j) { 127 size_t offset = RoundDown(r.next() % heap_capacity, kAlignment); 128 bool set = r.next() % 2 == 1; 129 130 if (set) { 131 space_bitmap->Set(reinterpret_cast<mirror::Object*>(heap_begin + offset)); 132 } else { 133 space_bitmap->Clear(reinterpret_cast<mirror::Object*>(heap_begin + offset)); 134 } 135 } 136 137 for (int j = 0; j < 50; ++j) { 138 size_t count = 0; 139 SimpleCounter c(&count); 140 141 size_t offset = RoundDown(r.next() % heap_capacity, kAlignment); 142 size_t remain = heap_capacity - offset; 143 size_t end = offset + RoundDown(r.next() % (remain + 1), kAlignment); 144 145 space_bitmap->VisitMarkedRange(reinterpret_cast<uintptr_t>(heap_begin) + offset, 146 reinterpret_cast<uintptr_t>(heap_begin) + end, c); 147 148 size_t manual = 0; 149 for (uintptr_t k = offset; k < end; k += kAlignment) { 150 if (space_bitmap->Test(reinterpret_cast<mirror::Object*>(heap_begin + k))) { 151 manual++; 152 } 153 } 154 155 EXPECT_EQ(count, manual); 156 } 157 } 158 } 159 160 TEST_F(SpaceBitmapTest, VisitorObjectAlignment) { 161 RunTest<kObjectAlignment>(); 162 } 163 164 TEST_F(SpaceBitmapTest, VisitorPageAlignment) { 165 RunTest<kPageSize>(); 166 } 167 168 } // namespace accounting 169 } // namespace gc 170 } // namespace art 171