Refactor large object sweeping.

Moved basic sweeping logic into large_object_space.cc.
Renamed SpaceSetMap -> ObjectSet.

Change-Id: I938c1f29f69b0682350347da2bd5de021c0e0224
diff --git a/runtime/gc/accounting/heap_bitmap.cc b/runtime/gc/accounting/heap_bitmap.cc
index 6625b7b..c520ee6 100644
--- a/runtime/gc/accounting/heap_bitmap.cc
+++ b/runtime/gc/accounting/heap_bitmap.cc
@@ -32,7 +32,7 @@
   LOG(FATAL) << "bitmap " << static_cast<const void*>(old_bitmap) << " not found";
 }
 
-void HeapBitmap::ReplaceObjectSet(SpaceSetMap* old_set, SpaceSetMap* new_set) {
+void HeapBitmap::ReplaceObjectSet(ObjectSet* old_set, ObjectSet* new_set) {
   for (auto& space_set : discontinuous_space_sets_) {
     if (space_set == old_set) {
       space_set = new_set;
@@ -61,12 +61,12 @@
   continuous_space_bitmaps_.erase(it);
 }
 
-void HeapBitmap::AddDiscontinuousObjectSet(SpaceSetMap* set) {
+void HeapBitmap::AddDiscontinuousObjectSet(ObjectSet* set) {
   DCHECK(set != NULL);
   discontinuous_space_sets_.push_back(set);
 }
 
-void HeapBitmap::RemoveDiscontinuousObjectSet(SpaceSetMap* set) {
+void HeapBitmap::RemoveDiscontinuousObjectSet(ObjectSet* set) {
   auto it = std::find(discontinuous_space_sets_.begin(), discontinuous_space_sets_.end(), set);
   DCHECK(it != discontinuous_space_sets_.end());
   discontinuous_space_sets_.erase(it);
diff --git a/runtime/gc/accounting/heap_bitmap.h b/runtime/gc/accounting/heap_bitmap.h
index bed2c1e..bcf36a2 100644
--- a/runtime/gc/accounting/heap_bitmap.h
+++ b/runtime/gc/accounting/heap_bitmap.h
@@ -32,7 +32,7 @@
 class HeapBitmap {
  public:
   typedef std::vector<SpaceBitmap*, GcAllocator<SpaceBitmap*> > SpaceBitmapVector;
-  typedef std::vector<SpaceSetMap*, GcAllocator<SpaceSetMap*> > SpaceSetMapVector;
+  typedef std::vector<ObjectSet*, GcAllocator<ObjectSet*> > ObjectSetVector;
 
   bool Test(const mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
     SpaceBitmap* bitmap = GetContinuousSpaceBitmap(obj);
@@ -48,7 +48,7 @@
     if (LIKELY(bitmap != NULL)) {
       bitmap->Clear(obj);
     } else {
-      SpaceSetMap* set = GetDiscontinuousSpaceObjectSet(obj);
+      ObjectSet* set = GetDiscontinuousSpaceObjectSet(obj);
       DCHECK(set != NULL);
       set->Clear(obj);
     }
@@ -59,7 +59,7 @@
     if (LIKELY(bitmap != NULL)) {
       bitmap->Set(obj);
     } else {
-      SpaceSetMap* set = GetDiscontinuousSpaceObjectSet(obj);
+      ObjectSet* set = GetDiscontinuousSpaceObjectSet(obj);
       DCHECK(set != NULL);
       set->Set(obj);
     }
@@ -74,7 +74,7 @@
     return NULL;
   }
 
-  SpaceSetMap* GetDiscontinuousSpaceObjectSet(const mirror::Object* obj) {
+  ObjectSet* GetDiscontinuousSpaceObjectSet(const mirror::Object* obj) {
     for (const auto& space_set : discontinuous_space_sets_) {
       if (space_set->Test(obj)) {
         return space_set;
@@ -96,7 +96,7 @@
       EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
 
   // Find and replace a object set pointer, this is used by for the bitmap swapping in the GC.
-  void ReplaceObjectSet(SpaceSetMap* old_set, SpaceSetMap* new_set)
+  void ReplaceObjectSet(ObjectSet* old_set, ObjectSet* new_set)
       EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
 
   explicit HeapBitmap(Heap* heap) : heap_(heap) {}
@@ -106,14 +106,14 @@
 
   void AddContinuousSpaceBitmap(SpaceBitmap* bitmap);
   void RemoveContinuousSpaceBitmap(SpaceBitmap* bitmap);
-  void AddDiscontinuousObjectSet(SpaceSetMap* set);
-  void RemoveDiscontinuousObjectSet(SpaceSetMap* set);
+  void AddDiscontinuousObjectSet(ObjectSet* set);
+  void RemoveDiscontinuousObjectSet(ObjectSet* set);
 
   // Bitmaps covering continuous spaces.
   SpaceBitmapVector continuous_space_bitmaps_;
 
   // Sets covering discontinuous spaces.
-  SpaceSetMapVector discontinuous_space_sets_;
+  ObjectSetVector discontinuous_space_sets_;
 
   friend class art::gc::Heap;
 };
diff --git a/runtime/gc/accounting/space_bitmap.cc b/runtime/gc/accounting/space_bitmap.cc
index 52c02f7..99800fc 100644
--- a/runtime/gc/accounting/space_bitmap.cc
+++ b/runtime/gc/accounting/space_bitmap.cc
@@ -44,7 +44,7 @@
                       reinterpret_cast<void*>(HeapLimit()));
 }
 
-void SpaceSetMap::Walk(SpaceBitmap::Callback* callback, void* arg) {
+void ObjectSet::Walk(SpaceBitmap::Callback* callback, void* arg) {
   for (const mirror::Object* obj : contained_) {
     callback(const_cast<mirror::Object*>(obj), arg);
   }
@@ -267,18 +267,6 @@
   }
 }
 
-std::string SpaceSetMap::GetName() const {
-  return name_;
-}
-
-void SpaceSetMap::SetName(const std::string& name) {
-  name_ = name;
-}
-
-void SpaceSetMap::CopyFrom(const SpaceSetMap& space_set) {
-  contained_ = space_set.contained_;
-}
-
 std::ostream& operator << (std::ostream& stream, const SpaceBitmap& bitmap) {
   return stream
     << bitmap.GetName() << "["
diff --git a/runtime/gc/accounting/space_bitmap.h b/runtime/gc/accounting/space_bitmap.h
index 21709ad..2d6cde5 100644
--- a/runtime/gc/accounting/space_bitmap.h
+++ b/runtime/gc/accounting/space_bitmap.h
@@ -208,7 +208,7 @@
 };
 
 // Like a bitmap except it keeps track of objects using sets.
-class SpaceSetMap {
+class ObjectSet {
  public:
   typedef std::set<
       const mirror::Object*, std::less<const mirror::Object*>,
@@ -237,14 +237,21 @@
     return contained_.find(obj) != contained_.end();
   }
 
-  std::string GetName() const;
-  void SetName(const std::string& name);
+  const std::string& GetName() const {
+    return name_;
+  }
+
+  void SetName(const std::string& name) {
+    name_ = name;
+  }
+
+  void CopyFrom(const ObjectSet& space_set) {
+    contained_ = space_set.contained_;
+  }
 
   void Walk(SpaceBitmap::Callback* callback, void* arg)
       SHARED_LOCKS_REQUIRED(GlobalSynchronization::heap_bitmap_lock_);
 
-  void CopyFrom(const SpaceSetMap& space_set);
-
   template <typename Visitor>
   void Visit(const Visitor& visitor) NO_THREAD_SAFETY_ANALYSIS {
     for (const mirror::Object* obj : contained_) {
@@ -252,8 +259,8 @@
     }
   }
 
-  explicit SpaceSetMap(const std::string& name) : name_(name) {}
-  ~SpaceSetMap() {}
+  explicit ObjectSet(const std::string& name) : name_(name) {}
+  ~ObjectSet() {}
 
   Objects& GetObjects() {
     return contained_;
diff --git a/runtime/gc/collector/garbage_collector.cc b/runtime/gc/collector/garbage_collector.cc
index 4822e64..28428cc 100644
--- a/runtime/gc/collector/garbage_collector.cc
+++ b/runtime/gc/collector/garbage_collector.cc
@@ -158,8 +158,8 @@
   }
   for (const auto& disc_space : GetHeap()->GetDiscontinuousSpaces()) {
     space::LargeObjectSpace* space = down_cast<space::LargeObjectSpace*>(disc_space);
-    accounting::SpaceSetMap* live_set = space->GetLiveObjects();
-    accounting::SpaceSetMap* mark_set = space->GetMarkObjects();
+    accounting::ObjectSet* live_set = space->GetLiveObjects();
+    accounting::ObjectSet* mark_set = space->GetMarkObjects();
     heap_->GetLiveBitmap()->ReplaceObjectSet(live_set, mark_set);
     heap_->GetMarkBitmap()->ReplaceObjectSet(mark_set, live_set);
     down_cast<space::LargeObjectSpace*>(space)->SwapBitmaps();
diff --git a/runtime/gc/collector/mark_sweep.cc b/runtime/gc/collector/mark_sweep.cc
index 937ff6d..5d450a7 100644
--- a/runtime/gc/collector/mark_sweep.cc
+++ b/runtime/gc/collector/mark_sweep.cc
@@ -465,7 +465,7 @@
 bool MarkSweep::MarkLargeObject(const Object* obj, bool set) {
   // TODO: support >1 discontinuous space.
   space::LargeObjectSpace* large_object_space = GetHeap()->GetLargeObjectsSpace();
-  accounting::SpaceSetMap* large_objects = large_object_space->GetMarkObjects();
+  accounting::ObjectSet* large_objects = large_object_space->GetMarkObjects();
   if (kProfileLargeObjects) {
     ++large_object_test_;
   }
@@ -1112,8 +1112,8 @@
   }
   // Handle the large object space.
   space::LargeObjectSpace* large_object_space = GetHeap()->GetLargeObjectsSpace();
-  accounting::SpaceSetMap* large_live_objects = large_object_space->GetLiveObjects();
-  accounting::SpaceSetMap* large_mark_objects = large_object_space->GetMarkObjects();
+  accounting::ObjectSet* large_live_objects = large_object_space->GetLiveObjects();
+  accounting::ObjectSet* large_mark_objects = large_object_space->GetMarkObjects();
   if (swap_bitmaps) {
     std::swap(large_live_objects, large_mark_objects);
   }
@@ -1163,23 +1163,9 @@
 
 void MarkSweep::SweepLargeObjects(bool swap_bitmaps) {
   TimingLogger::ScopedSplit("SweepLargeObjects", &timings_);
-  // Sweep large objects
-  space::LargeObjectSpace* large_object_space = GetHeap()->GetLargeObjectsSpace();
-  accounting::SpaceSetMap* large_live_objects = large_object_space->GetLiveObjects();
-  accounting::SpaceSetMap* large_mark_objects = large_object_space->GetMarkObjects();
-  if (swap_bitmaps) {
-    std::swap(large_live_objects, large_mark_objects);
-  }
-  // O(n*log(n)) but hopefully there are not too many large objects.
   size_t freed_objects = 0;
   size_t freed_bytes = 0;
-  Thread* self = Thread::Current();
-  for (const Object* obj : large_live_objects->GetObjects()) {
-    if (!large_mark_objects->Test(obj)) {
-      freed_bytes += large_object_space->Free(self, const_cast<Object*>(obj));
-      ++freed_objects;
-    }
-  }
+  GetHeap()->GetLargeObjectsSpace()->Sweep(swap_bitmaps, &freed_objects, &freed_bytes);
   freed_large_objects_.FetchAndAdd(freed_objects);
   freed_large_object_bytes_.FetchAndAdd(freed_bytes);
   GetHeap()->RecordFree(freed_objects, freed_bytes);
diff --git a/runtime/gc/collector/semi_space.cc b/runtime/gc/collector/semi_space.cc
index 1ea2002..aed260c 100644
--- a/runtime/gc/collector/semi_space.cc
+++ b/runtime/gc/collector/semi_space.cc
@@ -298,7 +298,7 @@
 bool SemiSpace::MarkLargeObject(const Object* obj) {
   // TODO: support >1 discontinuous space.
   space::LargeObjectSpace* large_object_space = GetHeap()->GetLargeObjectsSpace();
-  accounting::SpaceSetMap* large_objects = large_object_space->GetMarkObjects();
+  accounting::ObjectSet* large_objects = large_object_space->GetMarkObjects();
   if (UNLIKELY(!large_objects->Test(obj))) {
     large_objects->Set(obj);
     return true;
@@ -457,23 +457,9 @@
 
 void SemiSpace::SweepLargeObjects(bool swap_bitmaps) {
   TimingLogger::ScopedSplit("SweepLargeObjects", &timings_);
-  // Sweep large objects
-  space::LargeObjectSpace* large_object_space = GetHeap()->GetLargeObjectsSpace();
-  accounting::SpaceSetMap* large_live_objects = large_object_space->GetLiveObjects();
-  accounting::SpaceSetMap* large_mark_objects = large_object_space->GetMarkObjects();
-  if (swap_bitmaps) {
-    std::swap(large_live_objects, large_mark_objects);
-  }
-  // O(n*log(n)) but hopefully there are not too many large objects.
   size_t freed_objects = 0;
   size_t freed_bytes = 0;
-  Thread* self = Thread::Current();
-  for (const Object* obj : large_live_objects->GetObjects()) {
-    if (!large_mark_objects->Test(obj)) {
-      freed_bytes += large_object_space->Free(self, const_cast<Object*>(obj));
-      ++freed_objects;
-    }
-  }
+  GetHeap()->GetLargeObjectsSpace()->Sweep(swap_bitmaps, &freed_objects, &freed_bytes);
   freed_large_objects_.FetchAndAdd(freed_objects);
   freed_large_object_bytes_.FetchAndAdd(freed_bytes);
   GetHeap()->RecordFree(freed_objects, freed_bytes);
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 8d607e2..071b3de 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -1440,7 +1440,7 @@
 
 void Heap::MarkAllocStack(accounting::SpaceBitmap* bitmap1,
                           accounting::SpaceBitmap* bitmap2,
-                          accounting::SpaceSetMap* large_objects,
+                          accounting::ObjectSet* large_objects,
                           accounting::ObjectStack* stack) {
   DCHECK(bitmap1 != nullptr);
   DCHECK(bitmap2 != nullptr);
diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h
index 622850f..cc4d7be 100644
--- a/runtime/gc/heap.h
+++ b/runtime/gc/heap.h
@@ -54,7 +54,7 @@
 namespace accounting {
   class HeapBitmap;
   class ModUnionTable;
-  class SpaceSetMap;
+  class ObjectSet;
 }  // namespace accounting
 
 namespace collector {
@@ -468,7 +468,7 @@
 
   // Mark all the objects in the allocation stack in the specified bitmap.
   void MarkAllocStack(accounting::SpaceBitmap* bitmap1, accounting::SpaceBitmap* bitmap2,
-                      accounting::SpaceSetMap* large_objects, accounting::ObjectStack* stack)
+                      accounting::ObjectSet* large_objects, accounting::ObjectStack* stack)
       EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
 
   // Mark the specified allocation stack as live.
diff --git a/runtime/gc/space/large_object_space.cc b/runtime/gc/space/large_object_space.cc
index ab6e42b..7fcfed4 100644
--- a/runtime/gc/space/large_object_space.cc
+++ b/runtime/gc/space/large_object_space.cc
@@ -331,6 +331,29 @@
   }
 }
 
+void LargeObjectSpace::Sweep(bool swap_bitmaps, size_t* freed_objects, size_t* freed_bytes) {
+  // Sweep large objects
+  accounting::ObjectSet* large_live_objects = GetLiveObjects();
+  accounting::ObjectSet* large_mark_objects = GetMarkObjects();
+  if (swap_bitmaps) {
+    std::swap(large_live_objects, large_mark_objects);
+  }
+  DCHECK(freed_objects != nullptr);
+  DCHECK(freed_bytes != nullptr);
+  // O(n*log(n)) but hopefully there are not too many large objects.
+  size_t objects = 0;
+  size_t bytes = 0;
+  Thread* self = Thread::Current();
+  for (const mirror::Object* obj : large_live_objects->GetObjects()) {
+    if (!large_mark_objects->Test(obj)) {
+      bytes += Free(self, const_cast<mirror::Object*>(obj));
+      ++objects;
+    }
+  }
+  *freed_objects += objects;
+  *freed_bytes += bytes;
+}
+
 }  // namespace space
 }  // namespace gc
 }  // namespace art
diff --git a/runtime/gc/space/large_object_space.h b/runtime/gc/space/large_object_space.h
index d374ad3..cd7c383 100644
--- a/runtime/gc/space/large_object_space.h
+++ b/runtime/gc/space/large_object_space.h
@@ -67,6 +67,8 @@
     return this;
   }
 
+  virtual void Sweep(bool swap_bitmaps, size_t* freed_objects, size_t* freed_bytes);
+
  protected:
   explicit LargeObjectSpace(const std::string& name);
 
diff --git a/runtime/gc/space/space.cc b/runtime/gc/space/space.cc
index 8eb17e0..f8ba6b3 100644
--- a/runtime/gc/space/space.cc
+++ b/runtime/gc/space/space.cc
@@ -37,8 +37,8 @@
 DiscontinuousSpace::DiscontinuousSpace(const std::string& name,
                                        GcRetentionPolicy gc_retention_policy) :
     Space(name, gc_retention_policy),
-    live_objects_(new accounting::SpaceSetMap("large live objects")),
-    mark_objects_(new accounting::SpaceSetMap("large marked objects")) {
+    live_objects_(new accounting::ObjectSet("large live objects")),
+    mark_objects_(new accounting::ObjectSet("large marked objects")) {
 }
 
 }  // namespace space
diff --git a/runtime/gc/space/space.h b/runtime/gc/space/space.h
index 31bbb7b..5292344 100644
--- a/runtime/gc/space/space.h
+++ b/runtime/gc/space/space.h
@@ -314,11 +314,11 @@
 // is suitable for use for large primitive arrays.
 class DiscontinuousSpace : public Space {
  public:
-  accounting::SpaceSetMap* GetLiveObjects() const {
+  accounting::ObjectSet* GetLiveObjects() const {
     return live_objects_.get();
   }
 
-  accounting::SpaceSetMap* GetMarkObjects() const {
+  accounting::ObjectSet* GetMarkObjects() const {
     return mark_objects_.get();
   }
 
@@ -331,8 +331,8 @@
  protected:
   DiscontinuousSpace(const std::string& name, GcRetentionPolicy gc_retention_policy);
 
-  UniquePtr<accounting::SpaceSetMap> live_objects_;
-  UniquePtr<accounting::SpaceSetMap> mark_objects_;
+  UniquePtr<accounting::ObjectSet> live_objects_;
+  UniquePtr<accounting::ObjectSet> mark_objects_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(DiscontinuousSpace);