am 9a783d6a: Fix FindDeclaredVirtualMethod(DexCache...) for miranda methods

* commit '9a783d6a0cb437fc0d9ffcc84502912f3d1cb73b':
  Fix FindDeclaredVirtualMethod(DexCache...) for miranda methods
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 6af98cf..6645303 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -2153,6 +2153,13 @@
   } else {
     LOG(FATAL) << "Invalid current allocator " << current_allocator_;
   }
+  if (IsGcConcurrent()) {
+    // Disable concurrent GC check so that we don't have spammy JNI requests.
+    // This gets recalculated in GrowForUtilization. It is important that it is disabled /
+    // calculated in the same thread so that there aren't any races that can cause it to become
+    // permanantly disabled. b/17942071
+    concurrent_start_bytes_ = std::numeric_limits<size_t>::max();
+  }
   CHECK(collector != nullptr)
       << "Could not find garbage collector with collector_type="
       << static_cast<size_t>(collector_type_) << " and gc_type=" << gc_type;
@@ -2960,9 +2967,6 @@
       self->IsHandlingStackOverflow()) {
     return;
   }
-  // We already have a request pending, no reason to start more until we update
-  // concurrent_start_bytes_.
-  concurrent_start_bytes_ = std::numeric_limits<size_t>::max();
   JNIEnv* env = self->GetJniEnv();
   DCHECK(WellKnownClasses::java_lang_Daemons != nullptr);
   DCHECK(WellKnownClasses::java_lang_Daemons_requestGC != nullptr);
diff --git a/runtime/mirror/art_field-inl.h b/runtime/mirror/art_field-inl.h
index 336d9ee..00bed92 100644
--- a/runtime/mirror/art_field-inl.h
+++ b/runtime/mirror/art_field-inl.h
@@ -25,8 +25,6 @@
 #include "jvalue.h"
 #include "object-inl.h"
 #include "primitive.h"
-#include "scoped_thread_state_change.h"
-#include "well_known_classes.h"
 
 namespace art {
 namespace mirror {
@@ -286,14 +284,6 @@
   return GetDexCache()->GetDexFile();
 }
 
-inline ArtField* ArtField::FromReflectedField(const ScopedObjectAccessAlreadyRunnable& soa,
-                                              jobject jlr_field) {
-  mirror::ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_reflect_Field_artField);
-  mirror::ArtField* field = f->GetObject(soa.Decode<mirror::Object*>(jlr_field))->AsArtField();
-  DCHECK(field != nullptr);
-  return field;
-}
-
 }  // namespace mirror
 }  // namespace art
 
diff --git a/runtime/mirror/art_field.cc b/runtime/mirror/art_field.cc
index 7e20076..3c7c6ce 100644
--- a/runtime/mirror/art_field.cc
+++ b/runtime/mirror/art_field.cc
@@ -31,6 +31,14 @@
 // TODO: Get global references for these
 GcRoot<Class> ArtField::java_lang_reflect_ArtField_;
 
+ArtField* ArtField::FromReflectedField(const ScopedObjectAccessAlreadyRunnable& soa,
+                                       jobject jlr_field) {
+  mirror::ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_reflect_Field_artField);
+  mirror::ArtField* field = f->GetObject(soa.Decode<mirror::Object*>(jlr_field))->AsArtField();
+  DCHECK(field != nullptr);
+  return field;
+}
+
 void ArtField::SetClass(Class* java_lang_reflect_ArtField) {
   CHECK(java_lang_reflect_ArtField_.IsNull());
   CHECK(java_lang_reflect_ArtField != NULL);
diff --git a/runtime/mirror/art_field.h b/runtime/mirror/art_field.h
index 82d0a64..f3dfa15 100644
--- a/runtime/mirror/art_field.h
+++ b/runtime/mirror/art_field.h
@@ -47,8 +47,8 @@
     return sizeof(ArtField);
   }
 
