Sweep malloc spaces before clearing from space

Sweep the malloc spaces before clearing the from space since the
memory tool mode might access the object classes in the from space
for dead objects.

Fixes an occasional crash during sweeping for ASAN.

Bug: 134727798
Test: test-art-host
Test: art/test/testrunner/run_build_test_target.py -j50 art-asan

Change-Id: Ib1db6ca0ab5ebc6408afbd68e8b1937210aecd3d
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index 9428a0b..f23b3fd 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -2627,6 +2627,20 @@
   // the biggest memory range, thereby reducing the cost of this function.
   CaptureRssAtPeak();
 
+  // Sweep the malloc spaces before clearing the from space since the memory tool mode might
+  // access the object classes in the from space for dead objects.
+  {
+    WriterMutexLock mu(self, *Locks::heap_bitmap_lock_);
+    Sweep(/* swap_bitmaps= */ false);
+    SwapBitmaps();
+    heap_->UnBindBitmaps();
+
+    // The bitmap was cleared at the start of the GC, there is nothing we need to do here.
+    DCHECK(region_space_bitmap_ != nullptr);
+    region_space_bitmap_ = nullptr;
+  }
+
+
   {
     // Record freed objects.
     TimingLogger::ScopedTiming split2("RecordFree", GetTimings());
@@ -2689,17 +2703,6 @@
     reclaimed_bytes_ratio_sum_ += reclaimed_bytes_ratio;
   }
 
-  {
-    WriterMutexLock mu(self, *Locks::heap_bitmap_lock_);
-    Sweep(/* swap_bitmaps= */ false);
-    SwapBitmaps();
-    heap_->UnBindBitmaps();
-
-    // The bitmap was cleared at the start of the GC, there is nothing we need to do here.
-    DCHECK(region_space_bitmap_ != nullptr);
-    region_space_bitmap_ = nullptr;
-  }
-
   CheckEmptyMarkStack();
 
   if (heap_->dump_region_info_after_gc_) {