Skip to content

Commit c42fbe8

Browse files
committed
Handle HotSpotJavaType returned by BootstrapMethodInvocation.getStaticArguments
1 parent 3341e75 commit c42fbe8

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/WrappedConstantPool.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@
3232
import java.util.stream.Collectors;
3333

3434
import com.oracle.graal.pointsto.constraints.UnresolvedElementException;
35+
import com.oracle.graal.pointsto.util.GraalAccess;
3536
import com.oracle.svm.util.ReflectionUtil;
3637

38+
import jdk.graal.compiler.api.replacements.SnippetReflectionProvider;
3739
import jdk.graal.compiler.core.common.BootstrapMethodIntrospection;
3840
import jdk.graal.compiler.debug.GraalError;
3941
import jdk.graal.compiler.serviceprovider.BootstrapMethodIntrospectionImpl;
@@ -64,7 +66,27 @@ public int length() {
6466
}
6567

6668
private JavaConstant lookupConstant(JavaConstant constant) {
67-
return universe.lookup(constant);
69+
return universe.lookup(extractResolvedType(constant));
70+
}
71+
72+
public JavaConstant extractResolvedType(JavaConstant constant) {
73+
if (constant != null && constant.getJavaKind().isObject() && !constant.isNull()) {
74+
SnippetReflectionProvider snippetReflection = GraalAccess.getOriginalSnippetReflection();
75+
if (snippetReflection.asObject(Object.class, constant) instanceof ResolvedJavaType resolvedJavaType) {
76+
/*
77+
* BootstrapMethodInvocation.getStaticArguments can output a constant containing a
78+
* HotspotJavaType when a static argument of type Class if loaded lazily in pull
79+
* mode. In this case, the type has to be converted back to a Class, as it would
80+
* cause a hotspot value to be reachable otherwise.
81+
*
82+
* If the constant contains an UnresolvedJavaType, it cannot be converted as a
83+
* Class. It is not a problem for this type to be reachable, so those constants can
84+
* be handled later.
85+
*/
86+
return snippetReflection.forObject(OriginalClassProvider.getJavaClass(resolvedJavaType));
87+
}
88+
}
89+
return constant;
6890
}
6991

7092
/**

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/AnalysisGraphBuilderPhase.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
import jdk.vm.ci.meta.ResolvedJavaField;
8383
import jdk.vm.ci.meta.ResolvedJavaMethod;
8484
import jdk.vm.ci.meta.ResolvedJavaType;
85+
import jdk.vm.ci.meta.UnresolvedJavaType;
8586

8687
public class AnalysisGraphBuilderPhase extends SharedGraphBuilderPhase {
8788

@@ -174,6 +175,16 @@ protected void genInvokeDynamic(int cpi, int opcode) {
174175
JavaConstant type = ((ImageHeapInstance) bootstrap.getType()).getHostedObject();
175176
MethodType methodType = (MethodType) ((DirectSubstrateObjectConstant) type).getObject();
176177

178+
for (JavaConstant argument : staticArgumentsList) {
179+
if (argument instanceof ImageHeapInstance imageHeapInstance) {
180+
Object arg = ((DirectSubstrateObjectConstant) imageHeapInstance.getHostedObject()).getObject();
181+
if (arg instanceof UnresolvedJavaType unresolvedJavaType) {
182+
handleUnresolvedType(unresolvedJavaType);
183+
return;
184+
}
185+
}
186+
}
187+
177188
if (!bootstrapMethodHandler.checkBootstrapParameters(bootstrap.getMethod(), staticArgumentsList, false)) {
178189
WrongMethodTypeException cause = new WrongMethodTypeException("Cannot convert " + methodType + " to correct MethodType");
179190
replaceWithThrowingAtRuntime(this, new BootstrapMethodError("Bootstrap method initialization exception", cause));
@@ -186,6 +197,10 @@ protected void genInvokeDynamic(int cpi, int opcode) {
186197
*/
187198

188199
Object initializedCallSite = bootstrapMethodHandler.resolveLinkedObject(bci, cpi, opcode, bootstrap, parameterLength, staticArgumentsList, isVarargs, false);
200+
if (initializedCallSite instanceof UnresolvedJavaType unresolvedJavaType) {
201+
handleUnresolvedType(unresolvedJavaType);
202+
return;
203+
}
189204
if (initializedCallSite instanceof Throwable) {
190205
return;
191206
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/SharedGraphBuilderPhase.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@
141141
import jdk.vm.ci.meta.ResolvedJavaField;
142142
import jdk.vm.ci.meta.ResolvedJavaMethod;
143143
import jdk.vm.ci.meta.ResolvedJavaType;
144+
import jdk.vm.ci.meta.UnresolvedJavaType;
144145

145146
public abstract class SharedGraphBuilderPhase extends GraphBuilderPhase.Instance {
146147

@@ -915,6 +916,15 @@ private Object loadConstantDynamic(int cpi, int opcode) {
915916
DynamicHub typeClass = (DynamicHub) ((DirectSubstrateObjectConstant) type).getObject();
916917
boolean isPrimitive = typeClass.isPrimitive();
917918

919+
for (JavaConstant argument : staticArguments) {
920+
if (argument instanceof ImageHeapInstance imageHeapInstance) {
921+
Object arg = ((DirectSubstrateObjectConstant) imageHeapInstance.getHostedObject()).getObject();
922+
if (arg instanceof UnresolvedJavaType) {
923+
return arg;
924+
}
925+
}
926+
}
927+
918928
if (isBootstrapInvocationInvalid(bootstrap, parameterLength, staticArguments, isVarargs, typeClass.getHostedJavaClass())) {
919929
/*
920930
* The number of provided arguments does not match the signature of the
@@ -1007,7 +1017,7 @@ protected Object resolveLinkedObject(int bci, int cpi, int opcode, BootstrapMeth
10071017
Object argConstant = loadConstantDynamic(argCpi, opcode == Opcodes.INVOKEDYNAMIC ? Opcodes.LDC : opcode);
10081018
if (argConstant instanceof ValueNode valueNode) {
10091019
currentNode = valueNode;
1010-
} else if (argConstant instanceof Throwable) {
1020+
} else if (argConstant instanceof Throwable || argConstant instanceof UnresolvedJavaType) {
10111021
/* A nested constant dynamic threw. */
10121022
return argConstant;
10131023
} else {

0 commit comments

Comments
 (0)