ART: Add GetClassFields support
Add GetClassFields support. Add a test.
Bug: 31684578
Test: m test-art-host-run-test-912-classes
Change-Id: Id7509ef10ec9c19b54b7db8637729556b91273e5
diff --git a/runtime/openjdkjvmti/ti_class.cc b/runtime/openjdkjvmti/ti_class.cc
index fec8447..eea317a 100644
--- a/runtime/openjdkjvmti/ti_class.cc
+++ b/runtime/openjdkjvmti/ti_class.cc
@@ -32,11 +32,54 @@
#include "ti_class.h"
#include "art_jvmti.h"
+#include "jni_internal.h"
#include "scoped_thread_state_change-inl.h"
#include "thread-inl.h"
namespace openjdkjvmti {
+jvmtiError ClassUtil::GetClassFields(jvmtiEnv* env,
+ jclass jklass,
+ jint* field_count_ptr,
+ jfieldID** fields_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 (field_count_ptr == nullptr || fields_ptr == nullptr) {
+ 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();
+
+ unsigned char* out_ptr;
+ jvmtiError allocError = env->Allocate(array_size * sizeof(jfieldID), &out_ptr);
+ if (allocError != ERR(NONE)) {
+ return allocError;
+ }
+ jfieldID* field_array = reinterpret_cast<jfieldID*>(out_ptr);
+
+ size_t array_idx = 0;
+ for (art::ArtField& field : sfields) {
+ field_array[array_idx] = art::jni::EncodeArtField(&field);
+ ++array_idx;
+ }
+ for (art::ArtField& field : ifields) {
+ field_array[array_idx] = art::jni::EncodeArtField(&field);
+ ++array_idx;
+ }
+
+ *field_count_ptr = static_cast<jint>(array_size);
+ *fields_ptr = field_array;
+
+ return ERR(NONE);
+}
+
jvmtiError ClassUtil::GetClassSignature(jvmtiEnv* env,
jclass jklass,
char** signature_ptr,