namespace art HIDDEN { namespace gc { namespace accounting {
// SpaceBitmapTest is a CommonRuntimeTest as the test requires runtime to be initialized to enable // access to space::LargeObjectSpace::ObjectAlignment(). template <typename T> class SpaceBitmapTest : public CommonRuntimeTest {};
// Main test parameters. For each test case, we pair together a SpaceBitmap // implementation with an object alignment. The object alignment may be larger // than the underlying SpaceBitmap alignment. template <typename T, size_t kAlignment> struct SpaceBitmapTestType { using SpaceBitmap = T; static constexpr size_t GetObjectAlignment() { return kAlignment;
}
};
// This is a special case where object alignment is chosen to be the large-object // alignment determined at runtime. template <typename T> struct SpaceBitmapTestPageSizeType { using SpaceBitmap = T; static size_t GetObjectAlignment() { return space::LargeObjectSpace::ObjectAlignment();
}
};
using SpaceBitmapTestTypes =
::testing::Types<SpaceBitmapTestType<ContinuousSpaceBitmap, kObjectAlignment>, // Large objects are aligned to the OS page size, try // different supported values, including the current // runtime page size.
SpaceBitmapTestType<LargeObjectBitmap, kMinPageSize>,
SpaceBitmapTestPageSizeType<LargeObjectBitmap>,
SpaceBitmapTestType<LargeObjectBitmap, kMaxPageSize>>;
auto space_bitmap(TypeParam::SpaceBitmap::Create("test bitmap", heap_begin, heap_capacity));
EXPECT_TRUE(space_bitmap.IsValid());
// Set all the odd bits in the first BitsPerIntPtrT * 3 to one. for (size_t j = 0; j < kBitsPerIntPtrT * 3; ++j) { const mirror::Object* obj = reinterpret_cast<mirror::Object*>(heap_begin + j * gObjectAlignment); if (reinterpret_cast<uintptr_t>(obj) & 0xF) {
space_bitmap.Set(obj);
}
} // Try every possible starting bit in the first word. Then for each starting bit, try each // possible length up to a maximum of `kBitsPerIntPtrT * 2 - 1` bits. // This handles all the cases, having runs which start and end on the same word, and different // words. for (size_t i = 0; i < static_cast<size_t>(kBitsPerIntPtrT); ++i) {
mirror::Object* start = reinterpret_cast<mirror::Object*>(heap_begin + i * gObjectAlignment); for (size_t j = 0; j < static_cast<size_t>(kBitsPerIntPtrT * 2); ++j) {
mirror::Object* end = reinterpret_cast<mirror::Object*>(heap_begin + (i + j) * gObjectAlignment);
BitmapVerify(&space_bitmap, start, end);
}
}
}
auto bitmap(TypeParam::SpaceBitmap::Create("test bitmap", heap_begin, heap_capacity));
EXPECT_TRUE(bitmap.IsValid());
// Set all of the bits in the bitmap. for (size_t j = 0; j < heap_capacity; j += gObjectAlignment) { const mirror::Object* obj = reinterpret_cast<mirror::Object*>(heap_begin + j);
bitmap.Set(obj);
}
std::vector<std::pair<uintptr_t, uintptr_t>> ranges = {
{0, RoundUp(10 * KB, gObjectAlignment) + gObjectAlignment},
{gObjectAlignment, gObjectAlignment},
{gObjectAlignment, 2 * gObjectAlignment},
{gObjectAlignment, 5 * gObjectAlignment},
{RoundUp(1 * KB, gObjectAlignment) + gObjectAlignment,
RoundUp(2 * KB, gObjectAlignment) + 5 * gObjectAlignment},
}; // Try clearing a few ranges. for (const std::pair<uintptr_t, uintptr_t>& range : ranges) { const mirror::Object* obj_begin = reinterpret_cast<mirror::Object*>(heap_begin + range.first); const mirror::Object* obj_end = reinterpret_cast<mirror::Object*>(heap_begin + range.second);
bitmap.ClearRange(obj_begin, obj_end); // Boundaries should still be marked. for (uintptr_t i = 0; i < range.first; i += gObjectAlignment) {
EXPECT_TRUE(bitmap.Test(reinterpret_cast<mirror::Object*>(heap_begin + i)));
} for (uintptr_t i = range.second; i < range.second + page_size; i += gObjectAlignment) {
EXPECT_TRUE(bitmap.Test(reinterpret_cast<mirror::Object*>(heap_begin + i)));
} // Everything inside should be cleared. for (uintptr_t i = range.first; i < range.second; i += gObjectAlignment) {
EXPECT_FALSE(bitmap.Test(reinterpret_cast<mirror::Object*>(heap_begin + i)));
bitmap.Set(reinterpret_cast<mirror::Object*>(heap_begin + i));
}
}
}
class SimpleCounter { public: explicit SimpleCounter(size_t* counter) : count_(counter) {}
size_t manual = 0; for (uintptr_t k = offset; k < end; k += alignment) { if (space_bitmap.Test(reinterpret_cast<mirror::Object*>(heap_begin + k))) {
manual++;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.