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);