ART: clear dirty cards of alloc space for MS/CMS partial and full GCs

For MS/CMS partial and full GCs, we could clear the dirty cards of alloc
space when we process cards as we care about the dirty cards after GC
starts.

Change-Id: I1f9b32b20d75979387bc5d26b0cf9a256dcf20b6
Signed-off-by: Lei Li <lei.l.li@intel.com>
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index ba06e05..01d467a 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -2760,7 +2760,8 @@
   return it->second;
 }
 
-void Heap::ProcessCards(TimingLogger* timings, bool use_rem_sets) {
+void Heap::ProcessCards(TimingLogger* timings, bool use_rem_sets, bool process_alloc_space_cards,
+                        bool clear_alloc_space_cards) {
   TimingLogger::ScopedTiming t(__FUNCTION__, timings);
   // Clear cards and keep track of cards cleared in the mod-union table.
   for (const auto& space : continuous_spaces_) {
@@ -2776,17 +2777,21 @@
           << static_cast<int>(collector_type_);
       TimingLogger::ScopedTiming t2("AllocSpaceRemSetClearCards", timings);
       rem_set->ClearCards();
-    } else if (space->GetType() != space::kSpaceTypeBumpPointerSpace) {
+    } else if (process_alloc_space_cards) {
       TimingLogger::ScopedTiming t2("AllocSpaceClearCards", timings);
-      // No mod union table for the AllocSpace. Age the cards so that the GC knows that these cards
-      // were dirty before the GC started.
-      // TODO: Need to use atomic for the case where aged(cleaning thread) -> dirty(other thread)
-      // -> clean(cleaning thread).
-      // The races are we either end up with: Aged card, unaged card. Since we have the checkpoint
-      // roots and then we scan / update mod union tables after. We will always scan either card.
-      // If we end up with the non aged card, we scan it it in the pause.
-      card_table_->ModifyCardsAtomic(space->Begin(), space->End(), AgeCardVisitor(),
-                                     VoidFunctor());
+      if (clear_alloc_space_cards) {
+        card_table_->ClearCardRange(space->Begin(), space->End());
+      } else {
+        // No mod union table for the AllocSpace. Age the cards so that the GC knows that these
+        // cards were dirty before the GC started.
+        // TODO: Need to use atomic for the case where aged(cleaning thread) -> dirty(other thread)
+        // -> clean(cleaning thread).
+        // The races are we either end up with: Aged card, unaged card. Since we have the
+        // checkpoint roots and then we scan / update mod union tables after. We will always
+        // scan either card. If we end up with the non aged card, we scan it it in the pause.
+        card_table_->ModifyCardsAtomic(space->Begin(), space->End(), AgeCardVisitor(),
+                                       VoidFunctor());
+      }
     }
   }
 }