Skip to content

Commit

Permalink
[GR-40795] Insert deopt entries conditionally in PodFactorySubstituti…
Browse files Browse the repository at this point in the history
…onMethod.

PullRequest: graal/12576
  • Loading branch information
teshull committed Sep 3, 2022
2 parents 2abdd96 + 9157572 commit cd05e7b
Showing 1 changed file with 54 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@
import com.oracle.svm.core.graal.nodes.TestDeoptimizeNode;
import com.oracle.svm.core.heap.Pod;
import com.oracle.svm.core.heap.Pod.RuntimeSupport.PodFactory;
import com.oracle.svm.core.meta.SharedMethod;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.hosted.annotation.CustomSubstitutionMethod;
import com.oracle.svm.hosted.code.CompilationInfo;
import com.oracle.svm.hosted.meta.HostedMethod;
import com.oracle.svm.hosted.nodes.DeoptProxyNode;
import com.oracle.svm.hosted.phases.HostedGraphKit;
import com.oracle.svm.util.GuardedAnnotationAccess;
Expand Down Expand Up @@ -110,7 +112,10 @@ public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method,
boolean trackNodeSourcePosition = (purpose == Purpose.ANALYSIS);

HostedGraphKit kit = new HostedGraphKit(debug, providers, method, trackNodeSourcePosition);
boolean isDeoptTarget = (method instanceof SharedMethod) && ((SharedMethod) method).isDeoptTarget();
CompilationInfo deoptTargetInfo = null;
if ((method instanceof HostedMethod) && ((HostedMethod) method).isDeoptTarget()) {
deoptTargetInfo = ((HostedMethod) method).compilationInfo;
}

ResolvedJavaType factoryType = method.getDeclaringClass();
PodFactory annotation = factoryType.getAnnotation(PodFactory.class);
Expand All @@ -123,12 +128,12 @@ public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method,
* allocated instance in a local and load it after each step during which a deopt can occur.
*/
int instanceLocal = kit.getFrameState().localsSize() - 1; // reserved when generating class
int nextDeoptIndex = startMethod(kit, isDeoptTarget, 0);
int nextDeoptIndex = startMethod(kit, deoptTargetInfo, 0);
instantiatePod(kit, providers, factoryType, podConcreteType, instanceLocal);
if (isAnnotationPresent(DeoptTest.class)) {
kit.append(new TestDeoptimizeNode());
}
nextDeoptIndex = invokeConstructor(kit, method, isDeoptTarget, nextDeoptIndex, targetCtor, instanceLocal);
nextDeoptIndex = invokeConstructor(kit, method, deoptTargetInfo, nextDeoptIndex, targetCtor, instanceLocal);

kit.createReturn(kit.loadLocal(instanceLocal, JavaKind.Object), JavaKind.Object);
return kit.finalizeGraph();
Expand All @@ -149,12 +154,21 @@ private ResolvedJavaMethod findMatchingConstructor(ResolvedJavaMethod method, Re
throw new GraalError("Matching constructor not found: %s", getSignature());
}

