Skip to content

Commit 08165c2

Browse files
committed
Add RootNode.prepareForCompilation.
1 parent 8f98ffb commit 08165c2

File tree

15 files changed

+311
-19
lines changed

15 files changed

+311
-19
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public class ClassLinkedByCompilerTest extends PartialEvaluationTest {
3838
public void testClassLinkedByCompiler() {
3939
RootNode root = new RootNodeImpl();
4040
OptimizedCallTarget compilable = (OptimizedCallTarget) root.getCallTarget();
41+
compilable.ensureInitialized();
4142
TruffleCompilationTask task = newTask();
4243
TruffleCompilerImpl compiler = getTruffleCompiler(compilable);
4344
ResolvedJavaType unlinked = getMetaAccess().lookupJavaType(Unlinked.class);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ private static OptimizedCallTarget compileAST(RootNode rootNode) {
140140
try (DebugContext.Scope s = debug.scope("EncodedGraphCacheTest")) {
141141
TruffleCompilationTask task = newTask();
142142
try (TruffleCompilation compilation = compiler.openCompilation(task, target)) {
143+
target.ensureInitialized();
143144
getTruffleCompilerFromRuntime(target).compileAST(debug, target, compilation.getCompilationId(), task, null);
144145
assertTrue(target.isValid());
145146
}

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,13 @@ private static class MultiTierRootNode extends RootNode {
7575

7676
@Override
7777
public Object execute(VirtualFrame frame) {
78+
boundary();
79+
Object result = callNode.call(frame.getArguments());
7880
if (CompilerDirectives.inInterpreter()) {
7981
return "root:interpreter";
8082
}
8183
boundary();
82-
return callNode.call(frame.getArguments());
84+
return result;
8385
}
8486
}
8587

@@ -196,10 +198,6 @@ public void testDefault() {
196198
for (int i = 0; i < firstTierCompilationThreshold; i++) {
197199
multiTierTarget.call();
198200
}
199-
Assert.assertEquals("callee:interpreter", multiTierTarget.call());
200-
for (int i = 0; i < firstTierCompilationThreshold; i++) {
201-
multiTierTarget.call();
202-
}
203201
Assert.assertEquals("callee:first-tier", multiTierTarget.call());
204202
for (int i = 0; i < compilationThreshold; i++) {
205203
multiTierTarget.call();

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ private void assertExpectations() {
556556

557557
@Test
558558
public void testSplittingBudgetLimit() {
559-
try (Context c = Context.newBuilder(SplittingLimitTestLanguage.ID).build()) {
559+
try (Context c = Context.newBuilder(SplittingLimitTestLanguage.ID).option("engine.CompileImmediately", "false").build()) {
560560
c.eval(SplittingLimitTestLanguage.ID, "");
561561
}
562562
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ private void testHelper(RootNode rootNode, boolean expectException, String... ou
127127
DebugContext debug = new Builder(compiler.getOrCreateCompilerOptions(target)).build();
128128
try (DebugCloseable d = debug.disableIntercept(); DebugContext.Scope s = debug.scope("PerformanceWarningTest")) {
129129
final OptimizedCallTarget compilable = target;
130+
compilable.ensureInitialized();
130131
TruffleCompilationTask task = PartialEvaluationTest.newTask();
131132
try (TruffleCompilation compilation = compiler.openCompilation(task, compilable)) {
132133
compiler.compileAST(debug, compilable, compilation.getCompilationId(), task, null);

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

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,17 @@
2525
package jdk.graal.compiler.truffle.test;
2626

2727
import static org.junit.Assert.assertEquals;
28+
import static org.junit.Assert.assertFalse;
29+
import static org.junit.Assert.assertNull;
2830
import static org.junit.Assert.assertTrue;
2931

3032
import java.util.List;
3133

3234
import org.junit.Test;
3335

3436
import com.oracle.truffle.api.CallTarget;
37+
import com.oracle.truffle.api.CompilerDirectives;
38+
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
3539
import com.oracle.truffle.api.TruffleStackTrace;
3640
import com.oracle.truffle.api.TruffleStackTraceElement;
3741
import com.oracle.truffle.api.exception.AbstractTruffleException;
@@ -133,6 +137,147 @@ protected int findBytecodeIndex(Node node, Frame frame) {
133137
}
134138
}
135139

140+
@Test
141+
public void testPrepareForCompilationLastTier() {
142+
PrepareRootNode node = new PrepareRootNode(true);
143+
OptimizedCallTarget target = (OptimizedCallTarget) node.getCallTarget();
144+
target.compile(true);
145+
target.waitForCompilation();
146+
assertTrue(target.isValidLastTier());
147+
assertEquals(new CompilationData(true, 2, true), target.call());
148+
assertEquals(1, node.prepareCount);
149+
assertTrue(target.isValidLastTier());
150+
}
151+
152+
@Test
153+
public void testPrepareForCompilationLastTierReprofile() {
154+
PrepareRootNode node = new PrepareRootNode(false);
155+
OptimizedCallTarget target = (OptimizedCallTarget) node.getCallTarget();
156+
target.compile(true);
157+
target.waitForCompilation();
158+
assertFalse(target.isValidLastTier());
159+
assertNull(target.call());
160+
assertEquals(new CompilationData(true, 2, true), node.compilationData);
161+
assertEquals(1, node.prepareCount);
162+
163+
target.invalidate("test");
164+
node.returnValue = true;
165+
166+
target.compile(true);
167+
target.waitForCompilation();
168+
assertEquals(new CompilationData(true, 2, true), target.call());
169+
assertEquals(2, node.prepareCount);
170+
assertTrue(target.isValidLastTier());
171+
}
172+
173+
@Test
174+
public void testPrepareForCompilationFirstTier() {
175+
PrepareRootNode node = new PrepareRootNode(true);
176+
OptimizedCallTarget target = (OptimizedCallTarget) node.getCallTarget();
177+
target.compile(false);
178+
target.waitForCompilation();
179+
assertTrue(target.isValid());
180+
assertEquals(new CompilationData(true, 1, false), target.call());
181+
assertEquals(1, node.prepareCount);
182+
assertTrue(target.isValid());
183+
}
184+
185+
@Test
186+
public void testPrepareForCompilationFirstTierReprofile() {
187+
PrepareRootNode node = new PrepareRootNode(false);
188+
OptimizedCallTarget target = (OptimizedCallTarget) node.getCallTarget();
189+
target.compile(false);
190+
target.waitForCompilation();
191+
assertFalse(target.isValid());
192+
assertNull(target.call());
193+
assertEquals(new CompilationData(true, 1, false), node.compilationData);
194+
assertEquals(1, node.prepareCount);
195+
196+
target.invalidate("test");
197+
node.returnValue = true;
198+
199+
target.compile(false);
200+
target.waitForCompilation();
201+
assertEquals(new CompilationData(true, 1, false), target.call());
202+
assertEquals(2, node.prepareCount);
203+
assertTrue(target.isValid());
204+
205+
}
206+
207+
@Test
208+
public void testPrepareForCompilationInlined() {
209+
PrepareRootNode node = new PrepareRootNode(true);
210+
node.getCallTarget().call(); // ensure initialized for inlining
211+
ConstantTargetRootNode call = new ConstantTargetRootNode(node);
212+
OptimizedCallTarget target = (OptimizedCallTarget) call.getCallTarget();
213+
target.compile(true);
214+
target.waitForCompilation();
215+
assertTrue(target.isValidLastTier());
216+
assertEquals(1, node.prepareCount);
217+
assertEquals(new CompilationData(false, 2, true), target.call());
218+
assertTrue(target.isValidLastTier());
219+
}
220+
221+
@Test
222+
public void testPrepareForCompilationInlinedReprofile() {
223+
PrepareRootNode node = new PrepareRootNode(false);
224+
node.getCallTarget().call(); // ensure initialized for inlining
225+
ConstantTargetRootNode call = new ConstantTargetRootNode(node);
226+
OptimizedCallTarget target = (OptimizedCallTarget) call.getCallTarget();
227+
target.compile(true);
228+
target.waitForCompilation();
229+
assertTrue(target.isValidLastTier());
230+
assertNull(target.call());
231+
assertEquals(new CompilationData(false, 2, true), node.compilationData);
232+
assertEquals(1, node.prepareCount);
233+
234+
target.invalidate("test");
235+
node.returnValue = true;
236+
237+
target.compile(true);
238+
target.waitForCompilation();
239+
assertTrue(target.isValidLastTier());
240+
assertEquals(2, node.prepareCount);
241+
assertEquals(new CompilationData(false, 2, true), target.call());
242+
assertTrue(target.isValidLastTier());
243+
}
244+
245+
record CompilationData(boolean rootCompilation, int compilationTier, boolean lastTier) {
246+
}
247+
248+
static final class PrepareRootNode extends BaseRootNode {
249+
250+
private volatile int prepareCount = 0;
251+
@CompilationFinal volatile boolean returnValue;
252+
@CompilationFinal volatile CompilationData compilationData;
253+
254+
PrepareRootNode(boolean returnValue) {
255+
this.returnValue = returnValue;
256+
}
257+
258+
@Override
259+
public Object execute(VirtualFrame frame) {
260+
if (CompilerDirectives.inCompiledCode()) {
261+
return compilationData;
262+
}
263+
return null;
264+
}
265+
266+
@Override
267+
protected boolean isTrivial() {
268+
return true;
269+
}
270+
271+
@SuppressWarnings("hiding")
272+
@Override
273+
protected boolean prepareForCompilation(boolean rootCompilation, int compilationTier, boolean lastTier) {
274+
this.prepareCount++;
275+
this.compilationData = new CompilationData(rootCompilation, compilationTier, lastTier);
276+
return returnValue;
277+
}
278+
279+
}
280+
136281
static class ConstantTargetRootNode extends BaseRootNode {
137282

138283
// deliberately

substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/TruffleFromLibGraalStartPoints.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,21 +106,26 @@
106106
*/
107107
public final class TruffleFromLibGraalStartPoints {
108108

109-
private static TruffleFromLibGraalCalls calls;
109+
private static volatile TruffleFromLibGraalCalls calls;
110110
private static JavaVM javaVM;
111111

112112
private TruffleFromLibGraalStartPoints() {
113113
}
114114

115115
static void initializeJNI(JClass runtimeClass) {
116-
if (calls == null) {
117-
calls = new TruffleFromLibGraalCalls(JNIMethodScope.env(), runtimeClass);
118-
JavaVM vm = JNIUtil.GetJavaVM(JNIMethodScope.env());
119-
assert javaVM.isNull() || javaVM.equal(vm);
120-
javaVM = vm;
116+
TruffleFromLibGraalCalls localCalls = calls;
117+
if (localCalls == null) {
118+
initialize(runtimeClass);
121119
}
122120
}
123121

122+
private static synchronized void initialize(JClass runtimeClass) {
123+
calls = new TruffleFromLibGraalCalls(JNIMethodScope.env(), runtimeClass);
124+
JavaVM vm = JNIUtil.GetJavaVM(JNIMethodScope.env());
125+
assert javaVM.isNull() || javaVM.equal(vm);
126+
javaVM = vm;
127+
}
128+
124129
@TruffleFromLibGraal(Id.OnIsolateShutdown)
125130
public static void onIsolateShutdown(long isolateId) {
126131
JNIEnv env = JNIUtil.GetEnv(javaVM);

truffle/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ This changelog summarizes major changes between Truffle versions relevant to lan
1717
* GR-30264 `TruffleLanguage#initializeThread(Object, Thread)` is now guaranteed to be executed on the thread that is being initialized. Additional changes:
1818
* Added `ThreadLocalAction#notifyBlocked(Access)` and `ThreadLocalAction#notifyUnblocked(Access)` to notify thread local actions that their processing has been blocked/unblocked due to a blocked call (see `ThreadLocalAction` documentation).
1919
* `TruffleSafepoint#poll(Node)` does not require a non-null location anymore. However, it is still recommended to always pass a location node, if available.
20+
* GR-59565 Added `RootNode.prepareForCompilation` which allows root nodes to offload expensive computation to the compiler thread and to delay compilation if they are not yet fully profiled.
21+
2022

2123
## Version 24.1.0
2224
* GR-43839 Added optional parameter to TruffleString.ByteIndexOfCodePointSetNode to choose whether the node may calculate the input string's precise code range.

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1376,6 +1376,7 @@ meth protected boolean isCloneUninitializedSupported()
13761376
meth protected boolean isInstrumentable()
13771377
meth protected boolean isSameFrame(com.oracle.truffle.api.frame.Frame,com.oracle.truffle.api.frame.Frame)
13781378
meth protected boolean isTrivial()
1379+
meth protected boolean prepareForCompilation(boolean,int,boolean)
13791380
meth protected com.oracle.truffle.api.frame.FrameDescriptor getParentFrameDescriptor()
13801381
meth protected com.oracle.truffle.api.nodes.ExecutionSignature prepareForAOT()
13811382
meth protected com.oracle.truffle.api.nodes.RootNode cloneUninitialized()
@@ -1645,7 +1646,7 @@ meth public void printStackTrace(java.io.PrintStream)
16451646
meth public void printStackTrace(java.io.PrintWriter)
16461647
meth public void setStackTrace(java.lang.StackTraceElement[])
16471648
supr java.lang.Object
1648-
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
1649+
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
16491650
hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
16501651

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

truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ public abstract LanguageInfo createLanguage(Object cache, String id, String name
219219
public abstract int findBytecodeIndex(RootNode rootNode, Node callNode, Frame frame);
220220

221221
public abstract boolean isCaptureFramesForTrace(RootNode rootNode, boolean compiled);
222+
223+
public abstract boolean prepareForCompilation(RootNode rootNode, boolean rootCompilation, int compilationTier, boolean lastTier);
222224
}
223225

224226
public abstract static class SourceSupport extends Support {

0 commit comments

Comments
 (0)