Merge "Mark stack create once per heap." into ics-mr1-plus-art
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();