Skip to content

Commit ad42202

Browse files
committed
[GR-59565] [GR-59764] Add RootNode.prepareForCompilation(...) to delay compilation and offload expensive work to the compiler thread.
PullRequest: graal/19264
2 parents 47da7f5 + 8ac9409 commit ad42202

File tree

29 files changed

+590
-111
lines changed

29 files changed

+590
-111
lines changed

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,10 @@ public String toString(Verbosity verbosity) {
6363
return "";
6464
}
6565
};
66-
final TruffleTierContext context = new TruffleTierContext(partialEvaluator,
66+
final TruffleTierContext context = TruffleTierContext.createInitialContext(
67+
partialEvaluator,
6768
compiler.getOrCreateCompilerOptions(callTarget),
68-
getDebugContext(), callTarget, partialEvaluator.rootForCallTarget(callTarget),
69+
getDebugContext(), callTarget,
6970
compilationIdentifier, getSpeculationLog(),
7071
new TruffleCompilationTask() {
7172

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/PartialEvaluationTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,9 @@ private StructuredGraph partialEval(OptimizedCallTarget compilable, Object[] arg
299299
final PartialEvaluator partialEvaluator = compiler.getPartialEvaluator();
300300
try (PerformanceInformationHandler handler = PerformanceInformationHandler.install(
301301
compiler.getConfig().runtime(), compiler.getOrCreateCompilerOptions(compilable))) {
302-
final TruffleTierContext context = new TruffleTierContext(partialEvaluator,
302+
final TruffleTierContext context = TruffleTierContext.createInitialContext(partialEvaluator,
303303
compiler.getOrCreateCompilerOptions(compilable),
304304
debug, compilable,
305-
partialEvaluator.rootForCallTarget(compilable),
306305
compilation.getCompilationId(), speculationLog,
307306
task,
308307
handler);

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

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/libgraal/truffle/HSTruffleCompilable.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@ public long engineId() {
8787
}
8888

8989
@Override
90-
public void prepareForCompilation() {
90+
public boolean prepareForCompilation(boolean rootCompilation, int compilationTier, boolean lastTier) {
9191
try {
92-
HANDLES.prepareForCompilation.invoke(hsHandle);
92+
return (boolean) HANDLES.prepareForCompilation.invoke(hsHandle, rootCompilation, compilationTier, lastTier);
9393
} catch (Throwable t) {
9494
throw handleException(t);
9595
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/TruffleCompilerImpl.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -538,11 +538,10 @@ private StructuredGraph truffleTier(TruffleCompilationWrapper wrapper, DebugCont
538538
* TODO GR-37097 Merge TruffleTierConfiguration and TruffleCompilationWrapper so that
539539
* there is one place where compilation data lives
540540
*/
541-
TruffleTierContext context = new TruffleTierContext(partialEvaluator,
541+
TruffleTierContext context = TruffleTierContext.createInitialContext(partialEvaluator,
542542
wrapper.compilerOptions,
543543
debug,
544544
wrapper.compilable,
545-
partialEvaluator.rootForCallTarget(wrapper.compilable),
546545
wrapper.compilationId, TruffleTierContext.getSpeculationLog(wrapper), wrapper.task,
547546
handler);
548547

0 commit comments

Comments
 (0)