diff options
| -rw-r--r-- | runtime/openjdkjvmti/OpenjdkJvmTi.cc | 2 | ||||
| -rw-r--r-- | runtime/openjdkjvmti/ti_class.cc | 31 | ||||
| -rw-r--r-- | runtime/openjdkjvmti/ti_class.h | 5 | ||||
| -rw-r--r-- | test/912-classes/classes.cc | 18 | ||||
| -rw-r--r-- | test/912-classes/expected.txt | 2 | ||||
| -rw-r--r-- | test/912-classes/src/Main.java | 10 |
6 files changed, 67 insertions, 1 deletions
diff --git a/runtime/openjdkjvmti/OpenjdkJvmTi.cc b/runtime/openjdkjvmti/OpenjdkJvmTi.cc index 4589c9283f..fcedd4ee4c 100644 --- a/runtime/openjdkjvmti/OpenjdkJvmTi.cc +++ b/runtime/openjdkjvmti/OpenjdkJvmTi.cc @@ -594,7 +594,7 @@ class JvmtiFunctions { jclass klass, jint* minor_version_ptr, jint* major_version_ptr) { - return ERR(NOT_IMPLEMENTED); + return ClassUtil::GetClassVersionNumbers(env, klass, minor_version_ptr, major_version_ptr); } static jvmtiError GetConstantPool(jvmtiEnv* env, diff --git a/runtime/openjdkjvmti/ti_class.cc b/runtime/openjdkjvmti/ti_class.cc index d1324bc13f..abcc84925b 100644 --- a/runtime/openjdkjvmti/ti_class.cc +++ b/runtime/openjdkjvmti/ti_class.cc @@ -417,4 +417,35 @@ jvmtiError ClassUtil::GetClassLoaderClasses(jvmtiEnv* env, return ERR(NONE); } +jvmtiError ClassUtil::GetClassVersionNumbers(jvmtiEnv* env ATTRIBUTE_UNUSED, + jclass jklass, + jint* minor_version_ptr, + jint* major_version_ptr) { + art::ScopedObjectAccess soa(art::Thread::Current()); + if (jklass == nullptr) { + return ERR(INVALID_CLASS); + } + art::ObjPtr<art::mirror::Object> jklass_obj = soa.Decode<art::mirror::Object>(jklass); + if (!jklass_obj->IsClass()) { + return ERR(INVALID_CLASS); + } + art::ObjPtr<art::mirror::Class> klass = jklass_obj->AsClass(); + if (klass->IsPrimitive() || klass->IsArrayClass()) { + return ERR(INVALID_CLASS); + } + + if (minor_version_ptr == nullptr || major_version_ptr == nullptr) { + return ERR(NULL_POINTER); + } + + // Note: proxies will show the dex file version of java.lang.reflect.Proxy, as that is + // what their dex cache copies from. + uint32_t version = klass->GetDexFile().GetHeader().GetVersion(); + + *major_version_ptr = static_cast<jint>(version); + *minor_version_ptr = 0; + + return ERR(NONE); +} + } // namespace openjdkjvmti diff --git a/runtime/openjdkjvmti/ti_class.h b/runtime/openjdkjvmti/ti_class.h index 7a0fafbc83..9558894deb 100644 --- a/runtime/openjdkjvmti/ti_class.h +++ b/runtime/openjdkjvmti/ti_class.h @@ -72,6 +72,11 @@ class ClassUtil { static jvmtiError IsInterface(jvmtiEnv* env, jclass klass, jboolean* is_interface_ptr); static jvmtiError IsArrayClass(jvmtiEnv* env, jclass klass, jboolean* is_array_class_ptr); + + static jvmtiError GetClassVersionNumbers(jvmtiEnv* env, + jclass klass, + jint* minor_version_ptr, + jint* major_version_ptr); }; } // namespace openjdkjvmti diff --git a/test/912-classes/classes.cc b/test/912-classes/classes.cc index a22d1d72d8..29eeff6694 100644 --- a/test/912-classes/classes.cc +++ b/test/912-classes/classes.cc @@ -241,5 +241,23 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getClassLoaderClasses( return ret; } +extern "C" JNIEXPORT jintArray JNICALL Java_Main_getClassVersion( + JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) { + jint major, minor; + jvmtiError result = jvmti_env->GetClassVersionNumbers(klass, &minor, &major); + if (JvmtiErrorToException(env, result)) { + return nullptr; + } + + jintArray int_array = env->NewIntArray(2); + if (int_array == nullptr) { + return nullptr; + } + jint buf[2] = { major, minor }; + env->SetIntArrayRegion(int_array, 0, 2, buf); + + return int_array; +} + } // namespace Test912Classes } // namespace art diff --git a/test/912-classes/expected.txt b/test/912-classes/expected.txt index a95a465860..f3cb261480 100644 --- a/test/912-classes/expected.txt +++ b/test/912-classes/expected.txt @@ -59,3 +59,5 @@ boot <- src (B) <- src-ex (A, List) boot <- src+src-ex (A,B) 912-classes.jar+ -> [class A, class B, class java.lang.Object] + +[37, 0] diff --git a/test/912-classes/src/Main.java b/test/912-classes/src/Main.java index ea3c49c87b..cbf2392a73 100644 --- a/test/912-classes/src/Main.java +++ b/test/912-classes/src/Main.java @@ -80,6 +80,10 @@ public class Main { testClassLoader(getProxyClass()); testClassLoaderClasses(); + + System.out.println(); + + testClassVersion(); } private static Class<?> proxyClass = null; @@ -202,6 +206,10 @@ public class Main { } } + private static void testClassVersion() { + System.out.println(Arrays.toString(getClassVersion(Main.class))); + } + private static void printClassLoaderClasses(ClassLoader cl) { for (;;) { if (cl == null || !cl.getClass().getName().startsWith("dalvik.system")) { @@ -262,6 +270,8 @@ public class Main { private static native Class<?>[] getClassLoaderClasses(ClassLoader cl); + private static native int[] getClassVersion(Class<?> c); + private static class TestForNonInit { public static double dummy = Math.random(); // So it can't be compile-time initialized. } |