diff options
| author | 2017-07-08 15:54:30 +0100 | |
|---|---|---|
| committer | 2017-07-10 09:46:41 +0100 | |
| commit | a5fb2049a7e5233c6aefe174000f17769efe3d30 (patch) | |
| tree | 6935ee18673854cd024ca363cfb965946c2e06e2 | |
| parent | 2a546e14e55f7e0d8bbf122572b7bbd600400362 (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.cc | 36 | ||||
| -rw-r--r-- | runtime/gc/space/region_space.h | 4 |
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 = ®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) { + 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 = ®ions_[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_; } |