Return bytes freed from RosAlloc.

There was a problem with how RosAlloc space sweeping worked caused by
using the object size in the FreeList call, this won't work well with
class unloading since the object's class may be freed before the
object.

Bug: 13989231
Change-Id: I3df439c312310720fd34249334dec85030166fe9
diff --git a/runtime/gc/space/rosalloc_space.cc b/runtime/gc/space/rosalloc_space.cc
index 5a7d941..a5a6da0 100644
--- a/runtime/gc/space/rosalloc_space.cc
+++ b/runtime/gc/space/rosalloc_space.cc
@@ -33,6 +33,10 @@
 namespace space {
 
 static constexpr bool kPrefetchDuringRosAllocFreeList = true;
+static constexpr size_t kPrefetchLookAhead = 8;
+// Use this only for verification, it is not safe to use since the class of the object may have
+// been freed.
+static constexpr bool kVerifyFreedBytes = false;
 
 // TODO: Fix
 // template class ValgrindMallocSpace<RosAllocSpace, allocator::RosAlloc*>;
@@ -172,27 +176,24 @@
     CHECK(ptr != NULL);
     CHECK(Contains(ptr)) << "Free (" << ptr << ") not in bounds of heap " << *this;
   }
-  const size_t bytes_freed = AllocationSizeNonvirtual(ptr, nullptr);
   if (kRecentFreeCount > 0) {
     MutexLock mu(self, lock_);
     RegisterRecentFree(ptr);
   }
-  rosalloc_->Free(self, ptr);
-  return bytes_freed;
+  return rosalloc_->Free(self, ptr);
 }
 
 size_t RosAllocSpace::FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) {
-  DCHECK(ptrs != NULL);
+  DCHECK(ptrs != nullptr);
 
-  // Don't need the lock to calculate the size of the freed pointers.
-  size_t bytes_freed = 0;
+  size_t verify_bytes = 0;
   for (size_t i = 0; i < num_ptrs; i++) {
-    mirror::Object* ptr = ptrs[i];
-    const size_t look_ahead = 8;
-    if (kPrefetchDuringRosAllocFreeList && i + look_ahead < num_ptrs) {
-      __builtin_prefetch(reinterpret_cast<char*>(ptrs[i + look_ahead]));
+    if (kPrefetchDuringRosAllocFreeList && i + kPrefetchLookAhead < num_ptrs) {
+      __builtin_prefetch(reinterpret_cast<char*>(ptrs[i + kPrefetchLookAhead]));
     }
-    bytes_freed += AllocationSizeNonvirtual(ptr, nullptr);
+    if (kVerifyFreedBytes) {
+      verify_bytes += AllocationSizeNonvirtual(ptrs[i], nullptr);
+    }
   }
 
   if (kRecentFreeCount > 0) {
@@ -216,7 +217,10 @@
     CHECK_EQ(num_broken_ptrs, 0u);
   }
 
-  rosalloc_->BulkFree(self, reinterpret_cast<void**>(ptrs), num_ptrs);
+  const size_t bytes_freed = rosalloc_->BulkFree(self, reinterpret_cast<void**>(ptrs), num_ptrs);
+  if (kVerifyFreedBytes) {
+    CHECK_EQ(verify_bytes, bytes_freed);
+  }
   return bytes_freed;
 }