private static int startMethod(HostedGraphKit kit, boolean isDeoptTarget, int nextDeoptIndex) {
if (!isDeoptTarget) {
return nextDeoptIndex;
private static boolean shouldInsertDeoptEntry(CompilationInfo deoptTargetInfo, int bci, boolean duringCall, boolean rethrowException) {
if (deoptTargetInfo != null) {
return deoptTargetInfo.isDeoptEntry(bci, duringCall, rethrowException);
}
return false;
}

private static int startMethod(HostedGraphKit kit, CompilationInfo deoptTargetInfo, int nextDeoptIndex) {
if (deoptTargetInfo != null) {
FrameState initialState = kit.getGraph().start().stateAfter();
if (shouldInsertDeoptEntry(deoptTargetInfo, initialState.bci, false, false)) {
return appendDeoptWithExceptionUnwind(kit, initialState, initialState.bci, nextDeoptIndex);
}
}
FrameState initialState = kit.getGraph().start().stateAfter();
return appendDeoptWithExceptionUnwind(kit, initialState, initialState.bci, nextDeoptIndex);
return nextDeoptIndex;
}

private static void instantiatePod(HostedGraphKit kit, HostedProviders providers, ResolvedJavaType factoryType, ResolvedJavaType podConcreteType, int instanceLocal) {
Expand All @@ -172,50 +186,59 @@ private static ValueNode loadNonNullField(HostedGraphKit kit, ValueNode object,
return kit.append(PiNode.create(kit.createLoadField(object, field), StampFactory.objectNonNull()));
}

private static int invokeConstructor(HostedGraphKit kit, ResolvedJavaMethod method, boolean isDeoptTarget, int nextDeoptIndex, ResolvedJavaMethod targetCtor, int instanceLocal) {
private static int invokeConstructor(HostedGraphKit kit, ResolvedJavaMethod method, CompilationInfo deoptTargetInfo, int nextDeoptIndex, ResolvedJavaMethod targetCtor, int instanceLocal) {
ValueNode instance = kit.loadLocal(instanceLocal, JavaKind.Object);
ValueNode[] originalArgs = kit.loadArguments(method.toParameterTypes()).toArray(ValueNode.EMPTY_ARRAY);
ValueNode[] invokeArgs = Arrays.copyOf(originalArgs, originalArgs.length);
invokeArgs[0] = instance;
return invokeWithDeoptAndExceptionUnwind(kit, isDeoptTarget, nextDeoptIndex, targetCtor, InvokeKind.Special, invokeArgs);
return invokeWithDeoptAndExceptionUnwind(kit, deoptTargetInfo, nextDeoptIndex, targetCtor, InvokeKind.Special, invokeArgs);
}

/** @see com.oracle.svm.hosted.phases.HostedGraphBuilderPhase */
private static int invokeWithDeoptAndExceptionUnwind(HostedGraphKit kit, boolean isDeoptTarget, int initialNextDeoptIndex, ResolvedJavaMethod target, InvokeKind invokeKind, ValueNode... args) {
private static int invokeWithDeoptAndExceptionUnwind(HostedGraphKit kit, CompilationInfo deoptTargetInfo, int initialNextDeoptIndex, ResolvedJavaMethod target, InvokeKind invokeKind,
ValueNode... args) {
int bci = kit.bci();
InvokeWithExceptionNode invoke = kit.startInvokeWithException(target, invokeKind, kit.getFrameState(), bci, args);
invoke.setNodeSourcePosition(NodeSourcePosition.placeholder(kit.getGraph().method(), bci));
kit.exceptionPart();
ExceptionObjectNode exception = kit.exceptionObject();

if (!isDeoptTarget) {
if (deoptTargetInfo == null) {
kit.append(new UnwindNode(exception));
kit.endInvokeWithException();
return initialNextDeoptIndex;
}

int nextDeoptIndex = initialNextDeoptIndex;

// Exception during invoke

var exceptionDeopt = kit.add(new DeoptEntryNode());
exceptionDeopt.setStateAfter(exception.stateAfter().duplicate());
var exceptionDeoptBegin = kit.add(new DeoptEntryBeginNode());
int exceptionDeoptIndex = nextDeoptIndex++;
ValueNode exceptionProxy = createDeoptProxy(kit, exceptionDeoptIndex, exceptionDeopt, exception);
var unwind = kit.append(new UnwindNode(exceptionProxy));
exception.setNext(exceptionDeopt);
exceptionDeopt.setNext(exceptionDeoptBegin);
exceptionDeoptBegin.setNext(unwind);

var exceptionDeoptExceptionEdge = kit.add(new UnreachableBeginNode());
exceptionDeoptExceptionEdge.setNext(kit.add(new LoweredDeadEndNode()));
exceptionDeopt.setExceptionEdge(exceptionDeoptExceptionEdge);
if (shouldInsertDeoptEntry(deoptTargetInfo, bci, false, true)) {
// Exception during invoke

var exceptionDeopt = kit.add(new DeoptEntryNode());
exceptionDeopt.setStateAfter(exception.stateAfter().duplicate());
var exceptionDeoptBegin = kit.add(new DeoptEntryBeginNode());
int exceptionDeoptIndex = nextDeoptIndex++;
ValueNode exceptionProxy = createDeoptProxy(kit, exceptionDeoptIndex, exceptionDeopt, exception);
var unwind = kit.append(new UnwindNode(exceptionProxy));
exception.setNext(exceptionDeopt);
exceptionDeopt.setNext(exceptionDeoptBegin);
exceptionDeoptBegin.setNext(unwind);

var exceptionDeoptExceptionEdge = kit.add(new UnreachableBeginNode());
exceptionDeoptExceptionEdge.setNext(kit.add(new LoweredDeadEndNode()));
exceptionDeopt.setExceptionEdge(exceptionDeoptExceptionEdge);
} else {
kit.append(new UnwindNode(exception));
}

// Deopt entry after invoke without exception
if (shouldInsertDeoptEntry(deoptTargetInfo, invoke.stateAfter().bci, false, false)) {
// Deopt entry after invoke without exception

kit.noExceptionPart();
nextDeoptIndex = appendDeoptWithExceptionUnwind(kit, invoke.stateAfter(), invoke.stateAfter().bci, nextDeoptIndex);
kit.noExceptionPart();
nextDeoptIndex = appendDeoptWithExceptionUnwind(kit, invoke.stateAfter(), invoke.stateAfter().bci, nextDeoptIndex);
} else {
VMError.guarantee(!shouldInsertDeoptEntry(deoptTargetInfo, bci, true, false), "need to add support for inserting DeoptProxyAnchorNode");
}
kit.endInvokeWithException();

return nextDeoptIndex;
Expand Down

0 comments on commit cd05e7b

Please sign in to comment.