Skip to content

Commit e235b61

Browse files
teshullDoug Simon
authored andcommitted
8357987: [JVMCI] Add support for retrieving all methods of a ResolvedJavaType
Reviewed-by: dnsimon, yzheng, never
1 parent a44a470 commit e235b61

File tree

11 files changed

+103
-1
lines changed

11 files changed

+103
-1
lines changed

src/hotspot/share/jvmci/jvmciCompilerToVM.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2224,6 +2224,26 @@ C2V_VMENTRY_NULL(jobjectArray, getDeclaredMethods, (JNIEnv* env, jobject, ARGUME
22242224
return JVMCIENV->get_jobjectArray(methods);
22252225
C2V_END
22262226

2227+
C2V_VMENTRY_NULL(jobjectArray, getAllMethods, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass)))
2228+
Klass* klass = UNPACK_PAIR(Klass, klass);
2229+
if (klass == nullptr) {
2230+
JVMCI_THROW_NULL(NullPointerException);
2231+
}
2232+
if (!klass->is_instance_klass()) {
2233+
JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(0, JVMCI_CHECK_NULL);
2234+
return JVMCIENV->get_jobjectArray(methods);
2235+
}
2236+
2237+
InstanceKlass* iklass = InstanceKlass::cast(klass);
2238+
JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(iklass->methods()->length(), JVMCI_CHECK_NULL);
2239+
for (int i = 0; i < iklass->methods()->length(); i++) {
2240+
methodHandle mh(THREAD, iklass->methods()->at(i));
2241+
JVMCIObject method = JVMCIENV->get_jvmci_method(mh, JVMCI_CHECK_NULL);
2242+
JVMCIENV->put_object_at(methods, i, method);
2243+
}
2244+
return JVMCIENV->get_jobjectArray(methods);
2245+
C2V_END
2246+
22272247
C2V_VMENTRY_NULL(jobjectArray, getDeclaredFieldsInfo, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass)))
22282248
Klass* klass = UNPACK_PAIR(Klass, klass);
22292249
if (klass == nullptr) {
@@ -3359,6 +3379,7 @@ JNINativeMethod CompilerToVM::methods[] = {
33593379
{CC "boxPrimitive", CC "(" OBJECT ")" OBJECTCONSTANT, FN_PTR(boxPrimitive)},
33603380
{CC "getDeclaredConstructors", CC "(" HS_KLASS2 ")[" RESOLVED_METHOD, FN_PTR(getDeclaredConstructors)},
33613381
{CC "getDeclaredMethods", CC "(" HS_KLASS2 ")[" RESOLVED_METHOD, FN_PTR(getDeclaredMethods)},
3382+
{CC "getAllMethods", CC "(" HS_KLASS2 ")[" RESOLVED_METHOD, FN_PTR(getAllMethods)},
33623383
{CC "getDeclaredFieldsInfo", CC "(" HS_KLASS2 ")[" FIELDINFO, FN_PTR(getDeclaredFieldsInfo)},
33633384
{CC "readStaticFieldValue", CC "(" HS_KLASS2 "JC)" JAVACONSTANT, FN_PTR(readStaticFieldValue)},
33643385
{CC "readFieldValue", CC "(" OBJECTCONSTANT HS_KLASS2 "JC)" JAVACONSTANT, FN_PTR(readFieldValue)},

src/hotspot/share/jvmci/vmStructs_jvmci.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,7 @@
693693
declare_constant(ConstMethodFlags::_misc_reserved_stack_access) \
694694
declare_constant(ConstMethodFlags::_misc_changes_current_thread) \
695695
declare_constant(ConstMethodFlags::_misc_is_scoped) \
696+
declare_constant(ConstMethodFlags::_misc_is_overpass) \
696697
\
697698
declare_constant(CounterData::count_off) \
698699
\

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1148,14 +1148,24 @@ ResolvedJavaMethod[] getDeclaredConstructors(HotSpotResolvedObjectTypeImpl klass
11481148
native ResolvedJavaMethod[] getDeclaredConstructors(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
11491149

11501150
/**
1151-
* Gets the {@link ResolvedJavaMethod}s for all the non-constructor methods of {@code klass}.
1151+
* Gets the {@link ResolvedJavaMethod}s for all non-overpass and non-initializer
1152+
* methods of {@code klass}.
11521153
*/
11531154
ResolvedJavaMethod[] getDeclaredMethods(HotSpotResolvedObjectTypeImpl klass) {
11541155
return getDeclaredMethods(klass, klass.getKlassPointer());
11551156
}
11561157

11571158
native ResolvedJavaMethod[] getDeclaredMethods(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
11581159

1160+
/**
1161+
* Gets the {@link ResolvedJavaMethod}s for all methods of {@code klass}.
1162+
*/
1163+
ResolvedJavaMethod[] getAllMethods(HotSpotResolvedObjectTypeImpl klass) {
1164+
return getAllMethods(klass, klass.getKlassPointer());
1165+
}
1166+
1167+
native ResolvedJavaMethod[] getAllMethods(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1168+
11591169
HotSpotResolvedObjectTypeImpl.FieldInfo[] getDeclaredFieldsInfo(HotSpotResolvedObjectTypeImpl klass) {
11601170
return getDeclaredFieldsInfo(klass, klass.getKlassPointer());
11611171
}

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,19 @@ public boolean isDefault() {
573573
return ((getModifiers() & mask) == Modifier.PUBLIC) && getDeclaringClass().isInterface();
574574
}
575575

576+
/*
577+
* Currently in hotspot a method can either be a "normal" or an "overpass"
578+
* method. Overpass methods are instance methods which are created when
579+
* otherwise a valid candidate for method resolution would not be found.
580+
*/
581+
@Override
582+
public boolean isDeclared() {
583+
if (isConstructor() || isClassInitializer()) {
584+
return false;
585+
}
586+
return (getConstMethodFlags() & config().constMethodFlagsIsOverpass) == 0;
587+
}
588+
576589
@Override
577590
public Type[] getGenericParameterTypes() {
578591
if (isClassInitializer()) {

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,14 @@ public ResolvedJavaMethod[] getDeclaredMethods(boolean forceLink) {
10671067
return runtime().compilerToVm.getDeclaredMethods(this);
10681068
}
10691069

1070+
@Override
1071+
public List<ResolvedJavaMethod> getAllMethods(boolean forceLink) {
1072+
if (forceLink) {
1073+
link();
1074+
}
1075+
return List.of(runtime().compilerToVm.getAllMethods(this));
1076+
}
1077+
10701078
@Override
10711079
public ResolvedJavaMethod getClassInitializer() {
10721080
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
@@ -296,6 +296,11 @@ public ResolvedJavaMethod[] getDeclaredMethods() {
296296
return new ResolvedJavaMethod[0];
297297
}
298298

299+
@Override
300+
public List<ResolvedJavaMethod> getAllMethods(boolean forceLink) {
301+
return List.of();
302+
}
303+
299304
@Override
300305
public ResolvedJavaMethod getClassInitializer() {
301306
return null;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ long prototypeMarkWord() {
196196
final int constMethodFlagsCallerSensitive = getConstant("ConstMethodFlags::_misc_caller_sensitive", Integer.class);
197197
final int constMethodFlagsIntrinsicCandidate = getConstant("ConstMethodFlags::_misc_intrinsic_candidate", Integer.class);
198198
final int constMethodFlagsIsScoped = getConstant("ConstMethodFlags::_misc_is_scoped", Integer.class);
199+
final int constMethodFlagsIsOverpass = getConstant("ConstMethodFlags::_misc_is_overpass", Integer.class);
199200
final int constMethodHasLineNumberTable = getConstant("ConstMethodFlags::_misc_has_linenumber_table", Integer.class);
200201
final int constMethodHasLocalVariableTable = getConstant("ConstMethodFlags::_misc_has_localvariable_table", Integer.class);
201202
final int constMethodHasMethodAnnotations = getConstant("ConstMethodFlags::_misc_has_method_annotations", Integer.class);

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ default boolean isFinal() {
114114
*/
115115
boolean isDefault();
116116

117+
/**
118+
* Returns {@code true} if this method is contained in the array returned by
119+
* {@code getDeclaringClass().getDeclaredMethods()}
120+
*/
121+
boolean isDeclared();
122+
117123
/**
118124
* Checks whether this method is a class initializer.
119125
*

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
package jdk.vm.ci.meta;
2424

2525
import java.lang.reflect.AnnotatedElement;
26+
import java.util.List;
2627

2728
import jdk.vm.ci.meta.Assumptions.AssumptionResult;
2829

@@ -365,6 +366,17 @@ default ResolvedJavaMethod[] getDeclaredMethods(boolean forceLink) {
365366
throw new UnsupportedOperationException();
366367
}
367368

369+
/**
370+
* Returns a list containing all methods present within this type. This list can
371+
* include methods implicitly created and used by the VM that are not present in
372+
* {@link #getDeclaredMethods}. The returned List is unmodifiable; calls to any
373+
* mutator method will always cause {@code UnsupportedOperationException} to be
374+
* thrown.
375+
*
376+
* @param forceLink if {@code true}, forces this type to be {@link #link linked}
377+
*/
378+
List<ResolvedJavaMethod> getAllMethods(boolean forceLink);
379+
368380
/**
369381
* Returns the {@code <clinit>} method for this class if there is one.
370382
*/

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,19 @@ public void isDefaultTest() {
425425
}
426426
}
427427

428+
@Test
429+
public void isDeclaredTest() {
430+
for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
431+
ResolvedJavaMethod m = e.getValue();
432+
boolean expectedDeclared = Arrays.stream(m.getDeclaringClass().getDeclaredMethods()).anyMatch(i -> i.equals(m));
433+
assertEquals(expectedDeclared, m.isDeclared());
434+
}
435+
for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
436+
ResolvedJavaMethod m = e.getValue();
437+
assertFalse(m.isDeclared());
438+
}
439+
}
440+
428441
@Test
429442
public void hasReceiverTest() {
430443
for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {

0 commit comments

Comments
 (0)