-  ALWAYS_INLINE static ArtField* FromReflectedField(const ScopedObjectAccessAlreadyRunnable& soa,
-                                                    jobject jlr_field)
+  static ArtField* FromReflectedField(const ScopedObjectAccessAlreadyRunnable& soa,
+                                      jobject jlr_field)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   Class* GetDeclaringClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/runtime/native/java_lang_reflect_Field.cc b/runtime/native/java_lang_reflect_Field.cc
index 8850df2..3903ffc 100644
--- a/runtime/native/java_lang_reflect_Field.cc
+++ b/runtime/native/java_lang_reflect_Field.cc
@@ -23,21 +23,19 @@
 #include "mirror/art_field-inl.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/class-inl.h"
-#include "reflection-inl.h"
+#include "reflection.h"
 #include "scoped_fast_native_object_access.h"
 
 namespace art {
 
-template<bool kIsSet>
-ALWAYS_INLINE inline static bool VerifyFieldAccess(Thread* self, mirror::ArtField* field,
-                                                   mirror::Object* obj)
+static bool VerifyFieldAccess(mirror::ArtField* field, mirror::Object* obj, bool is_set)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  if (kIsSet && field->IsFinal()) {
+  if (field->IsFinal() && is_set) {
     ThrowIllegalAccessException(nullptr, StringPrintf("Cannot set final field: %s",
                                                       PrettyField(field).c_str()).c_str());
     return false;
   }
-  if (!VerifyAccess(self, obj, field->GetDeclaringClass(), field->GetAccessFlags())) {
+  if (!VerifyAccess(obj, field->GetDeclaringClass(), field->GetAccessFlags())) {
     ThrowIllegalAccessException(nullptr, StringPrintf("Cannot access field: %s",
                                                       PrettyField(field).c_str()).c_str());
     return false;
@@ -45,10 +43,9 @@
   return true;
 }
 
-template<bool kAllowReferences>
-ALWAYS_INLINE inline static bool GetFieldValue(
-    const ScopedFastNativeObjectAccess& soa, mirror::Object* o, mirror::ArtField* f,
-    Primitive::Type field_type, JValue* value)
+static bool GetFieldValue(const ScopedFastNativeObjectAccess& soa, mirror::Object* o,
+                          mirror::ArtField* f, Primitive::Type field_type, bool allow_references,
+                          JValue* value)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   DCHECK_EQ(value->GetJ(), INT64_C(0));
   switch (field_type) {
@@ -77,7 +74,7 @@
       value->SetS(f->GetShort(o));
       return true;
     case Primitive::kPrimNot:
-      if (kAllowReferences) {
+      if (allow_references) {
         value->SetL(f->GetObject(o));
         return true;
       }
@@ -92,29 +89,28 @@
   return false;
 }
 
-ALWAYS_INLINE inline static bool CheckReceiver(const ScopedFastNativeObjectAccess& soa,
-                                               jobject j_rcvr, mirror::ArtField** f,
-                                               mirror::Object** class_or_rcvr)
+static bool CheckReceiver(const ScopedFastNativeObjectAccess& soa, jobject j_rcvr,
+                          mirror::ArtField** f, mirror::Object** class_or_rcvr)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   soa.Self()->AssertThreadSuspensionIsAllowable();
-  mirror::Class* declaringClass = (*f)->GetDeclaringClass();
   if ((*f)->IsStatic()) {
-    if (UNLIKELY(!declaringClass->IsInitialized())) {
-      ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-      StackHandleScope<2> hs(soa.Self());
-      HandleWrapper<mirror::ArtField> h_f(hs.NewHandleWrapper(f));
-      HandleWrapper<mirror::Class> h_klass(hs.NewHandleWrapper(&declaringClass));
-      if (UNLIKELY(!class_linker->EnsureInitialized(h_klass, true, true))) {
-        DCHECK(soa.Self()->IsExceptionPending());
-        return false;
-      }
+    StackHandleScope<2> hs(soa.Self());
+    HandleWrapper<mirror::ArtField> h_f(hs.NewHandleWrapper(f));
+    Handle<mirror::Class> h_klass(hs.NewHandle((*f)->GetDeclaringClass()));
+    if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(h_klass, true, true))) {
+      DCHECK(soa.Self()->IsExceptionPending());
+      *class_or_rcvr = nullptr;
+      return false;
     }
-    *class_or_rcvr = declaringClass;
+    *class_or_rcvr = h_klass.Get();
     return true;
   }
+
   *class_or_rcvr = soa.Decode<mirror::Object*>(j_rcvr);
+  mirror::Class* declaringClass = (*f)->GetDeclaringClass();
   if (!VerifyObjectIsClass(*class_or_rcvr, declaringClass)) {
     DCHECK(soa.Self()->IsExceptionPending());
+    *class_or_rcvr = nullptr;
     return false;
   }
   return true;
@@ -129,7 +125,7 @@
     return nullptr;
   }
   // If field is not set to be accessible, verify it can be accessed by the caller.
-  if ((accessible == JNI_FALSE) && !VerifyFieldAccess<false>(soa.Self(), f, o)) {
+  if ((accessible == JNI_FALSE) && !VerifyFieldAccess(f, o, false)) {
     DCHECK(soa.Self()->IsExceptionPending());
     return nullptr;
   }
@@ -137,16 +133,15 @@
   // Get the field's value, boxing if necessary.
   Primitive::Type field_type = f->GetTypeAsPrimitiveType();
   JValue value;
-  if (!GetFieldValue<true>(soa, o, f, field_type, &value)) {
+  if (!GetFieldValue(soa, o, f, field_type, true, &value)) {
     DCHECK(soa.Self()->IsExceptionPending());
     return nullptr;
   }
   return soa.AddLocalReference<jobject>(BoxPrimitive(field_type, value));
 }
 
-template<Primitive::Type kPrimitiveType>
-ALWAYS_INLINE inline static JValue GetPrimitiveField(JNIEnv* env, jobject javaField,
-                                                     jobject javaObj, jboolean accessible) {
+static JValue GetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj,
+                                char dst_descriptor, jboolean accessible) {
   ScopedFastNativeObjectAccess soa(env);
   mirror::ArtField* f = mirror::ArtField::FromReflectedField(soa, javaField);
   mirror::Object* o = nullptr;
@@ -156,7 +151,7 @@
   }
 
   // If field is not set to be accessible, verify it can be accessed by the caller.
-  if (accessible == JNI_FALSE && !VerifyFieldAccess<false>(soa.Self(), f, o)) {
+  if ((accessible == JNI_FALSE) && !VerifyFieldAccess(f, o, false)) {
     DCHECK(soa.Self()->IsExceptionPending());
     return JValue();
   }
@@ -165,22 +160,15 @@
   // Read the value.
   Primitive::Type field_type = f->GetTypeAsPrimitiveType();
   JValue field_value;
-  if (field_type == kPrimitiveType) {
-    // This if statement should get optimized out since we only pass in valid primitive types.
-    if (UNLIKELY(!GetFieldValue<false>(soa, o, f, kPrimitiveType, &field_value))) {
-      DCHECK(soa.Self()->IsExceptionPending());
-      return JValue();
-    }
-    return field_value;
-  }
-  if (!GetFieldValue<false>(soa, o, f, field_type, &field_value)) {
+  if (!GetFieldValue(soa, o, f, field_type, false, &field_value)) {
     DCHECK(soa.Self()->IsExceptionPending());
     return JValue();
   }
+
   // Widen it if necessary (and possible).
   JValue wide_value;
-  if (!ConvertPrimitiveValue(nullptr, false, field_type, kPrimitiveType, field_value,
-                             &wide_value)) {
+  if (!ConvertPrimitiveValue(NULL, false, field_type, Primitive::GetType(dst_descriptor),
+                             field_value, &wide_value)) {
     DCHECK(soa.Self()->IsExceptionPending());
     return JValue();
   }
@@ -189,36 +177,36 @@
 
 static jboolean Field_getBoolean(JNIEnv* env, jobject javaField, jobject javaObj,
                                  jboolean accessible) {
-  return GetPrimitiveField<Primitive::kPrimBoolean>(env, javaField, javaObj, accessible).GetZ();
+  return GetPrimitiveField(env, javaField, javaObj, 'Z', accessible).GetZ();
 }
 
 static jbyte Field_getByte(JNIEnv* env, jobject javaField, jobject javaObj, jboolean accessible) {
-  return GetPrimitiveField<Primitive::kPrimByte>(env, javaField, javaObj, accessible).GetB();
+  return GetPrimitiveField(env, javaField, javaObj, 'B', accessible).GetB();
 }
 
 static jchar Field_getChar(JNIEnv* env, jobject javaField, jobject javaObj, jboolean accessible) {
-  return GetPrimitiveField<Primitive::kPrimChar>(env, javaField, javaObj, accessible).GetC();
+  return GetPrimitiveField(env, javaField, javaObj, 'C', accessible).GetC();
 }
 
 static jdouble Field_getDouble(JNIEnv* env, jobject javaField, jobject javaObj,
                                jboolean accessible) {
-  return GetPrimitiveField<Primitive::kPrimDouble>(env, javaField, javaObj, accessible).GetD();
+  return GetPrimitiveField(env, javaField, javaObj, 'D', accessible).GetD();
 }
 
 static jfloat Field_getFloat(JNIEnv* env, jobject javaField, jobject javaObj, jboolean accessible) {
-  return GetPrimitiveField<Primitive::kPrimFloat>(env, javaField, javaObj, accessible).GetF();
+  return GetPrimitiveField(env, javaField, javaObj, 'F', accessible).GetF();
 }
 
 static jint Field_getInt(JNIEnv* env, jobject javaField, jobject javaObj, jboolean accessible) {
-  return GetPrimitiveField<Primitive::kPrimInt>(env, javaField, javaObj, accessible).GetI();
+  return GetPrimitiveField(env, javaField, javaObj, 'I', accessible).GetI();
 }
 
 static jlong Field_getLong(JNIEnv* env, jobject javaField, jobject javaObj, jboolean accessible) {
-  return GetPrimitiveField<Primitive::kPrimLong>(env, javaField, javaObj, accessible).GetJ();
+  return GetPrimitiveField(env, javaField, javaObj, 'J', accessible).GetJ();
 }
 
 static jshort Field_getShort(JNIEnv* env, jobject javaField, jobject javaObj, jboolean accessible) {
-  return GetPrimitiveField<Primitive::kPrimShort>(env, javaField, javaObj, accessible).GetS();
+  return GetPrimitiveField(env, javaField, javaObj, 'S', accessible).GetS();
 }
 
 static void SetFieldValue(ScopedFastNativeObjectAccess& soa, mirror::Object* o,
@@ -301,15 +289,14 @@
     return;
   }
   // If field is not set to be accessible, verify it can be accessed by the caller.
-  if ((accessible == JNI_FALSE) && !VerifyFieldAccess<true>(soa.Self(), f, o)) {
+  if ((accessible == JNI_FALSE) && !VerifyFieldAccess(f, o, true)) {
     DCHECK(soa.Self()->IsExceptionPending());
     return;
   }
   SetFieldValue(soa, o, f, field_prim_type, true, unboxed_value);
 }
 
-template<Primitive::Type kPrimitiveType>
-static void SetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj,
+static void SetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char src_descriptor,
                               const JValue& new_value, jboolean accessible) {
   ScopedFastNativeObjectAccess soa(env);
   mirror::ArtField* f = mirror::ArtField::FromReflectedField(soa, javaField);
@@ -326,13 +313,14 @@
 
   // Widen the value if necessary (and possible).
   JValue wide_value;
-  if (!ConvertPrimitiveValue(nullptr, false, kPrimitiveType, field_type, new_value, &wide_value)) {
+  if (!ConvertPrimitiveValue(nullptr, false, Primitive::GetType(src_descriptor),
+                             field_type, new_value, &wide_value)) {
     DCHECK(soa.Self()->IsExceptionPending());
     return;
   }
 
   // If field is not set to be accessible, verify it can be accessed by the caller.
-  if ((accessible == JNI_FALSE) && !VerifyFieldAccess<true>(soa.Self(), f, o)) {
+  if ((accessible == JNI_FALSE) && !VerifyFieldAccess(f, o, true)) {
     DCHECK(soa.Self()->IsExceptionPending());
     return;
   }
@@ -345,56 +333,56 @@
                              jboolean accessible) {
   JValue value;
   value.SetZ(z);
-  SetPrimitiveField<Primitive::kPrimBoolean>(env, javaField, javaObj, value, accessible);
+  SetPrimitiveField(env, javaField, javaObj, 'Z', value, accessible);
 }
 
 static void Field_setByte(JNIEnv* env, jobject javaField, jobject javaObj, jbyte b,
                           jboolean accessible) {
   JValue value;
   value.SetB(b);
-  SetPrimitiveField<Primitive::kPrimByte>(env, javaField, javaObj, value, accessible);
+  SetPrimitiveField(env, javaField, javaObj, 'B', value, accessible);
 }
 
 static void Field_setChar(JNIEnv* env, jobject javaField, jobject javaObj, jchar c,
                           jboolean accessible) {
   JValue value;
   value.SetC(c);
-  SetPrimitiveField<Primitive::kPrimChar>(env, javaField, javaObj, value, accessible);
+  SetPrimitiveField(env, javaField, javaObj, 'C', value, accessible);
 }
 
 static void Field_setDouble(JNIEnv* env, jobject javaField, jobject javaObj, jdouble d,
                             jboolean accessible) {
   JValue value;
   value.SetD(d);
-  SetPrimitiveField<Primitive::kPrimDouble>(env, javaField, javaObj, value, accessible);
+  SetPrimitiveField(env, javaField, javaObj, 'D', value, accessible);
 }
 
 static void Field_setFloat(JNIEnv* env, jobject javaField, jobject javaObj, jfloat f,
                            jboolean accessible) {
   JValue value;
   value.SetF(f);
-  SetPrimitiveField<Primitive::kPrimFloat>(env, javaField, javaObj, value, accessible);
+  SetPrimitiveField(env, javaField, javaObj, 'F', value, accessible);
 }
 
 static void Field_setInt(JNIEnv* env, jobject javaField, jobject javaObj, jint i,
                          jboolean accessible) {
   JValue value;
   value.SetI(i);
-  SetPrimitiveField<Primitive::kPrimInt>(env, javaField, javaObj, value, accessible);
+  SetPrimitiveField(env, javaField, javaObj, 'I', value, accessible);
 }
 
 static void Field_setLong(JNIEnv* env, jobject javaField, jobject javaObj, jlong j,
                           jboolean accessible) {
   JValue value;
   value.SetJ(j);
-  SetPrimitiveField<Primitive::kPrimLong>(env, javaField, javaObj, value, accessible);
+  SetPrimitiveField(env, javaField, javaObj, 'J', value, accessible);
 }
 
 static void Field_setShort(JNIEnv* env, jobject javaField, jobject javaObj, jshort s,
                            jboolean accessible) {
   JValue value;
   value.SetS(s);
-  SetPrimitiveField<Primitive::kPrimShort>(env, javaField, javaObj, value, accessible);
+  SetPrimitiveField(env, javaField, javaObj, 'S', value, accessible);
 }
 
 static JNINativeMethod gMethods[] = {
diff --git a/runtime/reflection-inl.h b/runtime/reflection-inl.h
deleted file mode 100644
index be4d560..0000000
--- a/runtime/reflection-inl.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_RUNTIME_REFLECTION_INL_H_
-#define ART_RUNTIME_REFLECTION_INL_H_
-
-#include "reflection.h"
-
-#include "base/stringprintf.h"
-#include "common_throws.h"
-#include "jvalue.h"
-#include "primitive.h"
-#include "utils.h"
-
-namespace art {
-
-inline bool ConvertPrimitiveValue(const ThrowLocation* throw_location, bool unbox_for_result,
-                                  Primitive::Type srcType, Primitive::Type dstType,
-                                  const JValue& src, JValue* dst) {
-  DCHECK(srcType != Primitive::kPrimNot && dstType != Primitive::kPrimNot);
-  if (LIKELY(srcType == dstType)) {
-    dst->SetJ(src.GetJ());
-    return true;
-  }
-  switch (dstType) {
-  case Primitive::kPrimBoolean:  // Fall-through.
-  case Primitive::kPrimChar:  // Fall-through.
-  case Primitive::kPrimByte:
-    // Only expect assignment with source and destination of identical type.
-    break;
-  case Primitive::kPrimShort:
-    if (srcType == Primitive::kPrimByte) {
-      dst->SetS(src.GetI());
-      return true;
-    }
-    break;
-  case Primitive::kPrimInt:
-    if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
-        srcType == Primitive::kPrimShort) {
-      dst->SetI(src.GetI());
-      return true;
-    }
-    break;
-  case Primitive::kPrimLong:
-    if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
-        srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
-      dst->SetJ(src.GetI());
-      return true;
-    }
-    break;
-  case Primitive::kPrimFloat:
-    if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
-        srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
-      dst->SetF(src.GetI());
-      return true;
-    } else if (srcType == Primitive::kPrimLong) {
-      dst->SetF(src.GetJ());
-      return true;
-    }
-    break;
-  case Primitive::kPrimDouble:
-    if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
-        srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
-      dst->SetD(src.GetI());
-      return true;
-    } else if (srcType == Primitive::kPrimLong) {
-      dst->SetD(src.GetJ());
-      return true;
-    } else if (srcType == Primitive::kPrimFloat) {
-      dst->SetD(src.GetF());
-      return true;
-    }
-    break;
-  default:
-    break;
-  }
-  if (!unbox_for_result) {
-    ThrowIllegalArgumentException(throw_location,
-                                  StringPrintf("Invalid primitive conversion from %s to %s",
-                                               PrettyDescriptor(srcType).c_str(),
-                                               PrettyDescriptor(dstType).c_str()).c_str());
-  } else {
-    ThrowClassCastException(throw_location,
-                            StringPrintf("Couldn't convert result of type %s to %s",
-                                         PrettyDescriptor(srcType).c_str(),
-                                         PrettyDescriptor(dstType).c_str()).c_str());
-  }
-  return false;
-}
-
-}  // namespace art
-
-#endif  // ART_RUNTIME_REFLECTION_INL_H_
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index 18fcee4..4cd61a5 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "reflection-inl.h"
+#include "reflection.h"
 
 #include "class_linker.h"
 #include "common_throws.h"
@@ -565,7 +565,7 @@
   }
 
   // If method is not set to be accessible, verify it can be accessed by the caller.
-  if (!accessible && !VerifyAccess(soa.Self(), receiver, declaring_class, m->GetAccessFlags())) {
+  if (!accessible && !VerifyAccess(receiver, declaring_class, m->GetAccessFlags())) {
     ThrowIllegalAccessException(nullptr, StringPrintf("Cannot access method: %s",
                                                       PrettyMethod(m).c_str()).c_str());
     return nullptr;
@@ -617,6 +617,84 @@
   return true;
 }
 
+static std::string PrettyDescriptor(Primitive::Type type) {
+  return PrettyDescriptor(Primitive::Descriptor(type));
+}
+
+bool ConvertPrimitiveValue(const ThrowLocation* throw_location, bool unbox_for_result,
+                           Primitive::Type srcType, Primitive::Type dstType,
+                           const JValue& src, JValue* dst) {
+  DCHECK(srcType != Primitive::kPrimNot && dstType != Primitive::kPrimNot);
+  if (LIKELY(srcType == dstType)) {
+    dst->SetJ(src.GetJ());
+    return true;
+  }
+  switch (dstType) {
+  case Primitive::kPrimBoolean:  // Fall-through.
+  case Primitive::kPrimChar:  // Fall-through.
+  case Primitive::kPrimByte:
+    // Only expect assignment with source and destination of identical type.
+    break;
+  case Primitive::kPrimShort:
+    if (srcType == Primitive::kPrimByte) {
+      dst->SetS(src.GetI());
+      return true;
+    }
+    break;
+  case Primitive::kPrimInt:
+    if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
+        srcType == Primitive::kPrimShort) {
+      dst->SetI(src.GetI());
+      return true;
+    }
+    break;
+  case Primitive::kPrimLong:
+    if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
+        srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
+      dst->SetJ(src.GetI());
+      return true;
+    }
+    break;
+  case Primitive::kPrimFloat:
+    if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
+        srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
+      dst->SetF(src.GetI());
+      return true;
+    } else if (srcType == Primitive::kPrimLong) {
+      dst->SetF(src.GetJ());
+      return true;
+    }
+    break;
+  case Primitive::kPrimDouble:
+    if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
+        srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
+      dst->SetD(src.GetI());
+      return true;
+    } else if (srcType == Primitive::kPrimLong) {
+      dst->SetD(src.GetJ());
+      return true;
+    } else if (srcType == Primitive::kPrimFloat) {
+      dst->SetD(src.GetF());
+      return true;
+    }
+    break;
+  default:
+    break;
+  }
+  if (!unbox_for_result) {
+    ThrowIllegalArgumentException(throw_location,
+                                  StringPrintf("Invalid primitive conversion from %s to %s",
+                                               PrettyDescriptor(srcType).c_str(),
+                                               PrettyDescriptor(dstType).c_str()).c_str());
+  } else {
+    ThrowClassCastException(throw_location,
+                            StringPrintf("Couldn't convert result of type %s to %s",
+                                         PrettyDescriptor(srcType).c_str(),
+                                         PrettyDescriptor(dstType).c_str()).c_str());
+  }
+  return false;
+}
+
 mirror::Object* BoxPrimitive(Primitive::Type src_class, const JValue& value) {
   if (src_class == Primitive::kPrimNot) {
     return value.GetL();
@@ -788,18 +866,16 @@
   return UnboxPrimitive(&throw_location, o, dst_class, nullptr, unboxed_value);
 }
 
-bool VerifyAccess(Thread* self, mirror::Object* obj, mirror::Class* declaring_class, uint32_t access_flags) {
-  if ((access_flags & kAccPublic) != 0) {
-    return true;
-  }
-  NthCallerVisitor visitor(self, 2);
+bool VerifyAccess(mirror::Object* obj, mirror::Class* declaring_class, uint32_t access_flags) {
+  NthCallerVisitor visitor(Thread::Current(), 2);
   visitor.WalkStack();
   if (UNLIKELY(visitor.caller == nullptr)) {
     // The caller is an attached native thread.
-    return false;
+    return (access_flags & kAccPublic) != 0;
   }
   mirror::Class* caller_class = visitor.caller->GetDeclaringClass();
-  if (caller_class == declaring_class) {
+
+  if (((access_flags & kAccPublic) != 0) || (caller_class == declaring_class)) {
     return true;
   }
   if ((access_flags & kAccPrivate) != 0) {
@@ -813,7 +889,10 @@
       return true;
     }
   }
-  return declaring_class->IsInSamePackage(caller_class);
+  if (!declaring_class->IsInSamePackage(caller_class)) {
+    return false;
+  }
+  return true;
 }
 
 }  // namespace art
diff --git a/runtime/reflection.h b/runtime/reflection.h
index 0f41aca..2c54c06 100644
--- a/runtime/reflection.h
+++ b/runtime/reflection.h
@@ -42,9 +42,9 @@
                              mirror::Class* dst_class, JValue* unboxed_value)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-ALWAYS_INLINE bool ConvertPrimitiveValue(const ThrowLocation* throw_location, bool unbox_for_result,
-                                         Primitive::Type src_class, Primitive::Type dst_class,
-                                         const JValue& src, JValue* dst)
+bool ConvertPrimitiveValue(const ThrowLocation* throw_location, bool unbox_for_result,
+                           Primitive::Type src_class, Primitive::Type dst_class,
+                           const JValue& src, JValue* dst)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
 JValue InvokeWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa, jobject obj, jmethodID mid,
