Refactor array access for the interpreter.

Adds GetWithoutChecks and SetWithoutChecks methods in PrimitiveArray and use
them in the interpreter. Updates Get and Set methods to rely on them and adds
some DCHECK to control exception flow.

Renames IsValidIndex into CheckIsValidIndex to reflect it can throw an
exception. It's also more consistent with ObjectArray::CheckIsAssignable.

Make ThrowArrayIndexOutOfBoundsException private in Array since it's only used
by Array::CheckIsValidIndex.

Updates DoFilledNewArray to use SetWithoutChecks rather than Set.

Change-Id: I2fd314d77a67cf969843d499b86d04ca7b7a43e6
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());
   }
 }