Ensure usable space data is zeroed in arrays.

Address other outstanding review comments.

Change-Id: Iaffe04de080772a0d0c5fd973bcac0e23c8c3e25
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index 6ef0082..3da7409 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -40,7 +40,7 @@
 
 inline mirror::Class* ClassLinker::FindArrayClass(Thread* self, mirror::Class* element_class) {
   for (size_t i = 0; i < kFindArrayCacheSize; ++i) {
-    // Read the cached the array class once to avoid races with other threads setting it.
+    // Read the cached array class once to avoid races with other threads setting it.
     mirror::Class* array_class = find_array_class_cache_[i];
     if (array_class != nullptr && array_class->GetComponentType() == element_class) {
       return array_class;
diff --git a/runtime/gc/heap-inl.h b/runtime/gc/heap-inl.h
index ce9dcea..e089ef2 100644
--- a/runtime/gc/heap-inl.h
+++ b/runtime/gc/heap-inl.h
@@ -74,7 +74,7 @@
     obj->AssertSelfBrooksPointer();
   }
   pre_fence_visitor(obj, usable_size);
-  if (kIsDebugBuild && klass != nullptr && Runtime::Current()->IsStarted()) {
+  if (kIsDebugBuild && Runtime::Current()->IsStarted()) {
     CHECK_LE(obj->SizeOf(), usable_size);
   }
   const size_t new_num_bytes_allocated =
diff --git a/runtime/gc/space/rosalloc_space.cc b/runtime/gc/space/rosalloc_space.cc
index 567ec99..fe8421d 100644
--- a/runtime/gc/space/rosalloc_space.cc
+++ b/runtime/gc/space/rosalloc_space.cc
@@ -45,9 +45,9 @@
 }
 
 RosAllocSpace* RosAllocSpace::CreateFromMemMap(MemMap* mem_map, const std::string& name,
-                                            size_t starting_size, size_t initial_size,
-                                            size_t growth_limit, size_t capacity,
-                                            bool low_memory_mode) {
+                                               size_t starting_size, size_t initial_size,
+                                               size_t growth_limit, size_t capacity,
+                                               bool low_memory_mode) {
   DCHECK(mem_map != nullptr);
   allocator::RosAlloc* rosalloc = CreateRosAlloc(mem_map->Begin(), starting_size, initial_size,
                                                  low_memory_mode);
@@ -73,8 +73,8 @@
 }
 
 RosAllocSpace* RosAllocSpace::Create(const std::string& name, size_t initial_size,
-                                  size_t growth_limit, size_t capacity, byte* requested_begin,
-                                  bool low_memory_mode) {
+                                     size_t growth_limit, size_t capacity, byte* requested_begin,
+                                     bool low_memory_mode) {
   uint64_t start_time = 0;
   if (VLOG_IS_ON(heap) || VLOG_IS_ON(startup)) {
     start_time = NanoTime();
diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h
index d44f75f..8158bc5 100644
--- a/runtime/mirror/array-inl.h
+++ b/runtime/mirror/array-inl.h
@@ -91,20 +91,26 @@
 // array.
 class SetLengthToUsableSizeVisitor {
  public:
-  SetLengthToUsableSizeVisitor(size_t header_size, size_t component_size) :
-      header_size_(header_size), component_size_(component_size) {
+  SetLengthToUsableSizeVisitor(int32_t min_length, size_t header_size, size_t component_size) :
+      minimum_length_(min_length), header_size_(header_size), component_size_(component_size) {
   }
 
   void operator()(Object* obj, size_t usable_size) const
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     // Avoid AsArray as object is not yet in live bitmap or allocation stack.
     Array* array = down_cast<Array*>(obj);
-    uint32_t length = (usable_size - header_size_) / component_size_;
     // DCHECK(array->IsArrayInstance());
+    int32_t length = (usable_size - header_size_) / component_size_;
+    DCHECK_GE(length, minimum_length_);
+    byte* old_end = reinterpret_cast<byte*>(array->GetRawData(component_size_, minimum_length_));
+    byte* new_end = reinterpret_cast<byte*>(array->GetRawData(component_size_, length));
+    // Ensure space beyond original allocation is zeroed.
+    memset(old_end, 0, new_end - old_end);
     array->SetLength(length);
   }
 
  private:
+  const int32_t minimum_length_;
   const size_t header_size_;
   const size_t component_size_;
 
@@ -128,12 +134,14 @@
         heap->AllocObjectWithAllocator<kIsInstrumented, true>(self, array_class, size,
                                                               allocator_type, visitor));
   } else {
-    SetLengthToUsableSizeVisitor visitor(HeaderSize(component_size), component_size);
+    SetLengthToUsableSizeVisitor visitor(component_count, HeaderSize(component_size),
+                                         component_size);
     result = down_cast<Array*>(
         heap->AllocObjectWithAllocator<kIsInstrumented, true>(self, array_class, size,
                                                               allocator_type, visitor));
   }
   if (kIsDebugBuild && result != nullptr && Runtime::Current()->IsStarted()) {
+    CHECK_EQ(array_class->GetComponentSize(), component_size);
     if (!fill_usable) {
       CHECK_EQ(result->SizeOf(), size);
     } else {