Improvements to Field.get/set.
Avoid unnecessary repeated computation in Field.get/set.
Refactor FromReflectedField and FromReflectedMethod into common helpers in
mirror::ArtField and mirror::ArtMethod, and make use of thereby avoiding
transitions through JNI.
Avoid JNI use from within FromReflectedField and FromReflectedMethod.
Tidy up Field.get/set wrt moving collector support.
Bug: 12189533
Change-Id: I643ab3474bade4abac3a3ae2b6e373b2bb0891c8
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index cef9954..08ea123 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2314,26 +2314,26 @@
}
mirror::Class* ClassLinker::FindPrimitiveClass(char type) {
- switch (Primitive::GetType(type)) {
- case Primitive::kPrimByte:
+ switch (type) {
+ case 'B':
return GetClassRoot(kPrimitiveByte);
- case Primitive::kPrimChar:
+ case 'C':
return GetClassRoot(kPrimitiveChar);
- case Primitive::kPrimDouble:
+ case 'D':
return GetClassRoot(kPrimitiveDouble);
- case Primitive::kPrimFloat:
+ case 'F':
return GetClassRoot(kPrimitiveFloat);
- case Primitive::kPrimInt:
+ case 'I':
return GetClassRoot(kPrimitiveInt);
- case Primitive::kPrimLong:
+ case 'J':
return GetClassRoot(kPrimitiveLong);
- case Primitive::kPrimShort:
+ case 'S':
return GetClassRoot(kPrimitiveShort);
- case Primitive::kPrimBoolean:
+ case 'Z':
return GetClassRoot(kPrimitiveBoolean);
- case Primitive::kPrimVoid:
+ case 'V':
return GetClassRoot(kPrimitiveVoid);
- case Primitive::kPrimNot:
+ default:
break;
}
std::string printable_type(PrintableChar(type));
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index 43db7ec..13aa77f 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -550,24 +550,16 @@
return soa.AddLocalReference<jclass>(c);
}
- static jmethodID FromReflectedMethod(JNIEnv* env, jobject java_method) {
- CHECK_NON_NULL_ARGUMENT(FromReflectedMethod, java_method);
+ static jmethodID FromReflectedMethod(JNIEnv* env, jobject jlr_method) {
+ CHECK_NON_NULL_ARGUMENT(FromReflectedMethod, jlr_method);
ScopedObjectAccess soa(env);
- jobject art_method = env->GetObjectField(
- java_method, WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod);
- mirror::ArtMethod* method = soa.Decode<mirror::ArtMethod*>(art_method);
- DCHECK(method != nullptr);
- return soa.EncodeMethod(method);
+ return soa.EncodeMethod(mirror::ArtMethod::FromReflectedMethod(soa, jlr_method));
}
- static jfieldID FromReflectedField(JNIEnv* env, jobject java_field) {
- CHECK_NON_NULL_ARGUMENT(FromReflectedField, java_field);
+ static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) {
+ CHECK_NON_NULL_ARGUMENT(FromReflectedField, jlr_field);
ScopedObjectAccess soa(env);
- jobject art_field = env->GetObjectField(java_field,
- WellKnownClasses::java_lang_reflect_Field_artField);
- mirror::ArtField* field = soa.Decode<mirror::ArtField*>(art_field);
- DCHECK(field != nullptr);
- return soa.EncodeField(field);
+ return soa.EncodeField(mirror::ArtField::FromReflectedField(soa, jlr_field));
}
static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
diff --git a/runtime/mirror/art_field.cc b/runtime/mirror/art_field.cc
index 7740213..f91cab1 100644
--- a/runtime/mirror/art_field.cc
+++ b/runtime/mirror/art_field.cc
@@ -21,7 +21,9 @@
#include "object-inl.h"
#include "object_utils.h"
#include "runtime.h"
+#include "scoped_thread_state_change.h"
#include "utils.h"
+#include "well_known_classes.h"
namespace art {
namespace mirror {
@@ -29,6 +31,13 @@
// TODO: get global references for these
Class* ArtField::java_lang_reflect_ArtField_ = NULL;
+ArtField* ArtField::FromReflectedField(const ScopedObjectAccess& 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_ == NULL);
CHECK(java_lang_reflect_ArtField != NULL);
diff --git a/runtime/mirror/art_field.h b/runtime/mirror/art_field.h
index 46287c3..0daa838 100644
--- a/runtime/mirror/art_field.h
+++ b/runtime/mirror/art_field.h
@@ -25,12 +25,16 @@
namespace art {
struct ArtFieldOffsets;
+class ScopedObjectAccess;
namespace mirror {
// C++ mirror of java.lang.reflect.ArtField
class MANAGED ArtField : public Object {
public:
+ static ArtField* FromReflectedField(const ScopedObjectAccess& soa, jobject jlr_field)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
Class* GetDeclaringClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void SetDeclaringClass(Class *new_declaring_class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc
index 7814f36..ee5a0a4 100644
--- a/runtime/mirror/art_method.cc
+++ b/runtime/mirror/art_method.cc
@@ -16,6 +16,7 @@
#include "art_method.h"
+#include "art_field-inl.h"
#include "art_method-inl.h"
#include "base/stringpiece.h"
#include "class-inl.h"
@@ -28,8 +29,10 @@
#include "object-inl.h"
#include "object_array.h"
#include "object_array-inl.h"
+#include "scoped_thread_state_change.h"
#include "string.h"
#include "object_utils.h"
+#include "well_known_classes.h"
namespace art {
namespace mirror {
@@ -45,6 +48,15 @@
// TODO: get global references for these
Class* ArtMethod::java_lang_reflect_ArtMethod_ = NULL;
+ArtMethod* ArtMethod::FromReflectedMethod(const ScopedObjectAccess& soa, jobject jlr_method) {
+ mirror::ArtField* f =
+ soa.DecodeField(WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod);
+ mirror::ArtMethod* method = f->GetObject(soa.Decode<mirror::Object*>(jlr_method))->AsArtMethod();
+ DCHECK(method != nullptr);
+ return method;
+}
+
+
void ArtMethod::VisitRoots(RootCallback* callback, void* arg) {
if (java_lang_reflect_ArtMethod_ != nullptr) {
callback(reinterpret_cast<mirror::Object**>(&java_lang_reflect_ArtMethod_), arg, 0,
diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h
index c654933..fd5ac19 100644
--- a/runtime/mirror/art_method.h
+++ b/runtime/mirror/art_method.h
@@ -31,6 +31,7 @@
union JValue;
struct MethodClassOffsets;
class MethodHelper;
+class ScopedObjectAccess;
class StringPiece;
class ShadowFrame;
@@ -44,6 +45,9 @@
// C++ mirror of java.lang.reflect.Method and java.lang.reflect.Constructor
class MANAGED ArtMethod : public Object {
public:
+ static ArtMethod* FromReflectedMethod(const ScopedObjectAccess& soa, jobject jlr_method)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
Class* GetDeclaringClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void SetDeclaringClass(Class *new_declaring_class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/runtime/native/java_lang_reflect_Constructor.cc b/runtime/native/java_lang_reflect_Constructor.cc
index a22d7ca..b7e8ac2 100644
--- a/runtime/native/java_lang_reflect_Constructor.cc
+++ b/runtime/native/java_lang_reflect_Constructor.cc
@@ -36,10 +36,7 @@
*/
static jobject Constructor_newInstance(JNIEnv* env, jobject javaMethod, jobjectArray javaArgs) {
ScopedFastNativeObjectAccess soa(env);
- jobject art_method = soa.Env()->GetObjectField(
- javaMethod, WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod);
-
- mirror::ArtMethod* m = soa.Decode<mirror::Object*>(art_method)->AsArtMethod();
+ mirror::ArtMethod* m = mirror::ArtMethod::FromReflectedMethod(soa, javaMethod);
SirtRef<mirror::Class> c(soa.Self(), m->GetDeclaringClass());
if (UNLIKELY(c->IsAbstract())) {
ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
diff --git a/runtime/native/java_lang_reflect_Field.cc b/runtime/native/java_lang_reflect_Field.cc
index 7e21d6c..6667d51 100644
--- a/runtime/native/java_lang_reflect_Field.cc
+++ b/runtime/native/java_lang_reflect_Field.cc
@@ -28,69 +28,72 @@
namespace art {
static bool GetFieldValue(const ScopedFastNativeObjectAccess& soa, mirror::Object* o,
- mirror::ArtField* f, JValue& value, bool allow_references)
+ 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));
- CHECK(!kMovingFields);
- SirtRef<mirror::Object> sirt_obj(soa.Self(), o);
- SirtRef<mirror::Class> sirt_klass(soa.Self(), f->GetDeclaringClass());
- if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(sirt_klass, true, true)) {
- return false;
- }
- o = sirt_obj.get();
- switch (FieldHelper(f).GetTypeAsPrimitiveType()) {
- case Primitive::kPrimBoolean:
- value.SetZ(f->GetBoolean(o));
- return true;
- case Primitive::kPrimByte:
- value.SetB(f->GetByte(o));
- return true;
- case Primitive::kPrimChar:
- value.SetC(f->GetChar(o));
- return true;
- case Primitive::kPrimDouble:
- value.SetD(f->GetDouble(o));
- return true;
- case Primitive::kPrimFloat:
- value.SetF(f->GetFloat(o));
- return true;
- case Primitive::kPrimInt:
- value.SetI(f->GetInt(o));
- return true;
- case Primitive::kPrimLong:
- value.SetJ(f->GetLong(o));
- return true;
- case Primitive::kPrimShort:
- value.SetS(f->GetShort(o));
- return true;
- case Primitive::kPrimNot:
- if (allow_references) {
- value.SetL(f->GetObject(o));
+ DCHECK_EQ(value->GetJ(), INT64_C(0));
+ DCHECK(f->GetDeclaringClass()->IsInitialized());
+ switch (field_type) {
+ case Primitive::kPrimBoolean:
+ value->SetZ(f->GetBoolean(o));
return true;
- }
- // Else break to report an error.
- break;
- case Primitive::kPrimVoid:
- // Never okay.
- break;
+ case Primitive::kPrimByte:
+ value->SetB(f->GetByte(o));
+ return true;
+ case Primitive::kPrimChar:
+ value->SetC(f->GetChar(o));
+ return true;
+ case Primitive::kPrimDouble:
+ value->SetD(f->GetDouble(o));
+ return true;
+ case Primitive::kPrimFloat:
+ value->SetF(f->GetFloat(o));
+ return true;
+ case Primitive::kPrimInt:
+ value->SetI(f->GetInt(o));
+ return true;
+ case Primitive::kPrimLong:
+ value->SetJ(f->GetLong(o));
+ return true;
+ case Primitive::kPrimShort:
+ value->SetS(f->GetShort(o));
+ return true;
+ case Primitive::kPrimNot:
+ if (allow_references) {
+ value->SetL(f->GetObject(o));
+ return true;
+ }
+ // Else break to report an error.
+ break;
+ case Primitive::kPrimVoid:
+ // Never okay.
+ break;
}
- ThrowIllegalArgumentException(NULL,
- StringPrintf("Not a primitive field: %s",
- PrettyField(f).c_str()).c_str());
+ ThrowIllegalArgumentException(nullptr, StringPrintf("Not a primitive field: %s",
+ PrettyField(f).c_str()).c_str());
return false;
}
static bool CheckReceiver(const ScopedFastNativeObjectAccess& soa, jobject j_rcvr,
- mirror::ArtField* f, mirror::Object*& class_or_rcvr)
+ mirror::ArtField* f, mirror::Object** class_or_rcvr)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ soa.Self()->AssertThreadSuspensionIsAllowable();
if (f->IsStatic()) {
- class_or_rcvr = f->GetDeclaringClass();
+ SirtRef<mirror::Class> sirt_klass(soa.Self(), f->GetDeclaringClass());
+ if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(sirt_klass, true, true))) {
+ DCHECK(soa.Self()->IsExceptionPending());
+ *class_or_rcvr = nullptr;
+ return false;
+ }
+ *class_or_rcvr = sirt_klass.get();
return true;
}
- class_or_rcvr = soa.Decode<mirror::Object*>(j_rcvr);
+ *class_or_rcvr = soa.Decode<mirror::Object*>(j_rcvr);
mirror::Class* declaringClass = f->GetDeclaringClass();
- if (!VerifyObjectIsClass(class_or_rcvr, declaringClass)) {
+ if (!VerifyObjectIsClass(*class_or_rcvr, declaringClass)) {
+ DCHECK(soa.Self()->IsExceptionPending());
+ *class_or_rcvr = nullptr;
return false;
}
return true;
@@ -98,42 +101,48 @@
static jobject Field_get(JNIEnv* env, jobject javaField, jobject javaObj) {
ScopedFastNativeObjectAccess soa(env);
- mirror::ArtField* f = soa.DecodeField(env->FromReflectedField(javaField));
- mirror::Object* o = NULL;
- if (!CheckReceiver(soa, javaObj, f, o)) {
- return NULL;
+ CHECK(!kMovingFields) << "CheckReceiver may trigger thread suspension for initialization";
+ mirror::ArtField* f = mirror::ArtField::FromReflectedField(soa, javaField);
+ mirror::Object* o = nullptr;
+ if (!CheckReceiver(soa, javaObj, f, &o)) {
+ DCHECK(soa.Self()->IsExceptionPending());
+ return nullptr;
}
-
+ // We now don't expect suspension unless an exception is thrown.
// Get the field's value, boxing if necessary.
+ Primitive::Type field_type = FieldHelper(f).GetTypeAsPrimitiveType();
JValue value;
- if (!GetFieldValue(soa, o, f, value, true)) {
- return NULL;
+ if (!GetFieldValue(soa, o, f, field_type, true, &value)) {
+ DCHECK(soa.Self()->IsExceptionPending());
+ return nullptr;
}
- return
- soa.AddLocalReference<jobject>(BoxPrimitive(FieldHelper(f).GetTypeAsPrimitiveType(), value));
+ return soa.AddLocalReference<jobject>(BoxPrimitive(field_type, value));
}
static JValue GetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj,
char dst_descriptor) {
ScopedFastNativeObjectAccess soa(env);
- mirror::ArtField* f = soa.DecodeField(env->FromReflectedField(javaField));
- mirror::Object* o = NULL;
- if (!CheckReceiver(soa, javaObj, f, o)) {
+ CHECK(!kMovingFields) << "CheckReceiver may trigger thread suspension for initialization";
+ mirror::ArtField* f = mirror::ArtField::FromReflectedField(soa, javaField);
+ mirror::Object* o = nullptr;
+ if (!CheckReceiver(soa, javaObj, f, &o)) {
+ DCHECK(soa.Self()->IsExceptionPending());
return JValue();
}
-
+ // We now don't expect suspension unless an exception is thrown.
// Read the value.
+ Primitive::Type field_type = FieldHelper(f).GetTypeAsPrimitiveType();
JValue field_value;
- if (!GetFieldValue(soa, o, f, field_value, false)) {
+ 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;
- mirror::Class* dst_type =
- Runtime::Current()->GetClassLinker()->FindPrimitiveClass(dst_descriptor);
- if (!ConvertPrimitiveValue(NULL, false, FieldHelper(f).GetTypeAsPrimitiveType(),
- dst_type->GetPrimitiveType(), field_value, wide_value)) {
+ if (!ConvertPrimitiveValue(NULL, false, field_type, Primitive::GetType(dst_descriptor),
+ field_value, wide_value)) {
+ DCHECK(soa.Self()->IsExceptionPending());
return JValue();
}
return wide_value;
@@ -172,16 +181,11 @@
}
static void SetFieldValue(ScopedFastNativeObjectAccess& soa, mirror::Object* o,
- mirror::ArtField* f, const JValue& new_value, bool allow_references)
+ mirror::ArtField* f, Primitive::Type field_type, bool allow_references,
+ const JValue& new_value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- CHECK(!kMovingFields);
- SirtRef<mirror::Object> sirt_obj(soa.Self(), o);
- SirtRef<mirror::Class> sirt_klass(soa.Self(), f->GetDeclaringClass());
- if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(sirt_klass, true, true)) {
- return;
- }
- o = sirt_obj.get();
- switch (FieldHelper(f).GetTypeAsPrimitiveType()) {
+ DCHECK(f->GetDeclaringClass()->IsInitialized());
+ switch (field_type) {
case Primitive::kPrimBoolean:
f->SetBoolean<false>(o, new_value.GetZ());
break;
@@ -214,63 +218,77 @@
// Else fall through to report an error.
case Primitive::kPrimVoid:
// Never okay.
- ThrowIllegalArgumentException(NULL, StringPrintf("Not a primitive field: %s",
- PrettyField(f).c_str()).c_str());
+ ThrowIllegalArgumentException(nullptr, StringPrintf("Not a primitive field: %s",
+ PrettyField(f).c_str()).c_str());
return;
}
-
- // Special handling for final fields on SMP systems.
- // We need a store/store barrier here (JMM requirement).
- if (f->IsFinal()) {
- QuasiAtomic::MembarStoreLoad();
- }
}
static void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject javaValue) {
ScopedFastNativeObjectAccess soa(env);
- mirror::ArtField* f = soa.DecodeField(env->FromReflectedField(javaField));
-
+ CHECK(!kMovingFields) << "CheckReceiver may trigger thread suspension for initialization";
+ mirror::ArtField* f = mirror::ArtField::FromReflectedField(soa, javaField);
+ // Check that the receiver is non-null and an instance of the field's declaring class.
+ mirror::Object* o = nullptr;
+ if (!CheckReceiver(soa, javaObj, f, &o)) {
+ DCHECK(soa.Self()->IsExceptionPending());
+ return;
+ }
+ Primitive::Type field_prim_type;
+ mirror::Class* field_type;
+ {
+ FieldHelper fh(f);
+ const char* field_type_desciptor = fh.GetTypeDescriptor();
+ field_prim_type = Primitive::GetType(field_type_desciptor[0]);
+ if (field_prim_type == Primitive::kPrimNot) {
+ SirtRef<mirror::Object> sirt_obj(soa.Self(), o);
+ // May cause resolution.
+ CHECK(!kMovingFields) << "Resolution may trigger thread suspension";
+ field_type = fh.GetType(true);
+ if (field_type == nullptr) {
+ DCHECK(soa.Self()->IsExceptionPending());
+ return;
+ }
+ } else {
+ field_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(field_type_desciptor[0]);
+ }
+ }
+ // We now don't expect suspension unless an exception is thrown.
// Unbox the value, if necessary.
mirror::Object* boxed_value = soa.Decode<mirror::Object*>(javaValue);
JValue unboxed_value;
- if (!UnboxPrimitiveForField(boxed_value, FieldHelper(f).GetType(), unboxed_value, f)) {
+ if (!UnboxPrimitiveForField(boxed_value, field_type, unboxed_value, f)) {
+ DCHECK(soa.Self()->IsExceptionPending());
return;
}
-
- // Check that the receiver is non-null and an instance of the field's declaring class.
- mirror::Object* o = NULL;
- if (!CheckReceiver(soa, javaObj, f, o)) {
- return;
- }
-
- SetFieldValue(soa, o, f, unboxed_value, true);
+ SetFieldValue(soa, o, f, field_prim_type, true, unboxed_value);
}
static void SetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char src_descriptor,
const JValue& new_value) {
ScopedFastNativeObjectAccess soa(env);
- mirror::ArtField* f = soa.DecodeField(env->FromReflectedField(javaField));
- mirror::Object* o = NULL;
- if (!CheckReceiver(soa, javaObj, f, o)) {
+ mirror::ArtField* f = mirror::ArtField::FromReflectedField(soa, javaField);
+ mirror::Object* o = nullptr;
+ if (!CheckReceiver(soa, javaObj, f, &o)) {
return;
}
- FieldHelper fh(f);
- if (!fh.IsPrimitiveType()) {
- ThrowIllegalArgumentException(NULL, StringPrintf("Not a primitive field: %s",
- PrettyField(f).c_str()).c_str());
+ Primitive::Type field_type = FieldHelper(f).GetTypeAsPrimitiveType();
+ if (UNLIKELY(field_type == Primitive::kPrimNot)) {
+ ThrowIllegalArgumentException(nullptr, StringPrintf("Not a primitive field: %s",
+ PrettyField(f).c_str()).c_str());
return;
}
// Widen the value if necessary (and possible).
JValue wide_value;
- mirror::Class* src_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(src_descriptor);
- if (!ConvertPrimitiveValue(NULL, false, src_type->GetPrimitiveType(), fh.GetTypeAsPrimitiveType(),
- new_value, wide_value)) {
+ if (!ConvertPrimitiveValue(nullptr, false, Primitive::GetType(src_descriptor),
+ field_type, new_value, wide_value)) {
+ DCHECK(soa.Self()->IsExceptionPending());
return;
}
// Write the value.
- SetFieldValue(soa, o, f, wide_value, false);
+ SetFieldValue(soa, o, f, field_type, false, wide_value);
}
static void Field_setBoolean(JNIEnv* env, jobject javaField, jobject javaObj, jboolean z) {
diff --git a/runtime/native/java_lang_reflect_Method.cc b/runtime/native/java_lang_reflect_Method.cc
index 0b8bb7b..abb73b6 100644
--- a/runtime/native/java_lang_reflect_Method.cc
+++ b/runtime/native/java_lang_reflect_Method.cc
@@ -37,10 +37,7 @@
static jobject Method_getExceptionTypesNative(JNIEnv* env, jobject javaMethod) {
ScopedFastNativeObjectAccess soa(env);
- jobject art_method = soa.Env()->GetObjectField(
- javaMethod, WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod);
-
- mirror::ArtMethod* proxy_method = soa.Decode<mirror::Object*>(art_method)->AsArtMethod();
+ mirror::ArtMethod* proxy_method = mirror::ArtMethod::FromReflectedMethod(soa, javaMethod);
CHECK(proxy_method->GetDeclaringClass()->IsProxyClass());
mirror::SynthesizedProxyClass* proxy_class =
down_cast<mirror::SynthesizedProxyClass*>(proxy_method->GetDeclaringClass());
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index dde9a94..f567055 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -462,8 +462,7 @@
jobject InvokeMethod(const ScopedObjectAccess& soa, jobject javaMethod,
jobject javaReceiver, jobject javaArgs) {
- jmethodID mid = soa.Env()->FromReflectedMethod(javaMethod);
- mirror::ArtMethod* m = soa.DecodeMethod(mid);
+ mirror::ArtMethod* m = mirror::ArtMethod::FromReflectedMethod(soa, javaMethod);
mirror::Class* declaring_class = m->GetDeclaringClass();
if (UNLIKELY(!declaring_class->IsInitialized())) {