Merge "Refactor array access for the interpreter."
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index be358e3..0f94ccd 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -200,26 +200,20 @@
     DCHECK(self->IsExceptionPending());
     return false;
   }
+  uint32_t arg[5];  // only used in filled-new-array.
+  uint32_t vregC;   // only used in filled-new-array-range.
   if (is_range) {
-    uint32_t vregC = inst->VRegC_3rc();
-    const bool is_primitive_int_component = componentClass->IsPrimitiveInt();
-    for (int32_t i = 0; i < length; ++i) {
-      if (is_primitive_int_component) {
-        newArray->AsIntArray()->Set(i, shadow_frame.GetVReg(vregC + i));
-      } else {
-        newArray->AsObjectArray<Object>()->Set(i, shadow_frame.GetVRegReference(vregC + i));
-      }
-    }
+    vregC = inst->VRegC_3rc();
   } else {
-    uint32_t arg[5];
     inst->GetArgs(arg);
-    const bool is_primitive_int_component = componentClass->IsPrimitiveInt();
-    for (int32_t i = 0; i < length; ++i) {
-      if (is_primitive_int_component) {
-        newArray->AsIntArray()->Set(i, shadow_frame.GetVReg(arg[i]));
-      } else {
-        newArray->AsObjectArray<Object>()->Set(i, shadow_frame.GetVRegReference(arg[i]));
-      }
+  }
+  const bool is_primitive_int_component = componentClass->IsPrimitiveInt();
+  for (int32_t i = 0; i < length; ++i) {
+    size_t src_reg = is_range ? vregC + i : arg[i];
+    if (is_primitive_int_component) {
+      newArray->AsIntArray()->SetWithoutChecks(i, shadow_frame.GetVReg(src_reg));
+    } else {
+      newArray->AsObjectArray<Object>()->SetWithoutChecks(i, shadow_frame.GetVRegReference(src_reg));
     }
   }
 
diff --git a/runtime/interpreter/interpreter_goto_table_impl.cc b/runtime/interpreter/interpreter_goto_table_impl.cc
index 942c275..ca03885 100644
--- a/runtime/interpreter/interpreter_goto_table_impl.cc
+++ b/runtime/interpreter/interpreter_goto_table_impl.cc
@@ -932,8 +932,8 @@
     } else {
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
       BooleanArray* array = a->AsBooleanArray();
-      if (LIKELY(array->IsValidIndex(index))) {
-        shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetData()[index]);
+      if (LIKELY(array->CheckIsValidIndex(index))) {
+        shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
         ADVANCE(2);
       } else {
         HANDLE_PENDING_EXCEPTION();
@@ -950,8 +950,8 @@
     } else {
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
       ByteArray* array = a->AsByteArray();
-      if (LIKELY(array->IsValidIndex(index))) {
-        shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetData()[index]);
+      if (LIKELY(array->CheckIsValidIndex(index))) {
+        shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
         ADVANCE(2);
       } else {
         HANDLE_PENDING_EXCEPTION();
@@ -968,8 +968,8 @@
     } else {
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
       CharArray* array = a->AsCharArray();
-      if (LIKELY(array->IsValidIndex(index))) {
-        shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetData()[index]);
+      if (LIKELY(array->CheckIsValidIndex(index))) {
+        shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
         ADVANCE(2);
       } else {
         HANDLE_PENDING_EXCEPTION();
@@ -986,8 +986,8 @@
     } else {
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
       ShortArray* array = a->AsShortArray();
-      if (LIKELY(array->IsValidIndex(index))) {
-        shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetData()[index]);
+      if (LIKELY(array->CheckIsValidIndex(index))) {
+        shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
         ADVANCE(2);
       } else {
         HANDLE_PENDING_EXCEPTION();
@@ -1004,8 +1004,8 @@
     } else {
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
       IntArray* array = a->AsIntArray();
-      if (LIKELY(array->IsValidIndex(index))) {
-        shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetData()[index]);
+      if (LIKELY(array->CheckIsValidIndex(index))) {
+        shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
         ADVANCE(2);
       } else {
         HANDLE_PENDING_EXCEPTION();
@@ -1022,8 +1022,8 @@
     } else {
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
       LongArray* array = a->AsLongArray();
-      if (LIKELY(array->IsValidIndex(index))) {
-        shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetData()[index]);
+      if (LIKELY(array->CheckIsValidIndex(index))) {
+        shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
         ADVANCE(2);
       } else {
         HANDLE_PENDING_EXCEPTION();
@@ -1040,7 +1040,7 @@
     } else {
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
       ObjectArray<Object>* array = a->AsObjectArray<Object>();
-      if (LIKELY(array->IsValidIndex(index))) {
+      if (LIKELY(array->CheckIsValidIndex(index))) {
         shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
         ADVANCE(2);
       } else {
@@ -1059,8 +1059,8 @@
       uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
       BooleanArray* array = a->AsBooleanArray();
-      if (LIKELY(array->IsValidIndex(index))) {
-        array->GetData()[index] = val;
+      if (LIKELY(array->CheckIsValidIndex(index))) {
+        array->SetWithoutChecks(index, val);
         ADVANCE(2);
       } else {
         HANDLE_PENDING_EXCEPTION();
@@ -1078,8 +1078,8 @@
       int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
       ByteArray* array = a->AsByteArray();
-      if (LIKELY(array->IsValidIndex(index))) {
-        array->GetData()[index] = val;
+      if (LIKELY(array->CheckIsValidIndex(index))) {
+        array->SetWithoutChecks(index, val);
         ADVANCE(2);
       } else {
         HANDLE_PENDING_EXCEPTION();
@@ -1097,8 +1097,8 @@
       uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
       CharArray* array = a->AsCharArray();
-      if (LIKELY(array->IsValidIndex(index))) {
-        array->GetData()[index] = val;
+      if (LIKELY(array->CheckIsValidIndex(index))) {
+        array->SetWithoutChecks(index, val);
         ADVANCE(2);
       } else {
         HANDLE_PENDING_EXCEPTION();
@@ -1116,8 +1116,8 @@
       int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
       ShortArray* array = a->AsShortArray();
-      if (LIKELY(array->IsValidIndex(index))) {
-        array->GetData()[index] = val;
+      if (LIKELY(array->CheckIsValidIndex(index))) {
+        array->SetWithoutChecks(index, val);
         ADVANCE(2);
       } else {
         HANDLE_PENDING_EXCEPTION();
@@ -1135,8 +1135,8 @@
       int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
       IntArray* array = a->AsIntArray();
-      if (LIKELY(array->IsValidIndex(index))) {
-        array->GetData()[index] = val;
+      if (LIKELY(array->CheckIsValidIndex(index))) {
+        array->SetWithoutChecks(index, val);
         ADVANCE(2);
       } else {
         HANDLE_PENDING_EXCEPTION();
@@ -1154,8 +1154,8 @@
       int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
       LongArray* array = a->AsLongArray();
-      if (LIKELY(array->IsValidIndex(index))) {
-        array->GetData()[index] = val;
+      if (LIKELY(array->CheckIsValidIndex(index))) {
+        array->SetWithoutChecks(index, val);
         ADVANCE(2);
       } else {
         HANDLE_PENDING_EXCEPTION();
@@ -1173,7 +1173,7 @@
       int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
       Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
       ObjectArray<Object>* array = a->AsObjectArray<Object>();
-      if (LIKELY(array->IsValidIndex(index) && array->CheckAssignable(val))) {
+      if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
         array->SetWithoutChecks(index, val);
         ADVANCE(2);
       } else {
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index 75041ea..7631736 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -830,8 +830,8 @@
         }
         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
         BooleanArray* array = a->AsBooleanArray();
-        if (LIKELY(array->IsValidIndex(index))) {
-          shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetData()[index]);
+        if (LIKELY(array->CheckIsValidIndex(index))) {
+          shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
           inst = inst->Next_2xx();
         } else {
           HANDLE_PENDING_EXCEPTION();
@@ -848,8 +848,8 @@
         }
         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
         ByteArray* array = a->AsByteArray();
-        if (LIKELY(array->IsValidIndex(index))) {
-          shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetData()[index]);
+        if (LIKELY(array->CheckIsValidIndex(index))) {
+          shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
           inst = inst->Next_2xx();
         } else {
           HANDLE_PENDING_EXCEPTION();
@@ -866,8 +866,8 @@
         }
         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
         CharArray* array = a->AsCharArray();
-        if (LIKELY(array->IsValidIndex(index))) {
-          shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetData()[index]);
+        if (LIKELY(array->CheckIsValidIndex(index))) {
+          shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
           inst = inst->Next_2xx();
         } else {
           HANDLE_PENDING_EXCEPTION();
@@ -884,8 +884,8 @@
         }
         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
         ShortArray* array = a->AsShortArray();
-        if (LIKELY(array->IsValidIndex(index))) {
-          shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetData()[index]);
+        if (LIKELY(array->CheckIsValidIndex(index))) {
+          shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
           inst = inst->Next_2xx();
         } else {
           HANDLE_PENDING_EXCEPTION();
@@ -902,8 +902,8 @@
         }
         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
         IntArray* array = a->AsIntArray();
-        if (LIKELY(array->IsValidIndex(index))) {
-          shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetData()[index]);
+        if (LIKELY(array->CheckIsValidIndex(index))) {
+          shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
           inst = inst->Next_2xx();
         } else {
           HANDLE_PENDING_EXCEPTION();
@@ -920,8 +920,8 @@
         }
         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
         LongArray* array = a->AsLongArray();
-        if (LIKELY(array->IsValidIndex(index))) {
-          shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetData()[index]);
+        if (LIKELY(array->CheckIsValidIndex(index))) {
+          shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
           inst = inst->Next_2xx();
         } else {
           HANDLE_PENDING_EXCEPTION();
@@ -938,7 +938,7 @@
         }
         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
         ObjectArray<Object>* array = a->AsObjectArray<Object>();
-        if (LIKELY(array->IsValidIndex(index))) {
+        if (LIKELY(array->CheckIsValidIndex(index))) {
           shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
           inst = inst->Next_2xx();
         } else {
@@ -957,8 +957,8 @@
         uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
         BooleanArray* array = a->AsBooleanArray();
-        if (LIKELY(array->IsValidIndex(index))) {
-          array->GetData()[index] = val;
+        if (LIKELY(array->CheckIsValidIndex(index))) {
+          array->SetWithoutChecks(index, val);
           inst = inst->Next_2xx();
         } else {
           HANDLE_PENDING_EXCEPTION();
@@ -976,8 +976,8 @@
         int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
         ByteArray* array = a->AsByteArray();
-        if (LIKELY(array->IsValidIndex(index))) {
-          array->GetData()[index] = val;
+        if (LIKELY(array->CheckIsValidIndex(index))) {
+          array->SetWithoutChecks(index, val);
           inst = inst->Next_2xx();
         } else {
           HANDLE_PENDING_EXCEPTION();
@@ -995,8 +995,8 @@
         uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
         CharArray* array = a->AsCharArray();
-        if (LIKELY(array->IsValidIndex(index))) {
-          array->GetData()[index] = val;
+        if (LIKELY(array->CheckIsValidIndex(index))) {
+          array->SetWithoutChecks(index, val);
           inst = inst->Next_2xx();
         } else {
           HANDLE_PENDING_EXCEPTION();
@@ -1014,8 +1014,8 @@
         int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
         ShortArray* array = a->AsShortArray();
-        if (LIKELY(array->IsValidIndex(index))) {
-          array->GetData()[index] = val;
+        if (LIKELY(array->CheckIsValidIndex(index))) {
+          array->SetWithoutChecks(index, val);
           inst = inst->Next_2xx();
         } else {
           HANDLE_PENDING_EXCEPTION();
@@ -1033,8 +1033,8 @@
         int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
         IntArray* array = a->AsIntArray();
-        if (LIKELY(array->IsValidIndex(index))) {
-          array->GetData()[index] = val;
+        if (LIKELY(array->CheckIsValidIndex(index))) {
+          array->SetWithoutChecks(index, val);
           inst = inst->Next_2xx();
         } else {
           HANDLE_PENDING_EXCEPTION();
@@ -1052,8 +1052,8 @@
         int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
         LongArray* array = a->AsLongArray();
-        if (LIKELY(array->IsValidIndex(index))) {
-          array->GetData()[index] = val;
+        if (LIKELY(array->CheckIsValidIndex(index))) {
+          array->SetWithoutChecks(index, val);
           inst = inst->Next_2xx();
         } else {
           HANDLE_PENDING_EXCEPTION();
@@ -1071,7 +1071,7 @@
         int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
         Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
         ObjectArray<Object>* array = a->AsObjectArray<Object>();
-        if (LIKELY(array->IsValidIndex(index) && array->CheckAssignable(val))) {
+        if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
           array->SetWithoutChecks(index, val);
           inst = inst->Next_2xx();
         } else {
diff --git a/runtime/mirror/array.h b/runtime/mirror/array.h
index 5265946..207573f 100644
--- a/runtime/mirror/array.h
+++ b/runtime/mirror/array.h
@@ -19,6 +19,7 @@
 
 #include "object.h"
 #include "gc/heap.h"
+#include "thread.h"
 
 namespace art {
 namespace mirror {
@@ -83,7 +84,9 @@
     return reinterpret_cast<const void*>(data);
   }
 
-  bool IsValidIndex(int32_t index) const
+  // Returns true if the index is valid. If not, throws an ArrayIndexOutOfBoundsException and
+  // returns false.
+  bool CheckIsValidIndex(int32_t index) const
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     if (UNLIKELY(static_cast<uint32_t>(index) >= static_cast<uint32_t>(GetLength()))) {
       ThrowArrayIndexOutOfBoundsException(index);
@@ -93,12 +96,13 @@
   }
 
  protected:
-  void ThrowArrayIndexOutOfBoundsException(int32_t index) const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   void ThrowArrayStoreException(Object* object) const
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
  private:
+  void ThrowArrayIndexOutOfBoundsException(int32_t index) const
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
   // The number of array elements.
   int32_t length_;
   // Marker for the data (used by generated code)
@@ -126,18 +130,31 @@
   }
 
   T Get(int32_t i) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    if (!IsValidIndex(i)) {
+    if (UNLIKELY(!CheckIsValidIndex(i))) {
+      DCHECK(Thread::Current()->IsExceptionPending());
       return T(0);
     }
+    return GetWithoutChecks(i);
+  }
+
+  T GetWithoutChecks(int32_t i) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    DCHECK(CheckIsValidIndex(i));
     return GetData()[i];
   }
 
   void Set(int32_t i, T value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    if (IsValidIndex(i)) {
-      GetData()[i] = value;
+    if (LIKELY(CheckIsValidIndex(i))) {
+      SetWithoutChecks(i, value);
+    } else {
+      DCHECK(Thread::Current()->IsExceptionPending());
     }
   }
 
+  void SetWithoutChecks(int32_t i, T value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    DCHECK(CheckIsValidIndex(i));
+    GetData()[i] = value;
+  }
+
   static void SetArrayClass(Class* array_class) {
     CHECK(array_class_ == NULL);
     CHECK(array_class != NULL);
diff --git a/runtime/mirror/object_array-inl.h b/runtime/mirror/object_array-inl.h
index be49b42..6a50dfe 100644
--- a/runtime/mirror/object_array-inl.h
+++ b/runtime/mirror/object_array-inl.h
@@ -50,11 +50,11 @@
 
 template<class T>
 inline T* ObjectArray<T>::Get(int32_t i) const {
-  if (UNLIKELY(!IsValidIndex(i))) {
+  if (UNLIKELY(!CheckIsValidIndex(i))) {
+    DCHECK(Thread::Current()->IsExceptionPending());
     return NULL;
   }
-  MemberOffset data_offset(DataOffset(sizeof(Object*)).Int32Value() + i * sizeof(Object*));
-  return GetFieldObject<T*>(data_offset, false);
+  return GetWithoutChecks(i);
 }
 
 template<class T>
@@ -71,9 +71,8 @@
 
 template<class T>
 inline void ObjectArray<T>::Set(int32_t i, T* object) {
-  if (LIKELY(IsValidIndex(i) && CheckAssignable(object))) {
-    MemberOffset data_offset(DataOffset(sizeof(Object*)).Int32Value() + i * sizeof(Object*));
-    SetFieldObject(data_offset, object, false);
+  if (LIKELY(CheckIsValidIndex(i) && CheckAssignable(object))) {
+    SetWithoutChecks(i, object);
   } else {
     DCHECK(Thread::Current()->IsExceptionPending());
   }
@@ -81,21 +80,24 @@
 
 template<class T>
 inline void ObjectArray<T>::SetWithoutChecks(int32_t i, T* object) {
-  DCHECK(IsValidIndex(i));
+  DCHECK(CheckIsValidIndex(i));
+  DCHECK(CheckAssignable(object));
   MemberOffset data_offset(DataOffset(sizeof(Object*)).Int32Value() + i * sizeof(Object*));
   SetFieldObject(data_offset, object, false);
 }
 
 template<class T>
 inline void ObjectArray<T>::SetPtrWithoutChecks(int32_t i, T* object) {
-  DCHECK(IsValidIndex(i));
+  DCHECK(CheckIsValidIndex(i));
+  // TODO enable this check. It fails when writing the image in ImageWriter::FixupObjectArray.
+  // DCHECK(CheckAssignable(object));
   MemberOffset data_offset(DataOffset(sizeof(Object*)).Int32Value() + i * sizeof(Object*));
   SetFieldPtr(data_offset, object, false);
 }
 
 template<class T>
 inline T* ObjectArray<T>::GetWithoutChecks(int32_t i) const {
-  DCHECK(IsValidIndex(i));
+  DCHECK(CheckIsValidIndex(i));
   MemberOffset data_offset(DataOffset(sizeof(Object*)).Int32Value() + i * sizeof(Object*));
   return GetFieldObject<T*>(data_offset, false);
 }
@@ -104,10 +106,10 @@
 inline void ObjectArray<T>::Copy(const ObjectArray<T>* src, int src_pos,
                                  ObjectArray<T>* dst, int dst_pos,
                                  size_t length) {
-  if (src->IsValidIndex(src_pos) &&
-      src->IsValidIndex(src_pos+length-1) &&
-      dst->IsValidIndex(dst_pos) &&
-      dst->IsValidIndex(dst_pos+length-1)) {
+  if (src->CheckIsValidIndex(src_pos) &&
+      src->CheckIsValidIndex(src_pos + length - 1) &&
+      dst->CheckIsValidIndex(dst_pos) &&
+      dst->CheckIsValidIndex(dst_pos + length - 1)) {
     MemberOffset src_offset(DataOffset(sizeof(Object*)).Int32Value() + src_pos * sizeof(Object*));
     MemberOffset dst_offset(DataOffset(sizeof(Object*)).Int32Value() + dst_pos * sizeof(Object*));
     Class* array_class = dst->GetClass();
@@ -139,6 +141,8 @@
       }
     }
     heap->WriteBarrierArray(dst, dst_pos, length);
+  } else {
+    DCHECK(Thread::Current()->IsExceptionPending());
   }
 }