Skip to content

Commit 186a9b2

Browse files
committed
added ResolvedJavaType.getDeclaredTypes
1 parent 3d9e209 commit 186a9b2

File tree

6 files changed

+107
-4
lines changed

6 files changed

+107
-4
lines changed

src/hotspot/share/jvmci/jvmciCompilerToVM.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2033,6 +2033,57 @@ C2V_VMENTRY_NULL(jobject, getComponentType, (JNIEnv* env, jobject, ARGUMENT_PAIR
20332033
return JVMCIENV->get_jobject(result);
20342034
C2V_END
20352035

2036+
// Iterates over the inner classes of `k` and adds them to `inner_types` if it is non-null.
2037+
// Returns the number of inner classes.
2038+
static int iterate_inner_classes(InstanceKlass* k, JVMCIObjectArray& inner_types, JavaThread* THREAD, JVMCIEnv* JVMCIENV) {
2039+
InnerClassesIterator iter(k);
2040+
constantPoolHandle cp(THREAD, k->constants());
2041+
int length = iter.length();
2042+
int members = 0;
2043+
for (; !iter.done(); iter.next()) {
2044+
int ioff = iter.inner_class_info_index();
2045+
int ooff = iter.outer_class_info_index();
2046+
2047+
if (ioff != 0 && ooff != 0) {
2048+
// Check to see if the name matches the class we're looking for
2049+
// before attempting to find the class.
2050+
if (cp->klass_name_at_matches(k, ooff)) {
2051+
Klass* outer_klass = cp->klass_at(ooff, CHECK_0);
2052+
if (outer_klass == k) {
2053+
Klass* ik = cp->klass_at(ioff, CHECK_0);
2054+
InstanceKlass* inner_klass = InstanceKlass::cast(ik);
2055+
if (inner_types.is_null()) {
2056+
// Throws an exception if outer klass has not declared k as
2057+
// an inner klass
2058+
Reflection::check_for_inner_class(k, inner_klass, true, CHECK_0);
2059+
} else {
2060+
JVMCIObject inner_type = JVMCIENV->get_jvmci_type(JVMCIKlassHandle(THREAD, inner_klass), JVMCI_CHECK_0);
2061+
JVMCIENV->put_object_at(inner_types, members, inner_type);
2062+
}
2063+
members++;
2064+
}
2065+
}
2066+
}
2067+
}
2068+
return members;
2069+
}
2070+
2071+
C2V_VMENTRY_NULL(jobject, getDeclaredTypes, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass)))
2072+
Klass* klass = UNPACK_PAIR(Klass, klass);
2073+
if (klass == nullptr) {
2074+
JVMCI_THROW_NULL(NullPointerException);
2075+
}
2076+
if (!klass->is_instance_klass()) {
2077+
JVMCI_THROW_MSG_NULL(InternalError, err_msg("Class %s must be instance klass", klass->external_name()));
2078+
}
2079+
InstanceKlass* k = InstanceKlass::cast(klass);
2080+
JVMCIObjectArray inner_types;
2081+
int length = iterate_inner_classes(k, inner_types, thread, JVMCIENV);
2082+
inner_types = JVMCIENV->new_HotSpotResolvedObjectTypeImpl_array(length, JVMCI_CHECK_NULL);
2083+
iterate_inner_classes(k, inner_types, thread, JVMCIENV);
2084+
return JVMCIENV->get_jobject(inner_types);
2085+
C2V_END
2086+
20362087
C2V_VMENTRY(void, ensureInitialized, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass)))
20372088
Klass* klass = UNPACK_PAIR(Klass, klass);
20382089
if (klass == nullptr) {
@@ -3445,6 +3496,7 @@ JNINativeMethod CompilerToVM::methods[] = {
34453496
{CC "updateCompilerThreadCanCallJava", CC "(Z)Z", FN_PTR(updateCompilerThreadCanCallJava)},
34463497
{CC "getCompilationActivityMode", CC "()I", FN_PTR(getCompilationActivityMode)},
34473498
{CC "isCompilerThread", CC "()Z", FN_PTR(isCompilerThread)},
3499+
{CC "getDeclaredTypes", CC "(" HS_KLASS2 ")[" HS_KLASS, FN_PTR(getDeclaredTypes)},
34483500
};
34493501

34503502
int CompilerToVM::methods_count() {

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,6 +1182,15 @@ HotSpotResolvedObjectTypeImpl.FieldInfo[] getDeclaredFieldsInfo(HotSpotResolvedO
11821182

11831183
native HotSpotResolvedObjectTypeImpl.FieldInfo[] getDeclaredFieldsInfo(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
11841184

1185+
/**
1186+
* @see ResolvedJavaType#getDeclaredTypes()
1187+
*/
1188+
HotSpotResolvedObjectTypeImpl[] getDeclaredTypes(HotSpotResolvedObjectTypeImpl klass) {
1189+
return getDeclaredTypes(klass, klass.getKlassPointer());
1190+
}
1191+
1192+
native HotSpotResolvedObjectTypeImpl[] getDeclaredTypes(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1193+
11851194
/**
11861195
* Reads the current value of a static field of {@code declaringKlass}. Extra sanity checking is
11871196
* performed on the offset and kind of the read being performed.

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@
3434
import java.lang.reflect.Field;
3535
import java.lang.reflect.Modifier;
3636
import java.nio.ByteOrder;
37-
import java.util.Arrays;
38-
import java.util.Collections;
39-
import java.util.Comparator;
4037
import java.util.HashMap;
4138
import java.util.List;
4239

@@ -1075,6 +1072,14 @@ public List<ResolvedJavaMethod> getAllMethods(boolean forceLink) {
10751072
return List.of(runtime().compilerToVm.getAllMethods(this));
10761073
}
10771074

1075+
@Override
1076+
public ResolvedJavaType[] getDeclaredTypes() {
1077+
if (isArray()) {
1078+
return new ResolvedJavaType[0];
1079+
}
1080+
return compilerToVM().getDeclaredTypes(this);
1081+
}
1082+
10781083
@Override
10791084
public ResolvedJavaMethod getClassInitializer() {
10801085
if (!isArray()) {

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,11 @@ public ResolvedJavaMethod[] getDeclaredMethods(boolean forceLink) {
307307
return new ResolvedJavaMethod[0];
308308
}
309309

310+
@Override
311+
public ResolvedJavaType[] getDeclaredTypes() {
312+
return new ResolvedJavaType[0];
313+
}
314+
310315
@Override
311316
public ResolvedJavaMethod[] getDeclaredMethods() {
312317
return new ResolvedJavaMethod[0];

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaType.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,9 +333,23 @@ default ResolvedJavaMethod resolveConcreteMethod(ResolvedJavaMethod method, Reso
333333

334334
/**
335335
* Returns {@code true} if the type is a member type.
336+
*
337+
* @see Class#isMemberClass()
336338
*/
337339
boolean isMember();
338340

341+
/**
342+
* Gets the classes and interfaces declared as members of this type.
343+
* This includes public, protected, default
344+
* (package) access, and private classes and interfaces declared by the
345+
* class, but excludes inherited classes and interfaces. This method
346+
* returns an array of length 0 if this type declares no classes or
347+
* interfaces as members, or if it is a primitive type, an array class, or void.
348+
*
349+
* @see Class#getDeclaredClasses()
350+
*/
351+
ResolvedJavaType[] getDeclaredTypes();
352+
339353
/**
340354
* Returns the enclosing type of this type, if it exists, or {@code null}.
341355
*/

test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@
7575
import java.util.ArrayList;
7676
import java.util.Arrays;
7777
import java.util.Collection;
78-
import java.util.Collections;
7978
import java.util.function.BiConsumer;
8079
import java.util.function.Supplier;
8180
import java.util.HashMap;
@@ -1084,6 +1083,25 @@ public void getAllMethodsTest() {
10841083
}
10851084
}
10861085

1086+
@Test
1087+
public void getDeclaredTypesTest() {
1088+
for (Class<?> c : classes) {
1089+
ResolvedJavaType type = metaAccess.lookupJavaType(c);
1090+
Class<?>[] raw = c.getDeclaredClasses();
1091+
Set<ResolvedJavaType> expected = new HashSet<>();
1092+
for (Class<?> e : raw) {
1093+
ResolvedJavaType resolvedType = metaAccess.lookupJavaType(e);
1094+
assertNotNull(resolvedType);
1095+
expected.add(resolvedType);
1096+
}
1097+
Set<ResolvedJavaType> actual = new HashSet<>(Arrays.asList(type.getDeclaredTypes()));
1098+
for (ResolvedJavaType t : actual) {
1099+
assertNotNull(t.toString(), runtime.getMirror(t));
1100+
}
1101+
assertEquals(expected, actual);
1102+
}
1103+
}
1104+
10871105
static class A {
10881106
static String name = "foo";
10891107
}

0 commit comments

Comments
 (0)