Skip to content

Commit

Permalink
Handle HotSpotJavaType returned by BootstrapMethodInvocation.getStati…
Browse files Browse the repository at this point in the history
…cArguments
  • Loading branch information
Zeavee committed Dec 6, 2023
1 parent 1c47569 commit a32f26f
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@
import java.util.stream.Collectors;

import com.oracle.graal.pointsto.constraints.UnresolvedElementException;
import com.oracle.graal.pointsto.util.GraalAccess;
import com.oracle.svm.util.ReflectionUtil;

import jdk.graal.compiler.api.replacements.SnippetReflectionProvider;
import jdk.graal.compiler.core.common.BootstrapMethodIntrospection;
import jdk.graal.compiler.debug.GraalError;
import jdk.graal.compiler.serviceprovider.BootstrapMethodIntrospectionImpl;
Expand Down Expand Up @@ -64,7 +66,27 @@ public int length() {
}

private JavaConstant lookupConstant(JavaConstant constant) {
return universe.lookup(constant);
return universe.lookup(extractResolvedType(constant));
}

public JavaConstant extractResolvedType(JavaConstant constant) {
if (constant != null && constant.getJavaKind().isObject() && !constant.isNull()) {
SnippetReflectionProvider snippetReflection = GraalAccess.getOriginalSnippetReflection();
if (snippetReflection.asObject(Object.class, constant) instanceof ResolvedJavaType resolvedJavaType) {
/*
* BootstrapMethodInvocation.getStaticArguments can output a constant containing a
* HotspotJavaType when a static argument of type Class if loaded lazily in pull
* mode. In this case, the type has to be converted back to a Class, as it would
* cause a hotspot value to be reachable otherwise.
*
* If the constant contains an UnresolvedJavaType, it cannot be converted as a
* Class. It is not a problem for this type to be reachable, so those constants can
* be handled later.
*/
return snippetReflection.forObject(OriginalClassProvider.getJavaClass(resolvedJavaType));
}
}
return constant;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.UnresolvedJavaType;

public class AnalysisGraphBuilderPhase extends SharedGraphBuilderPhase {

Expand Down Expand Up @@ -175,6 +176,16 @@ protected void genInvokeDynamic(int cpi, int opcode) {
JavaConstant type = ((ImageHeapInstance) bootstrap.getType()).getHostedObject();
MethodType methodType = (MethodType) ((DirectSubstrateObjectConstant) type).getObject();

for (JavaConstant argument : staticArgumentsList) {
if (argument instanceof ImageHeapInstance imageHeapInstance) {
Object arg = ((DirectSubstrateObjectConstant) imageHeapInstance.getHostedObject()).getObject();
if (arg instanceof UnresolvedJavaType unresolvedJavaType) {
handleUnresolvedType(unresolvedJavaType);
return;
}
}
}

if (!bootstrapMethodHandler.checkBootstrapParameters(bootstrap.getMethod(), staticArgumentsList, false)) {
WrongMethodTypeException cause = new WrongMethodTypeException("Cannot convert " + methodType + " to correct MethodType");
replaceWithThrowingAtRuntime(this, new BootstrapMethodError("Bootstrap method initialization exception", cause));
Expand All @@ -187,6 +198,10 @@ protected void genInvokeDynamic(int cpi, int opcode) {
*/

Object initializedCallSite = bootstrapMethodHandler.resolveLinkedObject(bci, cpi, opcode, bootstrap, parameterLength, staticArgumentsList, isVarargs, false);
if (initializedCallSite instanceof UnresolvedJavaType unresolvedJavaType) {
handleUnresolvedType(unresolvedJavaType);
return;
}
if (initializedCallSite instanceof Throwable) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.UnresolvedJavaType;

public abstract class SharedGraphBuilderPhase extends GraphBuilderPhase.Instance {
final WordTypes wordTypes;
Expand Down Expand Up @@ -923,6 +924,15 @@ private Object loadConstantDynamic(int cpi, int opcode) {
DynamicHub typeClass = (DynamicHub) ((DirectSubstrateObjectConstant) type).getObject();
boolean isPrimitive = typeClass.isPrimitive();

for (JavaConstant argument : staticArguments) {
if (argument instanceof ImageHeapInstance imageHeapInstance) {
Object arg = ((DirectSubstrateObjectConstant) imageHeapInstance.getHostedObject()).getObject();
if (arg instanceof UnresolvedJavaType) {
return arg;
}
}
}

if (isBootstrapInvocationInvalid(bootstrap, parameterLength, staticArguments, isVarargs, typeClass.getHostedJavaClass())) {
/*
* The number of provided arguments does not match the signature of the
Expand Down Expand Up @@ -1015,7 +1025,7 @@ protected Object resolveLinkedObject(int bci, int cpi, int opcode, BootstrapMeth
Object argConstant = loadConstantDynamic(argCpi, opcode == Opcodes.INVOKEDYNAMIC ? Opcodes.LDC : opcode);
if (argConstant instanceof ValueNode valueNode) {
currentNode = valueNode;
} else if (argConstant instanceof Throwable) {
} else if (argConstant instanceof Throwable || argConstant instanceof UnresolvedJavaType) {
/* A nested constant dynamic threw. */
return argConstant;
} else {
Expand Down

0 comments on commit a32f26f

Please sign in to comment.