Merge "Clang build support, -Wthread-safety with GCC 4.6." into dalvik-dev
diff --git a/src/base/logging.cc b/src/base/logging.cc
index c9f28c8..a19580c 100644
--- a/src/base/logging.cc
+++ b/src/base/logging.cc
@@ -139,10 +139,6 @@
   delete data_;
 }
 
-std::ostream& LogMessage::stream() {
-  return data_->buffer;
-}
-
 HexDump::HexDump(const void* address, size_t byte_count, bool show_actual_addresses)
     : address_(address), byte_count_(byte_count), show_actual_addresses_(show_actual_addresses) {
 }
diff --git a/src/base/logging.h b/src/base/logging.h
index f250ce0..8d89e4d 100644
--- a/src/base/logging.h
+++ b/src/base/logging.h
@@ -184,8 +184,12 @@
   LogMessage(const char* file, int line, LogSeverity severity, int error)
     : data_(new LogMessageData(file, line, severity, error)) {
   }
+
   ~LogMessage() LOCKS_EXCLUDED(Locks::logging_lock_);
-  std::ostream& stream();
+
+  std::ostream& stream() {
+    return data_->buffer;
+  }
 
  private:
   static void LogLine(const LogMessageData& data, const char*);
diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc
index 5992c67..ab0abb2 100644
--- a/src/interpreter/interpreter.cc
+++ b/src/interpreter/interpreter.cc
@@ -970,10 +970,11 @@
         Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x());
         if (UNLIKELY(obj == NULL)) {
           ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+          HANDLE_PENDING_EXCEPTION();
         } else {
           DoMonitorEnter(self, obj);
+          POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_1xx);
         }
-        POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_1xx);
         break;
       }
       case Instruction::MONITOR_EXIT: {
@@ -981,10 +982,11 @@
         Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x());
         if (UNLIKELY(obj == NULL)) {
           ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
+          HANDLE_PENDING_EXCEPTION();
         } else {
           DoMonitorExit(self, obj);
+          POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_1xx);
         }
-        POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_1xx);
         break;
       }
       case Instruction::CHECK_CAST: {
@@ -1687,10 +1689,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