Optimize aput-object in interpreter.
Inline ObjectArray::Set test about valid index and valid object. Adding
ObjectArray::IsValidObject method to check for ArrayStoreException and
call it from interpreter.
Change-Id: I99beeb531455049fc189f9b8e8f4f020591f7bab
diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc
index 5992c67..cda376b 100644
--- a/src/interpreter/interpreter.cc
+++ b/src/interpreter/interpreter.cc
@@ -1687,10 +1687,15 @@
HANDLE_PENDING_EXCEPTION();
break;
}
- Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x());
int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
- a->AsObjectArray<Object>()->Set(index, val);
- POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
+ Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x());
+ ObjectArray<Object>* array = a->AsObjectArray<Object>();
+ if (LIKELY(array->IsValidIndex(index) && array->CheckAssignable(val))) {
+ array->SetWithoutChecks(index, val);
+ inst = inst->Next_2xx();
+ } else {
+ HANDLE_PENDING_EXCEPTION();
+ }
break;
}
case Instruction::IGET_BOOLEAN:
diff --git a/src/mirror/object_array-inl.h b/src/mirror/object_array-inl.h
index d981428..05bce95 100644
--- a/src/mirror/object_array-inl.h
+++ b/src/mirror/object_array-inl.h
@@ -23,6 +23,7 @@
#include "mirror/class.h"
#include "mirror/field.h"
#include "runtime.h"
+#include "thread.h"
namespace art {
namespace mirror {
@@ -47,17 +48,24 @@
}
template<class T>
-inline void ObjectArray<T>::Set(int32_t i, T* object) {
- if (LIKELY(IsValidIndex(i))) {
- if (object != NULL) {
- Class* element_class = GetClass()->GetComponentType();
- if (UNLIKELY(!object->InstanceOf(element_class))) {
- ThrowArrayStoreException(object);
- return;
- }
+inline bool ObjectArray<T>::CheckAssignable(T* object) {
+ if (object != NULL) {
+ Class* element_class = GetClass()->GetComponentType();
+ if (UNLIKELY(!object->InstanceOf(element_class))) {
+ ThrowArrayStoreException(object);
+ return false;
}
+ }
+ return true;
+}
+
+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);
+ } else {
+ DCHECK(Thread::Current()->IsExceptionPending());
}
}
diff --git a/src/mirror/object_array.h b/src/mirror/object_array.h
index 3d04b39..08a8d62 100644
--- a/src/mirror/object_array.h
+++ b/src/mirror/object_array.h
@@ -30,6 +30,10 @@
T* Get(int32_t i) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ // Returns true if the object can be stored into the array. If not, throws
+ // an ArrayStoreException and returns false.
+ bool CheckAssignable(T* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
void Set(int32_t i, T* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Set element without bound and element type checks, to be used in limited