Skip to content

Commit 862b0eb

Browse files
committed
[GR-51913] [GR-54983] Fix deoptimization into an exception handler.
PullRequest: graal/17608
2 parents 29b24aa + 1214be6 commit 862b0eb

File tree

4 files changed

+31
-6
lines changed

4 files changed

+31
-6
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/FrameInfoDecoder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ protected static boolean decodeDuringCall(long encodedBci) {
545545
return (encodedBci & ENCODED_BCI_DURING_CALL_MASK) != 0;
546546
}
547547

548-
protected static boolean decodeRethrowException(long encodedBci) {
548+
public static boolean decodeRethrowException(long encodedBci) {
549549
assert encodedBci >= 0 && encodedBci != FrameInfoDecoder.ENCODED_BCI_NO_CALLER : encodedBci;
550550
return (encodedBci & ENCODED_BCI_RETHROW_EXCEPTION_MASK) != 0;
551551
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/deopt/DeoptimizationRuntime.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import com.oracle.svm.core.snippets.SnippetRuntime.SubstrateForeignCallDescriptor;
4444
import com.oracle.svm.core.snippets.SubstrateForeignCallTarget;
4545
import com.oracle.svm.core.stack.StackOverflowCheck;
46+
import com.oracle.svm.core.util.VMError;
4647

4748
import jdk.graal.compiler.graph.NodeSourcePosition;
4849
import jdk.vm.ci.meta.DeoptimizationAction;
@@ -83,6 +84,12 @@ private static void deoptimize(long actionAndReason, SpeculationReason speculati
8384
Log.log().string("]").newline();
8485
}
8586

87+
} catch (Throwable t) {
88+
/*
89+
* If an error was thrown during this deoptimization stage we likely will be in an
90+
* inconsistent state from which execution cannot proceed.
91+
*/
92+
throw VMError.shouldNotReachHere(t);
8693
} finally {
8794
StackOverflowCheck.singleton().protectYellowZone();
8895
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/deopt/DeoptimizedFrame.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import com.oracle.svm.core.meta.SubstrateObjectConstant;
4848
import com.oracle.svm.core.monitor.MonitorSupport;
4949

50+
import jdk.graal.compiler.nodes.FrameState;
5051
import jdk.vm.ci.code.InstalledCode;
5152
import jdk.vm.ci.meta.JavaConstant;
5253

@@ -267,9 +268,9 @@ static class RelockObjectData {
267268
}
268269

269270
protected static DeoptimizedFrame factory(int targetContentSize, long sourceEncodedFrameSize, SubstrateInstalledCode sourceInstalledCode, VirtualFrame topFrame,
270-
RelockObjectData[] relockedObjects, CodePointer sourcePC) {
271+
RelockObjectData[] relockedObjects, CodePointer sourcePC, boolean rethrowException) {
271272
final TargetContent targetContentBuffer = new TargetContent(targetContentSize, ConfigurationValues.getTarget().arch.getByteOrder());
272-
return new DeoptimizedFrame(sourceEncodedFrameSize, sourceInstalledCode, topFrame, targetContentBuffer, relockedObjects, sourcePC);
273+
return new DeoptimizedFrame(sourceEncodedFrameSize, sourceInstalledCode, topFrame, targetContentBuffer, relockedObjects, sourcePC, rethrowException);
273274
}
274275

275276
private final long sourceEncodedFrameSize;
@@ -280,9 +281,16 @@ protected static DeoptimizedFrame factory(int targetContentSize, long sourceEnco
280281
private final PinnedObject pin;
281282
private final CodePointer sourcePC;
282283
private final char[] completedMessage;
284+
/**
285+
* This flag indicates this DeoptimizedFrame corresponds to a state where
286+
* {@link FrameState#rethrowException()} is set. Within the execution, this marks a spot where
287+
* we have an exception and are now starting to walk the exceptions handlers to see if execution
288+
* should continue in a matching handler or unwind.
289+
*/
290+
private final boolean rethrowException;
283291

284292
private DeoptimizedFrame(long sourceEncodedFrameSize, SubstrateInstalledCode sourceInstalledCode, VirtualFrame topFrame, Deoptimizer.TargetContent targetContent,
285-
RelockObjectData[] relockedObjects, CodePointer sourcePC) {
293+
RelockObjectData[] relockedObjects, CodePointer sourcePC, boolean rethrowException) {
286294
this.sourceEncodedFrameSize = sourceEncodedFrameSize;
287295
this.topFrame = topFrame;
288296
this.targetContent = targetContent;
@@ -293,6 +301,7 @@ private DeoptimizedFrame(long sourceEncodedFrameSize, SubstrateInstalledCode sou
293301
StringBuilderLog sbl = new StringBuilderLog();
294302
sbl.string("deoptStub: completed for DeoptimizedFrame at ").hex(pin.addressOfObject()).newline();
295303
this.completedMessage = sbl.getResult().toCharArray();
304+
this.rethrowException = rethrowException;
296305
}
297306

298307
/**
@@ -393,6 +402,13 @@ protected void buildContent(Pointer newSp) {
393402
* the deoptimization target.
394403
*/
395404
public void takeException() {
405+
if (rethrowException) {
406+
/*
407+
* This frame already corresponds to the start of an execution handler walk. Nothing
408+
* needs to be done.
409+
*/
410+
return;
411+
}
396412
ReturnAddress firstAddressEntry = topFrame.returnAddress;
397413
CodePointer ip = WordFactory.pointer(firstAddressEntry.returnAddress);
398414
CodeInfo info = CodeInfoTable.getImageCodeInfo(ip);

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/deopt/Deoptimizer.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@ private DeoptimizedFrame deoptSourceFrameOperation(CodePointer pc, boolean ignor
711711
return existing;
712712
}
713713

714-
FrameInfoQueryResult frameInfo = sourceChunk.getFrameInfo();
714+
final FrameInfoQueryResult frameInfo = sourceChunk.getFrameInfo();
715715
if (frameInfo == null) {
716716
if (ignoreNonDeoptimizable) {
717717
return null;
@@ -773,8 +773,10 @@ private DeoptimizedFrame deoptSourceFrameOperation(CodePointer pc, boolean ignor
773773
}
774774

775775
RelockObjectData[] relockObjectData = relockedObjects == null ? null : relockedObjects.toArray(new RelockObjectData[relockedObjects.size()]);
776+
boolean rethrowException = FrameInfoDecoder.decodeRethrowException(frameInfo.getEncodedBci());
776777
/* Allocate a buffer to hold the contents of the new target frame. */
777-
DeoptimizedFrame deoptimizedFrame = DeoptimizedFrame.factory(targetContentSize, sourceChunk.getEncodedFrameSize(), CodeInfoTable.lookupInstalledCode(pc), topFrame, relockObjectData, pc);
778+
DeoptimizedFrame deoptimizedFrame = DeoptimizedFrame.factory(targetContentSize, sourceChunk.getEncodedFrameSize(), CodeInfoTable.lookupInstalledCode(pc), topFrame, relockObjectData, pc,
779+
rethrowException);
778780

779781
installDeoptimizedFrame(deoptimizedFrame);
780782

0 commit comments

Comments
 (0)