Make active_concurrent_copying_collector_ atomic am: 45aa2affa5 am: 0ad7d8776d

Original change: https://android-review.googlesource.com/c/platform/art/+/1520678

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I254fe310199f35b5297d2c15aebd48eea89e1848
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index d83cdaf..6fdc4e4 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -708,7 +708,8 @@
             "young",
             measure_gc_performance);
       }
-      active_concurrent_copying_collector_ = concurrent_copying_collector_;
+      active_concurrent_copying_collector_.store(concurrent_copying_collector_,
+                                                 std::memory_order_relaxed);
       DCHECK(region_space_ != nullptr);
       concurrent_copying_collector_->SetRegionSpace(region_space_);
       if (use_generational_cc_) {
@@ -2576,19 +2577,24 @@
         collector = semi_space_collector_;
         break;
       case kCollectorTypeCC:
+        collector::ConcurrentCopying* active_cc_collector;
         if (use_generational_cc_) {
           // TODO: Other threads must do the flip checkpoint before they start poking at
           // active_concurrent_copying_collector_. So we should not concurrency here.
-          active_concurrent_copying_collector_ = (gc_type == collector::kGcTypeSticky) ?
-              young_concurrent_copying_collector_ : concurrent_copying_collector_;
-          DCHECK(active_concurrent_copying_collector_->RegionSpace() == region_space_);
+          active_cc_collector = (gc_type == collector::kGcTypeSticky) ?
+                  young_concurrent_copying_collector_ : concurrent_copying_collector_;
+          active_concurrent_copying_collector_.store(active_cc_collector,
+                                                     std::memory_order_relaxed);
+          DCHECK(active_cc_collector->RegionSpace() == region_space_);
+          collector = active_cc_collector;
+        } else {
+          collector = active_concurrent_copying_collector_.load(std::memory_order_relaxed);
         }
-        collector = active_concurrent_copying_collector_;
         break;
       default:
         LOG(FATAL) << "Invalid collector type " << static_cast<size_t>(collector_type_);
     }
-    if (collector != active_concurrent_copying_collector_) {
+    if (collector != active_concurrent_copying_collector_.load(std::memory_order_relaxed)) {
       temp_space_->GetMemMap()->Protect(PROT_READ | PROT_WRITE);
       if (kIsDebugBuild) {
         // Try to read each page of the memory map in case mprotect didn't work properly b/19894268.
diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h
index 92575c3..99da008 100644
--- a/runtime/gc/heap.h
+++ b/runtime/gc/heap.h
@@ -779,16 +779,18 @@
 
   // Returns the active concurrent copying collector.
   collector::ConcurrentCopying* ConcurrentCopyingCollector() {
+    collector::ConcurrentCopying* active_collector =
+            active_concurrent_copying_collector_.load(std::memory_order_relaxed);
     if (use_generational_cc_) {
-      DCHECK((active_concurrent_copying_collector_ == concurrent_copying_collector_) ||
-             (active_concurrent_copying_collector_ == young_concurrent_copying_collector_))
-              << "active_concurrent_copying_collector: " << active_concurrent_copying_collector_
+      DCHECK((active_collector == concurrent_copying_collector_) ||
+             (active_collector == young_concurrent_copying_collector_))
+              << "active_concurrent_copying_collector: " << active_collector
               << " young_concurrent_copying_collector: " << young_concurrent_copying_collector_
               << " concurrent_copying_collector: " << concurrent_copying_collector_;
     } else {
-      DCHECK_EQ(active_concurrent_copying_collector_, concurrent_copying_collector_);
+      DCHECK_EQ(active_collector, concurrent_copying_collector_);
     }
-    return active_concurrent_copying_collector_;
+    return active_collector;
   }
 
   CollectorType CurrentCollectorType() {
@@ -1496,7 +1498,7 @@
 
   std::vector<collector::GarbageCollector*> garbage_collectors_;
   collector::SemiSpace* semi_space_collector_;
-  collector::ConcurrentCopying* active_concurrent_copying_collector_;
+  Atomic<collector::ConcurrentCopying*> active_concurrent_copying_collector_;
   collector::ConcurrentCopying* young_concurrent_copying_collector_;
   collector::ConcurrentCopying* concurrent_copying_collector_;