ART: Add method code item functions
Add support for GetArgumentsSize, GetMaxLocals and GetMethodLocation
support. Add tests.
Bug: 34163329
Test: m test-art-host-run-test-910-methods
Change-Id: I14b5d02bf0513dc5a8d3f4ea17c849ab08b8554a
diff --git a/test/910-methods/expected.txt b/test/910-methods/expected.txt
index 9a74799..539f85b 100644
--- a/test/910-methods/expected.txt
+++ b/test/910-methods/expected.txt
@@ -1,15 +1,35 @@
[toString, ()Ljava/lang/String;, null]
class java.lang.Object
1
+Max locals: 3
+Argument size: 1
+Location start: 0
+Location end: 40
[charAt, (I)C, null]
class java.lang.String
257
+Max locals: JVMTI_ERROR_NATIVE_METHOD
+Argument size: JVMTI_ERROR_NATIVE_METHOD
+Location start: JVMTI_ERROR_NATIVE_METHOD
+Location end: JVMTI_ERROR_NATIVE_METHOD
[sqrt, (D)D, null]
class java.lang.Math
265
+Max locals: JVMTI_ERROR_NATIVE_METHOD
+Argument size: JVMTI_ERROR_NATIVE_METHOD
+Location start: JVMTI_ERROR_NATIVE_METHOD
+Location end: JVMTI_ERROR_NATIVE_METHOD
[add, (Ljava/lang/Object;)Z, null]
interface java.util.List
1025
+Max locals: 0
+Argument size: 0
+Location start: 0
+Location end: 0
[run, ()V, null]
class $Proxy0
17
+Max locals: 0
+Argument size: 0
+Location start: 0
+Location end: 0
diff --git a/test/910-methods/methods.cc b/test/910-methods/methods.cc
index b64952d..d3e4987 100644
--- a/test/910-methods/methods.cc
+++ b/test/910-methods/methods.cc
@@ -114,6 +114,80 @@
return modifiers;
}
+static bool ErrorToException(JNIEnv* env, jvmtiError error) {
+ if (error == JVMTI_ERROR_NONE) {
+ return false;
+ }
+
+ ScopedLocalRef<jclass> rt_exception(env, env->FindClass("java/lang/RuntimeException"));
+ if (rt_exception.get() == nullptr) {
+ // CNFE should be pending.
+ return true;
+ }
+
+ char* err;
+ jvmti_env->GetErrorName(error, &err);
+
+ env->ThrowNew(rt_exception.get(), err);
+
+ jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(err));
+ return true;
+}
+
+extern "C" JNIEXPORT jint JNICALL Java_Main_getMaxLocals(
+ JNIEnv* env, jclass klass ATTRIBUTE_UNUSED, jobject method) {
+ jmethodID id = env->FromReflectedMethod(method);
+
+ jint max_locals;
+ jvmtiError result = jvmti_env->GetMaxLocals(id, &max_locals);
+ if (ErrorToException(env, result)) {
+ return -1;
+ }
+
+ return max_locals;
+}
+
+extern "C" JNIEXPORT jint JNICALL Java_Main_getArgumentsSize(
+ JNIEnv* env, jclass klass ATTRIBUTE_UNUSED, jobject method) {
+ jmethodID id = env->FromReflectedMethod(method);
+
+ jint arguments;
+ jvmtiError result = jvmti_env->GetArgumentsSize(id, &arguments);
+ if (ErrorToException(env, result)) {
+ return -1;
+ }
+
+ return arguments;
+}
+
+extern "C" JNIEXPORT jlong JNICALL Java_Main_getMethodLocationStart(
+ JNIEnv* env, jclass klass ATTRIBUTE_UNUSED, jobject method) {
+ jmethodID id = env->FromReflectedMethod(method);
+
+ jlong start;
+ jlong end;
+ jvmtiError result = jvmti_env->GetMethodLocation(id, &start, &end);
+ if (ErrorToException(env, result)) {
+ return -1;
+ }
+
+ return start;
+}
+
+extern "C" JNIEXPORT jlong JNICALL Java_Main_getMethodLocationEnd(
+ JNIEnv* env, jclass klass ATTRIBUTE_UNUSED, jobject method) {
+ jmethodID id = env->FromReflectedMethod(method);
+
+ jlong start;
+ jlong end;
+ jvmtiError result = jvmti_env->GetMethodLocation(id, &start, &end);
+ if (ErrorToException(env, result)) {
+ return -1;
+ }
+
+ return end;
+}
+
// 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 3459134..8f722e8 100644
--- a/test/910-methods/src/Main.java
+++ b/test/910-methods/src/Main.java
@@ -68,9 +68,41 @@
throw new RuntimeException("Modifiers not equal: " + m.getModifiers() + " vs " + modifiers);
}
System.out.println(modifiers);
+
+ System.out.print("Max locals: ");
+ try {
+ System.out.println(getMaxLocals(m));
+ } catch (RuntimeException e) {
+ System.out.println(e.getMessage());
+ }
+
+ System.out.print("Argument size: ");
+ try {
+ System.out.println(getArgumentsSize(m));
+ } catch (RuntimeException e) {
+ System.out.println(e.getMessage());
+ }
+
+ System.out.print("Location start: ");
+ try {
+ System.out.println(getMethodLocationStart(m));
+ } catch (RuntimeException e) {
+ System.out.println(e.getMessage());
+ }
+
+ System.out.print("Location end: ");
+ try {
+ System.out.println(getMethodLocationEnd(m));
+ } catch (RuntimeException e) {
+ System.out.println(e.getMessage());
+ }
}
private static native String[] getMethodName(Method m);
private static native Class<?> getMethodDeclaringClass(Method m);
private static native int getMethodModifiers(Method m);
+ private static native int getMaxLocals(Method m);
+ private static native int getArgumentsSize(Method m);
+ private static native long getMethodLocationStart(Method m);
+ private static native long getMethodLocationEnd(Method m);
}