Mark stack create once per heap.
Mark stack is now created during heap initialization and is then re-used for each GC. This helps to prevent fragmentation of the heap.
Change-Id: I5dd1bdfb58452415b88bfeb0c05a41ecbca09696
diff --git a/src/heap.cc b/src/heap.cc
index e50a31c..75b11ea 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -239,6 +239,8 @@
num_bytes_allocated_ = 0;
num_objects_allocated_ = 0;
+ mark_stack_ = MarkStack::Create();
+
// It's still too early to take a lock because there are no threads yet,
// but we can create the heap lock now. We don't create it earlier to
// make it clear that you can't use locks during heap initialization.
@@ -263,6 +265,7 @@
delete mark_bitmap_;
delete live_bitmap_;
delete card_table_;
+ delete mark_stack_;
delete lock_;
}
@@ -586,7 +589,7 @@
uint64_t t0 = NanoTime();
Object* cleared_references = NULL;
{
- MarkSweep mark_sweep;
+ MarkSweep mark_sweep(mark_stack_);
timings.AddSplit("ctor");
mark_sweep.Init();
diff --git a/src/heap.h b/src/heap.h
index 5b6b991..d368158 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -34,12 +34,13 @@
class AllocSpace;
class Class;
+class HeapBitmap;
class ImageSpace;
+class MarkStack;
class Object;
class Space;
-class Thread;
-class HeapBitmap;
class SpaceTest;
+class Thread;
class Heap {
public:
@@ -271,6 +272,9 @@
// True while the garbage collector is running.
bool is_gc_running_;
+ // Mark stack that we reuse to avoid re-allocating the mark stack
+ MarkStack* mark_stack_;
+
// Number of bytes allocated. Adjusted after each allocation and free.
size_t num_bytes_allocated_;
diff --git a/src/mark_stack.cc b/src/mark_stack.cc
index 60c9e0d..e269455 100644
--- a/src/mark_stack.cc
+++ b/src/mark_stack.cc
@@ -41,9 +41,20 @@
}
byte* addr = mem_map_->Begin();
CHECK(addr != NULL);
+
begin_ = reinterpret_cast<const Object**>(addr);
limit_ = reinterpret_cast<const Object**>(addr + length);
- ptr_ = reinterpret_cast<Object const**>(addr);
+
+ Reset();
+}
+
+void MarkStack::Reset() {
+ DCHECK(mem_map_.get() != NULL);
+ DCHECK(begin_ != NULL);
+ DCHECK(limit_ != NULL);
+ byte* addr = const_cast<byte*>(reinterpret_cast<const byte*>(begin_));
+ const size_t length = limit_ - begin_;
+ ptr_ = reinterpret_cast<const Object**>(addr);
int result = madvise(addr, length, MADV_DONTNEED);
if (result == -1) {
PLOG(WARNING) << "madvise failed";
diff --git a/src/mark_stack.h b/src/mark_stack.h
index 4301e0e..cd308c5 100644
--- a/src/mark_stack.h
+++ b/src/mark_stack.h
@@ -50,6 +50,8 @@
return ptr_ == begin_;
}
+ void Reset();
+
private:
MarkStack() :
begin_(NULL), limit_(NULL), ptr_(NULL) {
diff --git a/src/mark_sweep.cc b/src/mark_sweep.cc
index 381c7f0..b80d1f6 100644
--- a/src/mark_sweep.cc
+++ b/src/mark_sweep.cc
@@ -36,12 +36,27 @@
namespace art {
-void MarkSweep::Init() {
- mark_stack_ = MarkStack::Create();
+MarkSweep::MarkSweep(MarkStack* mark_stack)
+ : mark_stack_(mark_stack),
+ heap_(NULL),
+ mark_bitmap_(NULL),
+ live_bitmap_(NULL),
+ finger_(NULL),
+ condemned_(NULL),
+ soft_reference_list_(NULL),
+ weak_reference_list_(NULL),
+ finalizer_reference_list_(NULL),
+ phantom_reference_list_(NULL),
+ cleared_reference_list_(NULL),
+ class_count_(0), array_count_(0), other_count_(0) {
+ DCHECK(mark_stack_ != NULL);
+}
+void MarkSweep::Init() {
heap_ = Runtime::Current()->GetHeap();
mark_bitmap_ = heap_->GetMarkBits();
live_bitmap_ = heap_->GetLiveBits();
+ mark_stack_->Reset();
// TODO: if concurrent, clear the card table.
@@ -598,8 +613,8 @@
#ifndef NDEBUG
VLOG(heap) << "MarkSweep scanned classes=" << class_count_ << " arrays=" << array_count_ << " other=" << other_count_;
#endif
- delete mark_stack_;
mark_bitmap_->Clear();
+ mark_stack_->Reset();
}
} // namespace art
diff --git a/src/mark_sweep.h b/src/mark_sweep.h
index dce4b52..7fda6ea 100644
--- a/src/mark_sweep.h
+++ b/src/mark_sweep.h
@@ -30,20 +30,7 @@
class MarkSweep {
public:
- MarkSweep() :
- mark_stack_(NULL),
- heap_(NULL),
- mark_bitmap_(NULL),
- live_bitmap_(NULL),
- finger_(NULL),
- condemned_(NULL),
- soft_reference_list_(NULL),
- weak_reference_list_(NULL),
- finalizer_reference_list_(NULL),
- phantom_reference_list_(NULL),
- cleared_reference_list_(NULL),
- class_count_(0), array_count_(0), other_count_(0) {
- }
+ MarkSweep(MarkStack* mark_stack);
~MarkSweep();