OSDN Git Service

Scan immune spaces using mod union tables.
authorHiroshi Yamauchi <yamauchi@google.com>
Wed, 27 Jul 2016 21:08:19 +0000 (14:08 -0700)
committerHiroshi Yamauchi <yamauchi@google.com>
Wed, 27 Jul 2016 21:45:53 +0000 (14:45 -0700)
It's faster to scan the immune spaces using the mod union tables (gray
objects on dirty pages) than the live bitmaps (gray objects).

The immune space scan time goes from ~13ms down to ~10ms in the
testWidgetsContainerFling test on angler at 1 GHz.

Change-Id: I0914d7bdb50cbf8a49c859070a3501b48eb79f3e
Test: N9 boot, art tests, Ritz EAAC.
Bug: 29516968
Bug: 29517059
Bug: 12687968

runtime/gc/collector/concurrent_copying.cc

index d413a50..4a80089 100644 (file)
@@ -520,7 +520,7 @@ class ConcurrentCopying::ImmuneSpaceScanObjVisitor {
   explicit ImmuneSpaceScanObjVisitor(ConcurrentCopying* cc)
       : collector_(cc) {}
 
-  void operator()(mirror::Object* obj) const SHARED_REQUIRES(Locks::mutator_lock_) {
+  ALWAYS_INLINE void operator()(mirror::Object* obj) const SHARED_REQUIRES(Locks::mutator_lock_) {
     if (kUseBakerReadBarrier && kGrayDirtyImmuneObjects) {
       if (obj->GetReadBarrierPointer() == ReadBarrier::GrayPtr()) {
         collector_->ScanImmuneObject(obj);
@@ -534,6 +534,10 @@ class ConcurrentCopying::ImmuneSpaceScanObjVisitor {
     }
   }
 
+  static void Callback(mirror::Object* obj, void* arg) SHARED_REQUIRES(Locks::mutator_lock_) {
+    reinterpret_cast<ImmuneSpaceScanObjVisitor*>(arg)->operator()(obj);
+  }
+
  private:
   ConcurrentCopying* const collector_;
 };
@@ -558,10 +562,15 @@ void ConcurrentCopying::MarkingPhase() {
     for (auto& space : immune_spaces_.GetSpaces()) {
       DCHECK(space->IsImageSpace() || space->IsZygoteSpace());
       accounting::ContinuousSpaceBitmap* live_bitmap = space->GetLiveBitmap();
+      accounting::ModUnionTable* table = heap_->FindModUnionTableFromSpace(space);
       ImmuneSpaceScanObjVisitor visitor(this);
-      live_bitmap->VisitMarkedRange(reinterpret_cast<uintptr_t>(space->Begin()),
-                                    reinterpret_cast<uintptr_t>(space->Limit()),
-                                    visitor);
+      if (table != nullptr) {
+        table->VisitObjects(ImmuneSpaceScanObjVisitor::Callback, &visitor);
+      } else {
+        live_bitmap->VisitMarkedRange(reinterpret_cast<uintptr_t>(space->Begin()),
+                                      reinterpret_cast<uintptr_t>(space->Limit()),
+                                      visitor);
+      }
     }
   }
   if (kUseBakerReadBarrier) {