Rewrite bits of RegionSpace::ClearFromSpace.
To make it clearer what the loop is for.
Test: test.py
Change-Id: Iae5d8351fd294a4f43dd74dc714d644c9d8f0c7f
diff --git a/runtime/gc/space/region_space.cc b/runtime/gc/space/region_space.cc
index b8f1e8f..fe3c1c0 100644
--- a/runtime/gc/space/region_space.cc
+++ b/runtime/gc/space/region_space.cc
@@ -290,6 +290,7 @@
clear_region(r);
} else if (r->IsInUnevacFromSpace()) {
if (r->LiveBytes() == 0) {
+ DCHECK(!r->IsLargeTail());
// Special case for 0 live bytes, this means all of the objects in the region are dead and
// we can clear it. This is important for large objects since we must not visit dead ones in
// RegionSpace::Walk because they may contain dangling references to invalid objects.
@@ -312,28 +313,29 @@
reinterpret_cast<mirror::Object*>(r->Begin() + free_regions * kRegionSize));
continue;
}
- size_t full_count = 0;
- while (r->IsInUnevacFromSpace()) {
- Region* const cur = ®ions_[i + full_count];
- if (i + full_count >= num_regions_ ||
- cur->LiveBytes() != static_cast<size_t>(cur->Top() - cur->Begin())) {
- break;
- }
- DCHECK(cur->IsInUnevacFromSpace());
- if (full_count != 0) {
- cur->SetUnevacFromSpaceAsToSpace();
- }
- ++full_count;
- }
- // Note that r is the full_count == 0 iteration since it is not handled by the loop.
r->SetUnevacFromSpaceAsToSpace();
- if (full_count >= 1) {
+ if (r->AllAllocatedBytesAreLive()) {
+ // Try to optimize the number of ClearRange calls by checking whether the next regions
+ // can also be cleared.
+ size_t regions_to_clear_bitmap = 1;
+ while (i + regions_to_clear_bitmap < num_regions_) {
+ Region* const cur = ®ions_[i + regions_to_clear_bitmap];
+ if (!cur->AllAllocatedBytesAreLive()) {
+ DCHECK(!cur->IsLargeTail());
+ break;
+ }
+ CHECK(cur->IsInUnevacFromSpace());
+ cur->SetUnevacFromSpaceAsToSpace();
+ ++regions_to_clear_bitmap;
+ }
+
GetLiveBitmap()->ClearRange(
reinterpret_cast<mirror::Object*>(r->Begin()),
- reinterpret_cast<mirror::Object*>(r->Begin() + full_count * kRegionSize));
- // Skip over extra regions we cleared.
+ reinterpret_cast<mirror::Object*>(r->Begin() + regions_to_clear_bitmap * kRegionSize));
+ // Skip over extra regions we cleared the bitmaps: we don't need to clear them, as they
+ // are unevac region sthat are live.
// Subtract one for the for loop.
- i += full_count - 1;
+ i += regions_to_clear_bitmap - 1;
}
}
// Note r != last_checked_region if r->IsInUnevacFromSpace() was true above.
diff --git a/runtime/gc/space/region_space.h b/runtime/gc/space/region_space.h
index 7b16ffe..6412158 100644
--- a/runtime/gc/space/region_space.h
+++ b/runtime/gc/space/region_space.h
@@ -393,6 +393,10 @@
DCHECK_LE(live_bytes_, BytesAllocated());
}
+ bool AllAllocatedBytesAreLive() const {
+ return LiveBytes() == static_cast<size_t>(Top() - Begin());
+ }
+
size_t LiveBytes() const {
return live_bytes_;
}