diff options
Diffstat (limited to 'runtime/openjdkjvmti/ti_class.cc')
| -rw-r--r-- | runtime/openjdkjvmti/ti_class.cc | 80 |
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 |