From 36bcd4f3f56adf889d488b3fd0fdc7e38e519675 Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Fri, 28 Oct 2016 18:07:18 -0700 Subject: [PATCH] ART: Add GetMethodModifiers Support GetMethodModifiers to retrieve the modifiers of a JNI method. Extend test 910. Bug: 31684812 Test: m test-art-host-run-test-910-methods Change-Id: Ib44df099bc056c557e526d5fa267df48ac2fd86c --- runtime/openjdkjvmti/OpenjdkJvmTi.cc | 2 +- runtime/openjdkjvmti/ti_method.cc | 27 +++++++++++++++++++++++++++ runtime/openjdkjvmti/ti_method.h | 4 ++++ test/910-methods/expected.txt | 5 +++++ test/910-methods/methods.cc | 16 ++++++++++++++++ test/910-methods/src/Main.java | 7 +++++++ 6 files changed, 60 insertions(+), 1 deletion(-) diff --git a/runtime/openjdkjvmti/OpenjdkJvmTi.cc b/runtime/openjdkjvmti/OpenjdkJvmTi.cc index f95ec591d..9c3e4fcf2 100644 --- a/runtime/openjdkjvmti/OpenjdkJvmTi.cc +++ b/runtime/openjdkjvmti/OpenjdkJvmTi.cc @@ -654,7 +654,7 @@ class JvmtiFunctions { static jvmtiError GetMethodModifiers(jvmtiEnv* env, jmethodID method, jint* modifiers_ptr) { - return ERR(NOT_IMPLEMENTED); + return MethodUtil::GetMethodModifiers(env, method, modifiers_ptr); } static jvmtiError GetMaxLocals(jvmtiEnv* env, diff --git a/runtime/openjdkjvmti/ti_method.cc b/runtime/openjdkjvmti/ti_method.cc index 4aae4d1d4..7b82e7c07 100644 --- a/runtime/openjdkjvmti/ti_method.cc +++ b/runtime/openjdkjvmti/ti_method.cc @@ -34,6 +34,7 @@ #include "art_jvmti.h" #include "art_method-inl.h" #include "base/enums.h" +#include "modifiers.h" #include "scoped_thread_state_change-inl.h" namespace openjdkjvmti { @@ -114,4 +115,30 @@ jvmtiError MethodUtil::GetMethodDeclaringClass(jvmtiEnv* env ATTRIBUTE_UNUSED, return ERR(NONE); } +jvmtiError MethodUtil::GetMethodModifiers(jvmtiEnv* env ATTRIBUTE_UNUSED, + jmethodID method, + jint* modifiers_ptr) { + if (modifiers_ptr == nullptr) { + return ERR(NULL_POINTER); + } + + art::ScopedObjectAccess soa(art::Thread::Current()); + art::ArtMethod* art_method = soa.DecodeMethod(method); + + uint32_t modifiers = art_method->GetAccessFlags(); + + // Note: Keep this code in sync with Executable.fixMethodFlags. + if ((modifiers & art::kAccAbstract) != 0) { + modifiers &= ~art::kAccNative; + } + modifiers &= ~art::kAccSynchronized; + if ((modifiers & art::kAccDeclaredSynchronized) != 0) { + modifiers |= art::kAccSynchronized; + } + modifiers &= art::kAccJavaFlagsMask; + + *modifiers_ptr = modifiers; + return ERR(NONE); +} + } // namespace openjdkjvmti diff --git a/runtime/openjdkjvmti/ti_method.h b/runtime/openjdkjvmti/ti_method.h index 7cae0bf58..43f11f97e 100644 --- a/runtime/openjdkjvmti/ti_method.h +++ b/runtime/openjdkjvmti/ti_method.h @@ -48,6 +48,10 @@ class MethodUtil { static jvmtiError GetMethodDeclaringClass(jvmtiEnv* env, jmethodID method, jclass* declaring_class_ptr); + + static jvmtiError GetMethodModifiers(jvmtiEnv* env, + jmethodID method, + jint* modifiers_ptr); }; } // namespace openjdkjvmti diff --git a/test/910-methods/expected.txt b/test/910-methods/expected.txt index 980edc349..9a747994f 100644 --- a/test/910-methods/expected.txt +++ b/test/910-methods/expected.txt @@ -1,10 +1,15 @@ [toString, ()Ljava/lang/String;, null] class java.lang.Object +1 [charAt, (I)C, null] class java.lang.String +257 [sqrt, (D)D, null] class java.lang.Math +265 [add, (Ljava/lang/Object;)Z, null] interface java.util.List +1025 [run, ()V, null] class $Proxy0 +17 diff --git a/test/910-methods/methods.cc b/test/910-methods/methods.cc index 214ae505d..cc6ad6793 100644 --- a/test/910-methods/methods.cc +++ b/test/910-methods/methods.cc @@ -91,6 +91,22 @@ extern "C" JNIEXPORT jclass JNICALL Java_Main_getMethodDeclaringClass( return declaring_class; } +extern "C" JNIEXPORT jint JNICALL Java_Main_getMethodModifiers( + JNIEnv* env, jclass klass ATTRIBUTE_UNUSED, jobject method) { + jmethodID id = env->FromReflectedMethod(method); + + jint modifiers; + jvmtiError result = jvmti_env->GetMethodModifiers(id, &modifiers); + if (result != JVMTI_ERROR_NONE) { + char* err; + jvmti_env->GetErrorName(result, &err); + printf("Failure running GetMethodModifiers: %s\n", err); + return 0; + } + + return modifiers; +} + // Don't do anything jint OnLoad(JavaVM* vm, char* options ATTRIBUTE_UNUSED, diff --git a/test/910-methods/src/Main.java b/test/910-methods/src/Main.java index d8c4627d8..3459134ea 100644 --- a/test/910-methods/src/Main.java +++ b/test/910-methods/src/Main.java @@ -62,8 +62,15 @@ public class Main { throw new RuntimeException("Declaring class not equal: " + base + " vs " + declClass); } System.out.println(declClass); + + int modifiers = getMethodModifiers(m); + if (modifiers != m.getModifiers()) { + throw new RuntimeException("Modifiers not equal: " + m.getModifiers() + " vs " + modifiers); + } + System.out.println(modifiers); } private static native String[] getMethodName(Method m); private static native Class getMethodDeclaringClass(Method m); + private static native int getMethodModifiers(Method m); } -- 2.11.0