summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2017-07-08 15:54:30 +0100
committer Nicolas Geoffray <ngeoffray@google.com> 2017-07-10 09:46:41 +0100
commita5fb2049a7e5233c6aefe174000f17769efe3d30 (patch)
tree6935ee18673854cd024ca363cfb965946c2e06e2
parent2a546e14e55f7e0d8bbf122572b7bbd600400362 (diff)
Rewrite bits of RegionSpace::ClearFromSpace.
To make it clearer what the loop is for. Test: test.py Change-Id: Iae5d8351fd294a4f43dd74dc714d644c9d8f0c7f
-rw-r--r--runtime/gc/space/region_space.cc36
-rw-r--r--runtime/gc/space/region_space.h4
2 files changed, 23 insertions, 17 deletions
diff --git a/runtime/gc/space/region_space.cc b/runtime/gc/space/region_space.cc
index b8f1e8fc71..fe3c1c022c 100644
--- a/runtime/gc/space/region_space.cc
+++ b/runtime/gc/space/region_space.cc
@@ -290,6 +290,7 @@ void RegionSpace::ClearFromSpace(uint64_t* cleared_bytes, uint64_t* cleared_obje
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 @@ void RegionSpace::ClearFromSpace(uint64_t* cleared_bytes, uint64_t* cleared_obje
reinterpret_cast<mirror::Object*>(r->Begin() + free_regions * kRegionSize));
continue;
}
- size_t full_count = 0;
- while (r->IsInUnevacFromSpace()) {
- Region* const cur = &regions_[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) {
+ r->SetUnevacFromSpaceAsToSpace();
+ 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 = &regions_[i + regions_to_clear_bitmap];
+ if (!cur->AllAllocatedBytesAreLive()) {
+ DCHECK(!cur->IsLargeTail());
+ break;
+ }
+ CHECK(cur->IsInUnevacFromSpace());
cur->SetUnevacFromSpaceAsToSpace();
+ ++regions_to_clear_bitmap;
}
- ++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) {
+
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 7b16ffe23d..6412158a77 100644
--- a/runtime/gc/space/region_space.h
+++ b/runtime/gc/space/region_space.h
@@ -393,6 +393,10 @@ class RegionSpace FINAL : public ContinuousMemMapAllocSpace {
DCHECK_LE(live_bytes_, BytesAllocated());
}
+ bool AllAllocatedBytesAreLive() const {
+ return LiveBytes() == static_cast<size_t>(Top() - Begin());
+ }
+
size_t LiveBytes() const {
return live_bytes_;
}