summaryrefslogtreecommitdiff
path: root/runtime/openjdkjvmti/ti_class.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/openjdkjvmti/ti_class.cc')
-rw-r--r--runtime/openjdkjvmti/ti_class.cc80
1 files changed, 79 insertions, 1 deletions
diff --git a/runtime/openjdkjvmti/ti_class.cc b/runtime/openjdkjvmti/ti_class.cc
index 7b30a9da74..76d070c799 100644
--- a/runtime/openjdkjvmti/ti_class.cc
+++ b/runtime/openjdkjvmti/ti_class.cc
@@ -52,7 +52,6 @@ jvmtiError ClassUtil::GetClassFields(jvmtiEnv* env,
return ERR(NULL_POINTER);
}
- art::StackHandleScope<1> hs(soa.Self());
art::IterationRange<art::StrideIterator<art::ArtField>> ifields = klass->GetIFields();
art::IterationRange<art::StrideIterator<art::ArtField>> sfields = klass->GetSFields();
size_t array_size = klass->NumInstanceFields() + klass->NumStaticFields();
@@ -80,6 +79,49 @@ jvmtiError ClassUtil::GetClassFields(jvmtiEnv* env,
return ERR(NONE);
}
+jvmtiError ClassUtil::GetClassMethods(jvmtiEnv* env,
+ jclass jklass,
+ jint* method_count_ptr,
+ jmethodID** methods_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 (method_count_ptr == nullptr || methods_ptr == nullptr) {
+ return ERR(NULL_POINTER);
+ }
+
+ size_t array_size = klass->NumDeclaredVirtualMethods() + klass->NumDirectMethods();
+ unsigned char* out_ptr;
+ jvmtiError allocError = env->Allocate(array_size * sizeof(jmethodID), &out_ptr);
+ if (allocError != ERR(NONE)) {
+ return allocError;
+ }
+ jmethodID* method_array = reinterpret_cast<jmethodID*>(out_ptr);
+
+ if (art::kIsDebugBuild) {
+ size_t count = 0;
+ for (auto& m ATTRIBUTE_UNUSED : klass->GetDeclaredMethods(art::kRuntimePointerSize)) {
+ count++;
+ }
+ CHECK_EQ(count, klass->NumDirectMethods() + klass->NumDeclaredVirtualMethods());
+ }
+
+ size_t array_idx = 0;
+ for (auto& m : klass->GetDeclaredMethods(art::kRuntimePointerSize)) {
+ method_array[array_idx] = art::jni::EncodeArtMethod(&m);
+ ++array_idx;
+ }
+
+ *method_count_ptr = static_cast<jint>(array_size);
+ *methods_ptr = method_array;
+
+ return ERR(NONE);
+}
+
+
jvmtiError ClassUtil::GetClassSignature(jvmtiEnv* env,
jclass jklass,
char** signature_ptr,
@@ -182,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<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