From: Andreas Gampe Date: Fri, 6 Jan 2017 21:07:19 +0000 (-0800) Subject: ART: Add GetClassModifiers X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=64013e5b5a57761d9a6767b9b03ff4f15fac51c2;p=android-x86%2Fart.git ART: Add GetClassModifiers Add support for GetClassModifiers. Add a test. Bug: 31684578 Test: m test-art-host-run-test-912-classes Change-Id: Ia14276d3139503ce35f7684bd846b371e9eafa25 --- diff --git a/runtime/openjdkjvmti/OpenjdkJvmTi.cc b/runtime/openjdkjvmti/OpenjdkJvmTi.cc index 528391954..75c314f01 100644 --- a/runtime/openjdkjvmti/OpenjdkJvmTi.cc +++ b/runtime/openjdkjvmti/OpenjdkJvmTi.cc @@ -546,7 +546,7 @@ class JvmtiFunctions { } static jvmtiError GetClassModifiers(jvmtiEnv* env, jclass klass, jint* modifiers_ptr) { - return ERR(NOT_IMPLEMENTED); + return ClassUtil::GetClassModifiers(env, klass, modifiers_ptr); } static jvmtiError GetClassMethods(jvmtiEnv* env, diff --git a/runtime/openjdkjvmti/ti_class.cc b/runtime/openjdkjvmti/ti_class.cc index 415e25857..76d070c79 100644 --- a/runtime/openjdkjvmti/ti_class.cc +++ b/runtime/openjdkjvmti/ti_class.cc @@ -224,4 +224,40 @@ jvmtiError ClassUtil::IsArrayClass(jvmtiEnv* env ATTRIBUTE_UNUSED, return ClassIsT(jklass, test, is_array_class_ptr); } +// Keep this in sync with Class.getModifiers(). +static uint32_t ClassGetModifiers(art::Thread* self, art::ObjPtr klass) + REQUIRES_SHARED(art::Locks::mutator_lock_) { + if (klass->IsArrayClass()) { + uint32_t component_modifiers = ClassGetModifiers(self, klass->GetComponentType()); + if ((component_modifiers & art::kAccInterface) != 0) { + component_modifiers &= ~(art::kAccInterface | art::kAccStatic); + } + return art::kAccAbstract | art::kAccFinal | component_modifiers; + } + + uint32_t modifiers = klass->GetAccessFlags() & art::kAccJavaFlagsMask; + + art::StackHandleScope<1> hs(self); + art::Handle h_klass(hs.NewHandle(klass)); + return art::mirror::Class::GetInnerClassFlags(h_klass, modifiers); +} + +jvmtiError ClassUtil::GetClassModifiers(jvmtiEnv* env ATTRIBUTE_UNUSED, + jclass jklass, + jint* modifiers_ptr) { + art::ScopedObjectAccess soa(art::Thread::Current()); + art::ObjPtr klass = soa.Decode(jklass); + if (klass == nullptr) { + return ERR(INVALID_CLASS); + } + + if (modifiers_ptr == nullptr) { + return ERR(NULL_POINTER); + } + + *modifiers_ptr = ClassGetModifiers(soa.Self(), klass); + + return ERR(NONE); +} + } // namespace openjdkjvmti diff --git a/runtime/openjdkjvmti/ti_class.h b/runtime/openjdkjvmti/ti_class.h index 838c94ceb..619f50e15 100644 --- a/runtime/openjdkjvmti/ti_class.h +++ b/runtime/openjdkjvmti/ti_class.h @@ -49,6 +49,8 @@ class ClassUtil { jint* method_count_ptr, jmethodID** methods_ptr); + static jvmtiError GetClassModifiers(jvmtiEnv* env, jclass klass, jint* modifiers_ptr); + static jvmtiError GetClassSignature(jvmtiEnv* env, jclass klass, char** signature_ptr, diff --git a/test/912-classes/classes.cc b/test/912-classes/classes.cc index 6771d7183..3383d0431 100644 --- a/test/912-classes/classes.cc +++ b/test/912-classes/classes.cc @@ -87,6 +87,19 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_isArrayClass( return is_array_class; } +extern "C" JNIEXPORT jint JNICALL Java_Main_getClassModifiers( + JNIEnv* env ATTRIBUTE_UNUSED, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) { + jint mod; + jvmtiError result = jvmti_env->GetClassModifiers(klass, &mod); + if (result != JVMTI_ERROR_NONE) { + char* err; + jvmti_env->GetErrorName(result, &err); + printf("Failure running GetClassModifiers: %s\n", err); + return JNI_FALSE; + } + return mod; +} + extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getClassFields( JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) { jint count = 0; diff --git a/test/912-classes/expected.txt b/test/912-classes/expected.txt index 999990364..de23b7bc4 100644 --- a/test/912-classes/expected.txt +++ b/test/912-classes/expected.txt @@ -1,10 +1,17 @@ [Ljava/lang/Object;, null] +1 [Ljava/lang/String;, null] +11 [Ljava/lang/Math;, null] +11 [Ljava/util/List;, null] +601 [L$Proxy0;, null] +11 [I, null] +411 [[D, null] +411 int interface=false array=false $Proxy0 interface=false array=false java.lang.Runnable interface=true array=false diff --git a/test/912-classes/src/Main.java b/test/912-classes/src/Main.java index fd9e31aea..cbcfe71aa 100644 --- a/test/912-classes/src/Main.java +++ b/test/912-classes/src/Main.java @@ -82,6 +82,11 @@ public class Main { private static void testClass(Class base) throws Exception { String[] result = getClassSignature(base); System.out.println(Arrays.toString(result)); + int mod = getClassModifiers(base); + if (mod != base.getModifiers()) { + throw new RuntimeException("Unexpected modifiers: " + base.getModifiers() + " vs " + mod); + } + System.out.println(Integer.toHexString(mod)); } private static void testClassType(Class c) throws Exception { @@ -107,6 +112,8 @@ public class Main { private static native boolean isInterface(Class c); private static native boolean isArrayClass(Class c); + private static native int getClassModifiers(Class c); + private static native Object[] getClassFields(Class c); private static native Object[] getClassMethods(Class c);