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 5283919..75c314f 100644
--- a/runtime/openjdkjvmti/OpenjdkJvmTi.cc
+++ b/runtime/openjdkjvmti/OpenjdkJvmTi.cc
@@ -546,7 +546,7 @@
   }
 
   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 415e258..76d070c 100644
--- a/runtime/openjdkjvmti/ti_class.cc
+++ b/runtime/openjdkjvmti/ti_class.cc
@@ -224,4 +224,40 @@
   return ClassIsT(jklass, test, is_array_class_ptr);
 }
 
+// Keep this in sync with Class.getModifiers().
+static uint32_t ClassGetModifiers(art::Thread* self, art::ObjPtr<art::mirror::Class> 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<art::mirror::Class> 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<art::mirror::Class> klass = soa.Decode<art::mirror::Class>(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 838c94c..619f50e 100644
--- a/runtime/openjdkjvmti/ti_class.h
+++ b/runtime/openjdkjvmti/ti_class.h
@@ -49,6 +49,8 @@
                                     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,