Skip to content

Commit acac8d8

Browse files
committed
[GR-64124] [GR-64563] Implement Bytecode OSR batch polling; Fixes and improvements to the bytecode loop in bc DSL; Improvements to SL.
PullRequest: graal/20655
2 parents 544de6e + 8e93662 commit acac8d8

File tree

24 files changed

+825
-441
lines changed

24 files changed

+825
-441
lines changed

compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/truffle/test/BytecodeOSRNodeTest.java

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ public Object execute(VirtualFrame frame) {
816816
// must never happen
817817
return 41;
818818
}
819-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
819+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
820820
Object result = BytecodeOSRNode.tryOSR(this, DEFAULT_TARGET, null, null, frame);
821821
if (result != null) {
822822
return result;
@@ -864,7 +864,7 @@ protected Object executeLoop(VirtualFrame frame, int numIterations) {
864864
loopIterations++;
865865
frame.setInt(indexSlot, i);
866866
if (i + 1 < numIterations) { // back-edge will be taken
867-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
867+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
868868
Object result = BytecodeOSRNode.tryOSR(this, DEFAULT_TARGET, null, null, frame);
869869
if (result != null) {
870870
return result;
@@ -897,7 +897,7 @@ protected Object executeLoop(VirtualFrame frame, int numIterations) {
897897
for (int i = frame.getInt(indexSlot); i < numIterations; i++) {
898898
frame.setInt(indexSlot, i);
899899
if (i + 1 < numIterations) { // back-edge will be taken
900-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
900+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
901901
Object result = BytecodeOSRNode.tryOSR(this, DEFAULT_TARGET, null, null, frame);
902902
if (result != null) {
903903
return OSR_IN_FIRST_LOOP;
@@ -908,7 +908,7 @@ protected Object executeLoop(VirtualFrame frame, int numIterations) {
908908
for (int i = frame.getInt(indexSlot); i < 2 * numIterations; i++) {
909909
frame.setInt(indexSlot, i);
910910
if (i + 1 < 2 * numIterations) { // back-edge will be taken
911-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
911+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
912912
Object result = BytecodeOSRNode.tryOSR(this, DEFAULT_TARGET, null, null, frame);
913913
if (result != null) {
914914
return OSR_IN_SECOND_LOOP;
@@ -977,7 +977,7 @@ protected Object executeLoop(VirtualFrame frame, int numIterations, boolean sele
977977
int partial = frame.getInt(localSlot);
978978
frame.setInt(localSlot, i + partial);
979979
if (i + 1 < numIterations) { // back-edge will be taken
980-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
980+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
981981
Object result = BytecodeOSRNode.tryOSR(this, FIRST_LOOP_TARGET, null, null, frame);
982982
if (result != null) {
983983
return OSR_IN_FIRST_LOOP;
@@ -991,7 +991,7 @@ protected Object executeLoop(VirtualFrame frame, int numIterations, boolean sele
991991
double partial = frame.getDouble(localSlot);
992992
frame.setDouble(localSlot, i + partial);
993993
if (i + 1 < numIterations) { // back-edge will be taken
994-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
994+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
995995
Object result = BytecodeOSRNode.tryOSR(this, SECOND_LOOP_TARGET, null, null, frame);
996996
if (result != null) {
997997
return OSR_IN_SECOND_LOOP;
@@ -1018,7 +1018,7 @@ protected Object executeLoop(VirtualFrame frame, int numIterations) {
10181018
for (int i = 0; i < numIterations; i++) {
10191019
CompilerAsserts.neverPartOfCompilation();
10201020
if (i + 1 < numIterations) { // back-edge will be taken
1021-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
1021+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
10221022
Object result = BytecodeOSRNode.tryOSR(this, DEFAULT_TARGET, null, null, frame);
10231023
if (result != null) {
10241024
return result;
@@ -1045,7 +1045,7 @@ protected Object executeLoop(VirtualFrame frame, int numIterations) {
10451045
for (int i = frame.getInt(indexSlot); i < numIterations; i++) {
10461046
frame.setInt(indexSlot, i);
10471047
if (i + 1 < numIterations) { // back-edge will be taken
1048-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
1048+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
10491049
Object result = BytecodeOSRNode.tryOSR(this, DEFAULT_TARGET, null, null, frame);
10501050
if (result != null) {
10511051
return result;
@@ -1125,7 +1125,7 @@ protected Object executeLoop(VirtualFrame frame, int foo, int bar) {
11251125
if (CompilerDirectives.inCompiledCode()) {
11261126
return foo + bar;
11271127
}
1128-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
1128+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
11291129
Object result = BytecodeOSRNode.tryOSR(this, DEFAULT_TARGET, new InterpreterState(2 * foo, 2 * bar), null, frame);
11301130
if (result != null) {
11311131
return result;
@@ -1151,7 +1151,7 @@ public Object execute(VirtualFrame frame) {
11511151
if (CompilerDirectives.inCompiledCode()) {
11521152
return 42;
11531153
}
1154-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
1154+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
11551155
Object result = BytecodeOSRNode.tryOSR(this, DEFAULT_TARGET, null, () -> {
11561156
callbackInvoked = true;
11571157
}, frame);
@@ -1175,7 +1175,7 @@ protected Object executeLoop(VirtualFrame frame, int numIterations) {
11751175
frame.setInt(indexSlot, i);
11761176
checkStackTrace(i);
11771177
if (i + 1 < numIterations) { // back-edge will be taken
1178-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
1178+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
11791179
Object result = BytecodeOSRNode.tryOSR(this, DEFAULT_TARGET, null, null, frame);
11801180
if (result != null) {
11811181
return result;
@@ -1294,7 +1294,7 @@ protected Object executeLoop(VirtualFrame frame, int numIterations) {
12941294
frame.setInt(indexSlot, i);
12951295
checkCallerFrame();
12961296
if (i + 1 < numIterations) { // back-edge will be taken
1297-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
1297+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
12981298
Object result = BytecodeOSRNode.tryOSR(this, DEFAULT_TARGET, null, null, frame);
12991299
if (result != null) {
13001300
return result;
@@ -1345,7 +1345,7 @@ public Object execute(VirtualFrame frame) {
13451345
if (CompilerDirectives.inCompiledCode()) {
13461346
return 42;
13471347
}
1348-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
1348+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
13491349
Object result = BytecodeOSRNode.tryOSR(this, DEFAULT_TARGET, null, null, frame);
13501350
if (result != null) {
13511351
return result;
@@ -1424,7 +1424,7 @@ public Object execute(VirtualFrame frame) {
14241424
public Object executeLoop(VirtualFrame frame) {
14251425
// This node only terminates in compiled code.
14261426
while (true) {
1427-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
1427+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
14281428
Object result = BytecodeOSRNode.tryOSR(this, DEFAULT_TARGET, null, null, frame);
14291429
if (result != null) {
14301430
checkOSRState(frame);
@@ -1539,7 +1539,7 @@ public Object execute(VirtualFrame frame) {
15391539
public Object executeLoop(VirtualFrame frame) {
15401540
// This node only terminates in compiled code.
15411541
while (true) {
1542-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
1542+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
15431543
Object result = BytecodeOSRNode.tryOSR(this, DEFAULT_TARGET, null, null, frame);
15441544
if (result != null) {
15451545
checkOSRState(frame);
@@ -1840,7 +1840,7 @@ Object doExecute(VirtualFrame frame) {
18401840
if (CompilerDirectives.inCompiledCode()) {
18411841
CompilerDirectives.transferToInterpreterAndInvalidate();
18421842
}
1843-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
1843+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
18441844
Object result = BytecodeOSRNode.tryOSR(this, DEFAULT_TARGET, null, null, frame);
18451845
if (result != null) {
18461846
return result;
@@ -1951,7 +1951,7 @@ public Object executeFromBCI(VirtualFrame frame, int startBCI) {
19511951
if (value != 0) {
19521952
int target = bci + bytecodes[bci + 2];
19531953
if (target < bci) { // back-edge
1954-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
1954+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
19551955
Object result = BytecodeOSRNode.tryOSR(this, target, null, null, frame);
19561956
if (result != null) {
19571957
return result;
@@ -2049,7 +2049,7 @@ protected Object executeLoop(VirtualFrame frame, int numIterations) {
20492049
loopIterations++;
20502050
frame.setInt(indexSlot, i);
20512051
if (i + 1 < numIterations) { // back-edge will be taken
2052-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
2052+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
20532053
Object result = BytecodeOSRNode.tryOSR(this, DEFAULT_TARGET, null, null, frame);
20542054
if (result != null) {
20552055
return result;
@@ -2135,7 +2135,7 @@ protected Object executeLoop(VirtualFrame frame, long target) {
21352135
try {
21362136
for (int i = (int) target; i < numIterations; i++) {
21372137
if (i + 1 < numIterations) { // back-edge will be taken
2138-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
2138+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
21392139
long osrState = (target & 0xFFFFFFFF00000000L) | (i & 0xFFFFFFFFL);
21402140
Object result = BytecodeOSRNode.tryOSR(this, osrState, null, null, frame);
21412141
if (result != null) {
@@ -2170,7 +2170,7 @@ protected Object executeLoop(VirtualFrame frame, long target) {
21702170
try {
21712171
for (int i = (int) target; i < numIterations; i++) {
21722172
if (i + 1 < numIterations) { // back-edge will be taken
2173-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
2173+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
21742174
Object result = BytecodeOSRNode.tryOSR(this, i, null, null, frame);
21752175
if (result != null) {
21762176
return result;
@@ -2213,7 +2213,7 @@ public Object executeLoop(VirtualFrame frame, long target) {
22132213
try {
22142214
for (long i = target; i < numIterations; i++) {
22152215
if (i + 1 < numIterations) { // back-edge will be taken
2216-
if (BytecodeOSRNode.pollOSRBackEdge(this)) {
2216+
if (BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
22172217
Object result = BytecodeOSRNode.tryOSR(this, i, null, null, frame);
22182218
if (result != null) {
22192219
return result;

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2015,24 +2015,24 @@ private int beforeJumpChecks(VirtualFrame frame, int curBCI, int targetBCI, int
20152015
TruffleSafepoint.poll(this);
20162016
if (CompilerDirectives.hasNextTier() && ++loopCount.value >= REPORT_LOOP_STRIDE) {
20172017
LoopNode.reportLoopCount(this, REPORT_LOOP_STRIDE);
2018-
loopCount.value = 0;
2019-
}
2020-
if (CompilerDirectives.inInterpreter() && BytecodeOSRNode.pollOSRBackEdge(this)) {
2021-
livenessAnalysis.catchUpOSR(frame, targetBCI, skipLivenessActions);
2022-
Object osrResult;
2023-
StoredWrapperNode storedWrapperNode = null;
2024-
try {
2025-
storedWrapperNode = storeWrapperNodeIfSet(frame, instrument);
2026-
osrResult = BytecodeOSRNode.tryOSR(this, targetBCI, new EspressoOSRInterpreterState(top, nextStatementIndex), null, frame);
2027-
} catch (Throwable any) {
2028-
// Has already been guest-handled in OSR. Shortcut out of the method.
2029-
throw new EspressoOSRReturnException(any);
2030-
} finally {
2031-
restoreWrapperNode(frame, storedWrapperNode, instrument);
2032-
}
2033-
if (osrResult != null) {
2034-
throw new EspressoOSRReturnException(osrResult);
2018+
if (CompilerDirectives.inInterpreter() && BytecodeOSRNode.pollOSRBackEdge(this, REPORT_LOOP_STRIDE)) {
2019+
livenessAnalysis.catchUpOSR(frame, targetBCI, skipLivenessActions);
2020+
Object osrResult;
2021+
StoredWrapperNode storedWrapperNode = null;
2022+
try {
2023+
storedWrapperNode = storeWrapperNodeIfSet(frame, instrument);
2024+
osrResult = BytecodeOSRNode.tryOSR(this, targetBCI, new EspressoOSRInterpreterState(top, nextStatementIndex), null, frame);
2025+
} catch (Throwable any) {
2026+
// Has already been guest-handled in OSR. Shortcut out of the method.
2027+
throw new EspressoOSRReturnException(any);
2028+
} finally {
2029+
restoreWrapperNode(frame, storedWrapperNode, instrument);
2030+
}
2031+
if (osrResult != null) {
2032+
throw new EspressoOSRReturnException(osrResult);
2033+
}
20352034
}
2035+
loopCount.value = 0;
20362036
}
20372037
}
20382038
livenessAnalysis.performOnEdge(frame, curBCI, targetBCI, skipLivenessActions);

sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/nodes/control/LLVMDispatchBasicBlockNode.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2023, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2025, Oracle and/or its affiliates.
33
*
44
* All rights reserved.
55
*
@@ -100,7 +100,7 @@ private Object dispatchFromBasicBlock(VirtualFrame frame, int bci, Counters coun
100100
if (basicBlockIndex <= counters.previousBasicBlockIndex) {
101101
TruffleSafepoint.poll(this);
102102
counters.backEdgeCounter++;
103-
if (CompilerDirectives.inInterpreter() && osrMode == SulongEngineOption.OSRMode.BYTECODE && BytecodeOSRNode.pollOSRBackEdge(this)) {
103+
if (CompilerDirectives.inInterpreter() && osrMode == SulongEngineOption.OSRMode.BYTECODE && BytecodeOSRNode.pollOSRBackEdge(this, 1)) {
104104
ensureAllFrameSlotsInitialized(frame);
105105
returnValue = BytecodeOSRNode.tryOSR(this, basicBlockIndex, counters, null, frame);
106106
if (returnValue != null) {

truffle/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ This changelog summarizes major changes between Truffle versions relevant to lan
1515
* GR-61282 Bytecode DSL: Bytecode builders now also allow emitting source sections using the start and length source indices in the end method in addition to the begin method. This was added to support linear parsing without look-ahead.
1616
* GR-61282 Bytecode DSL: (breaking) If multiple source sections were specified around root operations, only the innermost source section directly encapsulating the root will be accessible. Other encapsulating source sections will be discarded for outer most root operations.
1717
* GR-64533 By default every specialization is now included for {@link GenerateUncached}, except specializations that require a {@link Specialization#limit() limit} and are replaced, those are excluded by default. By setting `@Specialization(excludeForUncached=..)` explicitly the default behavior can be overridden, e.g. to include or exclude a specialization for uncached. Specializations which are no longer compatible with uncached will produce a warning instead of an error for compatibility reasons until all languages are migrated. It is therefore expected that language implementations may see new warnings with this version.
18+
* GR-64124 Added `BytecodeOSRNode.pollOSRBackEdge(BytecodeOSRNode, int)` that supports batch polling for bytecode OSR. Using this method avoids checking for bytecode OSR on every loop backedge.
19+
* GR-64124 Deprecated `BytecodeOSRNode.pollOSRBackEdge(BytecodeOSRNode)`. Use `BytecodeOSRNode.pollOSRBackEdge(BytecodeOSRNode, int)` instead. Please note that the old method did call `TruffleSafepoint.poll(Node)`, but the the new method does not. Please double check that your bytecode interpreter polls Truffle safepoints at loop back-edges.
1820

1921
## Version 24.2.0
2022
* GR-60636 Truffle now stops compiling when the code cache fills up on HotSpot. A warning is printed when that happens.

truffle/src/com.oracle.truffle.api.bytecode.test/src/com/oracle/truffle/api/bytecode/test/InstructionBytecodeSizeTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373

7474
public class InstructionBytecodeSizeTest {
7575

76-
private static final int CACHED_INSTRUCTION_SIZE = 31;
76+
private static final int CACHED_INSTRUCTION_SIZE = 29;
7777
private static final int UNCACHED_INSTRUCTION_SIZE = 29;
7878

7979
// !Important: Keep these in sync with BytecodeDSLNodeFactory!

truffle/src/com.oracle.truffle.api/snapshot.sigtest

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1151,6 +1151,8 @@ meth public java.lang.Object executeOSR(com.oracle.truffle.api.frame.VirtualFram
11511151
meth public java.lang.Object executeOSR(com.oracle.truffle.api.frame.VirtualFrame,long,java.lang.Object)
11521152
meth public java.lang.Object[] storeParentFrameInArguments(com.oracle.truffle.api.frame.VirtualFrame)
11531153
meth public static boolean pollOSRBackEdge(com.oracle.truffle.api.nodes.BytecodeOSRNode)
1154+
anno 0 java.lang.Deprecated(boolean forRemoval=false, java.lang.String since="25.0")
1155+
meth public static boolean pollOSRBackEdge(com.oracle.truffle.api.nodes.BytecodeOSRNode,int)
11541156
meth public static java.lang.Object tryOSR(com.oracle.truffle.api.nodes.BytecodeOSRNode,int,java.lang.Object,java.lang.Runnable,com.oracle.truffle.api.frame.VirtualFrame)
11551157
meth public static java.lang.Object tryOSR(com.oracle.truffle.api.nodes.BytecodeOSRNode,long,java.lang.Object,java.lang.Runnable,com.oracle.truffle.api.frame.VirtualFrame)
11561158
meth public void copyIntoOSRFrame(com.oracle.truffle.api.frame.VirtualFrame,com.oracle.truffle.api.frame.VirtualFrame,int)
@@ -1705,7 +1707,7 @@ meth public void printStackTrace(java.io.PrintStream)
17051707
meth public void printStackTrace(java.io.PrintWriter)
17061708
meth public void setStackTrace(java.lang.StackTraceElement[])
17071709
supr java.lang.Object
1708-
hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,depth,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
1710+
hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,depth,detailMessage,jfrTracing,serialVersionUID,stackTrace,suppressedExceptions
17091711
hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
17101712

17111713
CLSS public abstract interface java.lang.annotation.Annotation

0 commit comments

Comments
 (0)