Skip to content

Commit ccb2743

Browse files
teshullpeter-hofer
authored andcommitted
More eagerly clear exception object frame states.
1 parent 7e8431b commit ccb2743

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/java/BytecodeParser.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,6 +1338,16 @@ protected void handleUnresolvedInvoke(JavaMethod javaMethod, InvokeKind invokeKi
13381338
deopt.updateNodeSourcePosition(() -> createBytecodePosition());
13391339
}
13401340

1341+
protected FrameStateBuilder createFrameStateForExceptionHandling(@SuppressWarnings("unused") int bci) {
1342+
FrameStateBuilder dispatchState = frameState.copy();
1343+
dispatchState.clearStack();
1344+
return dispatchState;
1345+
}
1346+
1347+
protected void clearNonLiveLocals(FrameStateBuilder state, BciBlock block, boolean liveIn) {
1348+
state.clearNonLiveLocals(block, liveness, liveIn);
1349+
}
1350+
13411351
/**
13421352
* @return the entry point to exception dispatch
13431353
*/
@@ -1346,8 +1356,7 @@ protected AbstractBeginNode handleException(ValueNode exceptionObject, int bci,
13461356
assert bci == BytecodeFrame.BEFORE_BCI || bci == bci() : "invalid bci";
13471357
debug.log("Creating exception dispatch edges at %d, exception object=%s, exception seen=%s", bci, exceptionObject, (profilingInfo == null ? "" : profilingInfo.getExceptionSeen(bci)));
13481358

1349-
FrameStateBuilder dispatchState = frameState.copy();
1350-
dispatchState.clearStack();
1359+
FrameStateBuilder dispatchState = createFrameStateForExceptionHandling(bci);
13511360

13521361
AbstractBeginNode dispatchBegin;
13531362
if (exceptionObject == null) {
@@ -1374,13 +1383,20 @@ protected AbstractBeginNode handleException(ValueNode exceptionObject, int bci,
13741383
return dispatchBegin;
13751384
}
13761385

1377-
protected void createHandleExceptionTarget(FixedWithNextNode afterExceptionLoaded, int bci, FrameStateBuilder dispatchState) {
1386+
private void createHandleExceptionTarget(FixedWithNextNode afterExceptionLoaded, int bci, FrameStateBuilder dispatchState) {
13781387
FixedWithNextNode afterInstrumentation = afterExceptionLoaded;
13791388
for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
13801389
afterInstrumentation = plugin.instrumentExceptionDispatch(graph, afterInstrumentation, () -> dispatchState.create(bci, getNonIntrinsicAncestor(), false, null, null));
13811390
assert afterInstrumentation.next() == null : "exception dispatch instrumentation will be linked to dispatch block";
13821391
}
13831392

1393+
BciBlock dispatchBlock = getDispatchBlock(bci);
1394+
1395+
FixedNode target = createTarget(dispatchBlock, dispatchState);
1396+
afterInstrumentation.setNext(target);
1397+
}
1398+
1399+
protected BciBlock getDispatchBlock(int bci) {
13841400
BciBlock dispatchBlock = currentBlock.exceptionDispatchBlock();
13851401
/*
13861402
* The exception dispatch block is always for the last bytecode of a block, so if we are not
@@ -1391,8 +1407,7 @@ protected void createHandleExceptionTarget(FixedWithNextNode afterExceptionLoade
13911407
dispatchBlock = blockMap.getUnwindBlock();
13921408
}
13931409

1394-
FixedNode target = createTarget(dispatchBlock, dispatchState);
1395-
afterInstrumentation.setNext(target);
1410+
return dispatchBlock;
13961411
}
13971412

13981413
protected ValueNode genLoadIndexed(ValueNode array, ValueNode index, GuardingNode boundsCheck, JavaKind kind) {

compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/java/FrameStateBuilder.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,9 @@ public boolean contains(ValueNode value) {
729729
return false;
730730
}
731731

732+
/**
733+
* @param liveIn true if live in, false if live out
734+
*/
732735
public void clearNonLiveLocals(BciBlock block, LocalLiveness liveness, boolean liveIn) {
733736
/*
734737
* Non-live local clearing is mandatory for the entry block of an OSR compilation so that

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
package com.oracle.svm.hosted.phases;
2626

2727
import org.graalvm.compiler.core.common.BootstrapMethodIntrospection;
28+
import org.graalvm.compiler.java.BciBlockMapping;
2829
import org.graalvm.compiler.java.BytecodeParser;
30+
import org.graalvm.compiler.java.FrameStateBuilder;
2931
import org.graalvm.compiler.java.GraphBuilderPhase;
3032
import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
3133
import org.graalvm.compiler.nodes.StructuredGraph;
@@ -43,6 +45,7 @@
4345
import com.oracle.graal.pointsto.meta.AnalysisMethod;
4446
import com.oracle.svm.core.SubstrateOptions;
4547
import com.oracle.svm.hosted.SVMHost;
48+
import com.oracle.svm.hosted.code.SubstrateCompilationDirectives;
4649
import com.oracle.svm.util.ModuleSupport;
4750

4851
import jdk.vm.ci.meta.JavaKind;
@@ -144,5 +147,24 @@ protected void genStoreField(ValueNode receiver, ResolvedJavaField field, ValueN
144147
hostVM.recordFieldStore(field, method);
145148
super.genStoreField(receiver, field, value);
146149
}
150+
151+
@Override
152+
protected FrameStateBuilder createFrameStateForExceptionHandling(int bci) {
153+
var dispatchState = super.createFrameStateForExceptionHandling(bci);
154+
if (SubstrateOptions.parseOnce()) {
155+
/*
156+
* It is beneficial to eagerly clear all non-live locals on the exception object
157+
* before entering the dispatch target. This helps us prune unneeded values from the
158+
* graph, which can positively impact our analysis. Since deoptimization is not
159+
* possible, then there is no risk in clearing the unneeded locals.
160+
*/
161+
AnalysisMethod aMethod = (AnalysisMethod) method;
162+
if (aMethod.isOriginalMethod() && !SubstrateCompilationDirectives.singleton().isRegisteredForDeoptTesting(aMethod)) {
163+
BciBlockMapping.BciBlock dispatchBlock = getDispatchBlock(bci);
164+
clearNonLiveLocals(dispatchState, dispatchBlock, true);
165+
}
166+
}
167+
return dispatchState;
168+
}
147169
}
148170
}

0 commit comments

Comments
 (0)