diff options
-rw-r--r-- | runtime/class_linker.cc | 22 | ||||
-rw-r--r-- | runtime/jni_internal.cc | 20 | ||||
-rw-r--r-- | runtime/mirror/art_field.cc | 9 | ||||
-rw-r--r-- | runtime/mirror/art_field.h | 4 | ||||
-rw-r--r-- | runtime/mirror/art_method.cc | 12 | ||||
-rw-r--r-- | runtime/mirror/art_method.h | 4 | ||||
-rw-r--r-- | runtime/native/java_lang_reflect_Constructor.cc | 5 | ||||
-rw-r--r-- | runtime/native/java_lang_reflect_Field.cc | 232 | ||||
-rw-r--r-- | runtime/native/java_lang_reflect_Method.cc | 5 | ||||
-rw-r--r-- | runtime/reflection.cc | 3 |
10 files changed, 174 insertions, 142 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index cef99543b5..08ea123865 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -2314,26 +2314,26 @@ mirror::Class* ClassLinker::CreateArrayClass(Thread* self, const char* descripto } 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 43db7eccb0..13aa77faf2 100644 --- a/runtime/jni_internal.cc +++ b/runtime/jni_internal.cc @@ -550,24 +550,16 @@ class JNI { 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 7740213cf9..f91cab1036 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 @@ namespace mirror { // 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 46287c3ea4..0daa838a2c 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 7814f36075..ee5a0a4060 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 @@ extern "C" void art_quick_invoke_static_stub(ArtMethod*, uint32_t*, uint32_t, Th // 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 c6549330af..fd5ac19435 100644 --- a/runtime/mirror/art_method.h +++ b/runtime/mirror/art_method.h @@ -31,6 +31,7 @@ struct ConstructorMethodOffsets; union JValue; struct MethodClassOffsets; class MethodHelper; +class ScopedObjectAccess; class StringPiece; class ShadowFrame; @@ -44,6 +45,9 @@ typedef void (EntryPointFromInterpreter)(Thread* self, MethodHelper& mh, // 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 a22d7caa06..b7e8ac273a 100644 --- a/runtime/native/java_lang_reflect_Constructor.cc +++ b/runtime/native/java_lang_reflect_Constructor.cc @@ -36,10 +36,7 @@ namespace art { */ 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 7e21d6c985..6667d511c2 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 bool CheckReceiver(const ScopedFastNativeObjectAccess& soa, jobject j_rcv 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 jshort Field_getShort(JNIEnv* env, jobject javaField, jobject javaObj) { } 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 @@ static void SetFieldValue(ScopedFastNativeObjectAccess& soa, mirror::Object* o, // 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)) { - 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)) { + if (!UnboxPrimitiveForField(boxed_value, field_type, unboxed_value, f)) { + DCHECK(soa.Self()->IsExceptionPending()); 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 0b8bb7bbe5..abb73b6927 100644 --- a/runtime/native/java_lang_reflect_Method.cc +++ b/runtime/native/java_lang_reflect_Method.cc @@ -37,10 +37,7 @@ static jobject Method_invoke(JNIEnv* env, 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 dde9a942ff..f5670551e8 100644 --- a/runtime/reflection.cc +++ b/runtime/reflection.cc @@ -462,8 +462,7 @@ void InvokeWithShadowFrame(Thread* self, ShadowFrame* shadow_frame, uint16_t arg 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())) { |