@@ -74,8 +74,7 @@
 bool VerifyObjectIsClass(mirror::Object* o, mirror::Class* c)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-bool VerifyAccess(Thread* self, mirror::Object* obj, mirror::Class* declaring_class,
-                  uint32_t access_flags)
+bool VerifyAccess(mirror::Object* obj, mirror::Class* declaring_class, uint32_t access_flags)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
 }  // namespace art
diff --git a/runtime/utils.cc b/runtime/utils.cc
index 3765759..d01c2cb 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -1376,8 +1376,4 @@
   return true;
 }
 
-std::string PrettyDescriptor(Primitive::Type type) {
-  return PrettyDescriptor(Primitive::Descriptor(type));
-}
-
 }  // namespace art
diff --git a/runtime/utils.h b/runtime/utils.h
index 5bdbba8..1dfa02a 100644
--- a/runtime/utils.h
+++ b/runtime/utils.h
@@ -25,10 +25,9 @@
 #include <vector>
 
 #include "base/logging.h"
-#include "base/mutex.h"
 #include "globals.h"
 #include "instruction_set.h"
-#include "primitive.h"
+#include "base/mutex.h"
 
 #ifdef HAVE_ANDROID_OS
 #include "cutils/properties.h"
@@ -281,7 +280,6 @@
 std::string PrettyDescriptor(const char* descriptor);
 std::string PrettyDescriptor(mirror::Class* klass)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-std::string PrettyDescriptor(Primitive::Type type);
 
 // Returns a human-readable signature for 'f'. Something like "a.b.C.f" or
 // "int a.b.C.f" (depending on the value of 'with_type').
