ART: Fix valgrind

Allow ValgrindMallocSpace wrapper for RosAlloc.Requires refactoring,
as ValgrindMallocSpace was bound to the signature of DlMallocSpace.

Also turn of native stack dumping when running under Valgrind to
work around b/18119146.

Ritzperf before and after
Mean               3190.725   3082.475
Standard Error     11.68407   10.37911
Mode               3069       2980
Median             3182.5     3051.5
Variance           16382.117  12927.125
Standard Deviation 127.99264  113.69751
Kurtosis           1.1065632  0.3657799
Skewness           0.9013805  0.9117792
Range              644        528
Minimum            2991       2928
Maximum            3635       3456
Count              120        120

Bug: 18119146
Change-Id: I25558ea7cb578406011dede9d3d0bdbfee4ff4d5
diff --git a/runtime/gc/space/rosalloc_space.cc b/runtime/gc/space/rosalloc_space.cc
index ff8b570..74d1a2b 100644
--- a/runtime/gc/space/rosalloc_space.cc
+++ b/runtime/gc/space/rosalloc_space.cc
@@ -44,10 +44,10 @@
 // TODO: Fix
 // template class ValgrindMallocSpace<RosAllocSpace, allocator::RosAlloc*>;
 
-RosAllocSpace::RosAllocSpace(const std::string& name, MemMap* mem_map,
+RosAllocSpace::RosAllocSpace(MemMap* mem_map, size_t initial_size, const std::string& name,
                              art::gc::allocator::RosAlloc* rosalloc, uint8_t* begin, uint8_t* end,
                              uint8_t* limit, size_t growth_limit, bool can_move_objects,
-                             size_t starting_size, size_t initial_size, bool low_memory_mode)
+                             size_t starting_size, bool low_memory_mode)
     : MallocSpace(name, mem_map, begin, end, limit, growth_limit, true, can_move_objects,
                   starting_size, initial_size),
       rosalloc_(rosalloc), low_memory_mode_(low_memory_mode) {
@@ -59,8 +59,11 @@
                                                size_t growth_limit, size_t capacity,
                                                bool low_memory_mode, bool can_move_objects) {
   DCHECK(mem_map != nullptr);
+
+  bool running_on_valgrind = Runtime::Current()->RunningOnValgrind();
+
   allocator::RosAlloc* rosalloc = CreateRosAlloc(mem_map->Begin(), starting_size, initial_size,
-                                                 capacity, low_memory_mode);
+                                                 capacity, low_memory_mode, running_on_valgrind);
   if (rosalloc == NULL) {
     LOG(ERROR) << "Failed to initialize rosalloc for alloc space (" << name << ")";
     return NULL;
@@ -76,12 +79,13 @@
   uint8_t* begin = mem_map->Begin();
   // TODO: Fix RosAllocSpace to support valgrind. There is currently some issues with
   // AllocationSize caused by redzones. b/12944686
-  if (Runtime::Current()->RunningOnValgrind()) {
-    UNIMPLEMENTED(FATAL);
-    UNREACHABLE();
+  if (running_on_valgrind) {
+    return new ValgrindMallocSpace<RosAllocSpace, kDefaultValgrindRedZoneBytes, false, true>(
+        mem_map, initial_size, name, rosalloc, begin, end, begin + capacity, growth_limit,
+        can_move_objects, starting_size, low_memory_mode);
   } else {
-    return new RosAllocSpace(name, mem_map, rosalloc, begin, end, begin + capacity, growth_limit,
-                             can_move_objects, starting_size, initial_size, low_memory_mode);
+    return new RosAllocSpace(mem_map, initial_size, name, rosalloc, begin, end, begin + capacity,
+                             growth_limit, can_move_objects, starting_size, low_memory_mode);
   }
 }
 
@@ -128,7 +132,8 @@
 
 allocator::RosAlloc* RosAllocSpace::CreateRosAlloc(void* begin, size_t morecore_start,
                                                    size_t initial_size,
-                                                   size_t maximum_size, bool low_memory_mode) {
+                                                   size_t maximum_size, bool low_memory_mode,
+                                                   bool running_on_valgrind) {
   // clear errno to allow PLOG on error
   errno = 0;
   // create rosalloc using our backing storage starting at begin and
@@ -138,7 +143,8 @@
       begin, morecore_start, maximum_size,
       low_memory_mode ?
           art::gc::allocator::RosAlloc::kPageReleaseModeAll :
-          art::gc::allocator::RosAlloc::kPageReleaseModeSizeAndEnd);
+          art::gc::allocator::RosAlloc::kPageReleaseModeSizeAndEnd,
+      running_on_valgrind);
   if (rosalloc != NULL) {
     rosalloc->SetFootprintLimit(initial_size);
   } else {
@@ -167,12 +173,19 @@
   return result;
 }
 
-MallocSpace* RosAllocSpace::CreateInstance(const std::string& name, MemMap* mem_map, void* allocator,
-                                           uint8_t* begin, uint8_t* end, uint8_t* limit, size_t growth_limit,
+MallocSpace* RosAllocSpace::CreateInstance(MemMap* mem_map, const std::string& name,
+                                           void* allocator, uint8_t* begin, uint8_t* end,
+                                           uint8_t* limit, size_t growth_limit,
                                            bool can_move_objects) {
-  return new RosAllocSpace(name, mem_map, reinterpret_cast<allocator::RosAlloc*>(allocator),
-                           begin, end, limit, growth_limit, can_move_objects, starting_size_,
-                           initial_size_, low_memory_mode_);
+  if (Runtime::Current()->RunningOnValgrind()) {
+    return new ValgrindMallocSpace<RosAllocSpace, kDefaultValgrindRedZoneBytes, false, true>(
+        mem_map, initial_size_, name, reinterpret_cast<allocator::RosAlloc*>(allocator), begin, end,
+        limit, growth_limit, can_move_objects, starting_size_, low_memory_mode_);
+  } else {
+    return new RosAllocSpace(mem_map, initial_size_, name,
+                             reinterpret_cast<allocator::RosAlloc*>(allocator), begin, end, limit,
+                             growth_limit, can_move_objects, starting_size_, low_memory_mode_);
+  }
 }
 
 size_t RosAllocSpace::Free(Thread* self, mirror::Object* ptr) {
@@ -353,7 +366,7 @@
   SetEnd(begin_ + starting_size_);
   delete rosalloc_;
   rosalloc_ = CreateRosAlloc(mem_map_->Begin(), starting_size_, initial_size_, Capacity(),
-                             low_memory_mode_);
+                             low_memory_mode_, Runtime::Current()->RunningOnValgrind());
   SetFootprintLimit(footprint_limit);
 }