diff --git a/runtime/utils_test.cc b/runtime/utils_test.cc
index 1b2c3ee..d6c90e1 100644
--- a/runtime/utils_test.cc
+++ b/runtime/utils_test.cc
@@ -44,18 +44,6 @@
   EXPECT_EQ("java.lang.String", PrettyDescriptor("Ljava/lang/String;"));
 }
 
-TEST_F(UtilsTest, PrettyDescriptor_Primitive) {
-  EXPECT_EQ("boolean", PrettyDescriptor(Primitive::kPrimBoolean));
-  EXPECT_EQ("byte", PrettyDescriptor(Primitive::kPrimByte));
-  EXPECT_EQ("char", PrettyDescriptor(Primitive::kPrimChar));
-  EXPECT_EQ("short", PrettyDescriptor(Primitive::kPrimShort));
-  EXPECT_EQ("int", PrettyDescriptor(Primitive::kPrimInt));
-  EXPECT_EQ("float", PrettyDescriptor(Primitive::kPrimFloat));
-  EXPECT_EQ("long", PrettyDescriptor(Primitive::kPrimLong));
-  EXPECT_EQ("double", PrettyDescriptor(Primitive::kPrimDouble));
-  EXPECT_EQ("void", PrettyDescriptor(Primitive::kPrimVoid));
-}
-
 TEST_F(UtilsTest, PrettyDescriptor_PrimitiveArrays) {
   EXPECT_EQ("boolean[]", PrettyDescriptor("[Z"));
   EXPECT_EQ("boolean[][]", PrettyDescriptor("[[Z"));