Skip to content

Commit e1ae1b0

Browse files
committed
Fixed gates.
1 parent 99df0fb commit e1ae1b0

File tree

2 files changed

+87
-36
lines changed

2 files changed

+87
-36
lines changed

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

Lines changed: 73 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -35,32 +35,49 @@
3535
import jdk.graal.compiler.truffle.test.nodes.RootTestNode;
3636
import jdk.jfr.Event;
3737
import jdk.jfr.Name;
38+
import jdk.vm.ci.meta.ResolvedJavaMethod;
3839
import org.junit.Test;
3940

4041
import java.io.IOException;
4142
import java.nio.file.Files;
4243
import java.nio.file.Path;
43-
import java.util.Set;
4444

4545
import static org.junit.Assert.assertNotNull;
4646

4747
public class JFRPartialEvaluationTest extends PartialEvaluationTest {
4848

49+
public static Object constant42() {
50+
return 42;
51+
}
52+
4953
@Test
5054
public void testException() throws IOException, InterruptedException {
5155
runInSubprocessWithJFREnabled(this::performTestException);
5256
}
5357

5458
private void performTestException() {
5559
RootTestNode root = new RootTestNode(new FrameDescriptor(), "NewException", new NewTruffleExceptionNode());
56-
OptimizedCallTarget callTarget = (OptimizedCallTarget) root.getCallTarget();
57-
StructuredGraph graph = partialEval(callTarget, new Object[0]);
58-
// The call from the exception constructor to the JFR tracing must not be inlined.
59-
assertNotNull("The call to ThrowableTracer#traceThrowable was not inlined or is missing.", findAnyInvoke(graph,
60-
"jdk.jfr.internal.instrument.ThrowableTracer#traceThrowable",
61-
"jdk.internal.event.ThrowableTracer#traceThrowable"));
62-
// Also make sure that the node count hasn't exploded.
63-
assertTrue("The number of graal nodes for an exception instantiation exceeded 100.", graph.getNodeCount() < 100);
60+
if (Runtime.version().feature() < 22) {
61+
Class<?> throwableTracer = findThrowableTracerClass();
62+
ResolvedJavaMethod traceThrowable = getResolvedJavaMethod(throwableTracer, "traceThrowable");
63+
OptimizedCallTarget callTarget = (OptimizedCallTarget) root.getCallTarget();
64+
StructuredGraph graph = partialEval(callTarget, new Object[0]);
65+
// The call from the exception constructor to the JFR tracing must not be inlined.
66+
assertNotNull("The call to ThrowableTracer#traceThrowable was not inlined or is missing.", findInvoke(graph, traceThrowable));
67+
// Also make sure that the node count hasn't exploded.
68+
assertTrue("The number of graal nodes for an exception instantiation exceeded 100.", graph.getNodeCount() < 100);
69+
} else {
70+
// On JDK-22+ JFR exception tracing is unconditionally disabled by PartialEvaluator
71+
assertPartialEvalEquals(JFRPartialEvaluationTest::constant42, root);
72+
}
73+
}
74+
75+
private static Class<?> findThrowableTracerClass() {
76+
try {
77+
return Class.forName("jdk.jfr.internal.instrument.ThrowableTracer");
78+
} catch (ClassNotFoundException cnf) {
79+
throw new RuntimeException("ThrowableTracer not found", cnf);
80+
}
6481
}
6582

6683
@Test
@@ -70,17 +87,21 @@ public void testError() throws IOException, InterruptedException {
7087

7188
private void performTestError() {
7289
RootTestNode root = new RootTestNode(new FrameDescriptor(), "NewError", new NewErrorNode());
73-
OptimizedCallTarget callTarget = (OptimizedCallTarget) root.getCallTarget();
74-
StructuredGraph graph = partialEval(callTarget, new Object[0]);
75-
// The call from the exception constructor to the JFR tracing must not be inlined.
76-
assertNotNull("The call to ThrowableTracer#traceThrowable was not inlined or is missing.", findAnyInvoke(graph,
77-
"jdk.jfr.internal.instrument.ThrowableTracer#traceThrowable",
78-
"jdk.internal.event.ThrowableTracer#traceThrowable"));
79-
assertNotNull("The call to ThrowableTracer#traceError was not inlined or is missing.", findAnyInvoke(graph,
80-
"jdk.jfr.internal.instrument.ThrowableTracer#traceError",
81-
"jdk.internal.event.ThrowableTracer#traceError"));
82-
// Also make sure that the node count hasn't exploded.
83-
assertTrue("The number of graal nodes for an exception instantiation exceeded 100.", graph.getNodeCount() < 100);
90+
if (Runtime.version().feature() < 22) {
91+
Class<?> throwableTracer = findThrowableTracerClass();
92+
ResolvedJavaMethod traceThrowable = getResolvedJavaMethod(throwableTracer, "traceThrowable");
93+
ResolvedJavaMethod traceError = getResolvedJavaMethod(throwableTracer, "traceError");
94+
OptimizedCallTarget callTarget = (OptimizedCallTarget) root.getCallTarget();
95+
StructuredGraph graph = partialEval(callTarget, new Object[0]);
96+
// The call from the exception constructor to the JFR tracing must not be inlined.
97+
assertNotNull("The call to ThrowableTracer#traceThrowable was not inlined or is missing.", findInvoke(graph, traceThrowable));
98+
assertNotNull("The call to ThrowableTracer#traceError was not inlined or is missing.", findInvoke(graph, traceError));
99+
// Also make sure that the node count hasn't exploded.
100+
assertTrue("The number of graal nodes for an exception instantiation exceeded 100.", graph.getNodeCount() < 100);
101+
} else {
102+
// On JDK-22+ JFR exception tracing is unconditionally disabled by PartialEvaluator
103+
assertPartialEvalEquals(JFRPartialEvaluationTest::constant42, root);
104+
}
84105
}
85106

86107
@Test
@@ -89,23 +110,22 @@ public void testJFREvent() throws IOException, InterruptedException {
89110
}
90111

91112
private void performTestJFREvent() {
113+
ResolvedJavaMethod shouldCommit = getResolvedJavaMethod(TestEvent.class, "shouldCommit");
114+
ResolvedJavaMethod commit = getResolvedJavaMethod(TestEvent.class, "commit");
92115
RootTestNode root = new RootTestNode(new FrameDescriptor(), "JFREvent", new JFREventNode());
93116
OptimizedCallTarget callTarget = (OptimizedCallTarget) root.getCallTarget();
94117
StructuredGraph graph = partialEval(callTarget, new Object[0]);
95118
// Calls to JFR event methods must not be inlined.
96-
assertNotNull("The call to TestEvent#shouldCommit was not inlined or is missing.", findAnyInvoke(graph,
97-
"jdk.graal.compiler.truffle.test.JFRPartialEvaluationTest$TestEvent#shouldCommit"));
98-
assertNotNull("The call to TestEvent#commit was not inlined or is missing.", findAnyInvoke(graph,
99-
"jdk.graal.compiler.truffle.test.JFRPartialEvaluationTest$TestEvent#commit"));
119+
assertNotNull("The call to TestEvent#shouldCommit was not inlined or is missing.", findInvoke(graph, shouldCommit));
120+
assertNotNull("The call to TestEvent#commit was not inlined or is missing.", findInvoke(graph, commit));
100121
// Also make sure that the node count hasn't exploded.
101122
assertTrue("The number of graal nodes for an exception instantiation exceeded 100.", graph.getNodeCount() < 100);
102123
}
103124

104-
private static MethodCallTargetNode findAnyInvoke(StructuredGraph graph, String... expectedMethodNames) {
105-
Set<String> expectedSet = Set.of(expectedMethodNames);
125+
private static MethodCallTargetNode findInvoke(StructuredGraph graph, ResolvedJavaMethod expectedMethod) {
106126
for (MethodCallTargetNode node : graph.getNodes(MethodCallTargetNode.TYPE)) {
107-
String targetMethodName = node.targetMethod().format("%H#%n");
108-
if (expectedSet.contains(targetMethodName)) {
127+
ResolvedJavaMethod targetMethod = node.targetMethod();
128+
if (expectedMethod.equals(targetMethod)) {
109129
return node;
110130
}
111131
}
@@ -141,23 +161,43 @@ private static final class NewTruffleExceptionNode extends AbstractTestNode {
141161

142162
@Override
143163
public int execute(VirtualFrame frame) {
144-
new AbstractTruffleException() {
145-
};
146-
return 1;
164+
try {
165+
throw new TruffleExceptionImpl(42);
166+
} catch (TruffleExceptionImpl e) {
167+
return e.value;
168+
}
169+
}
170+
171+
@SuppressWarnings("serial")
172+
private static final class TruffleExceptionImpl extends AbstractTruffleException {
173+
final int value;
174+
175+
TruffleExceptionImpl(int value) {
176+
this.value = value;
177+
}
147178
}
148179
}
149180

150181
private static final class NewErrorNode extends AbstractTestNode {
151182

152183
@Override
153184
public int execute(VirtualFrame frame) {
154-
new ErrorImpl();
155-
return 1;
185+
try {
186+
throw new ErrorImpl(42);
187+
} catch (ErrorImpl e) {
188+
return e.value;
189+
}
156190
}
157191

158192
@SuppressWarnings("serial")
159193
private static final class ErrorImpl extends Error {
160194

195+
final int value;
196+
197+
ErrorImpl(int value) {
198+
this.value = value;
199+
}
200+
161201
@Override
162202
@SuppressWarnings("sync-override")
163203
public Throwable fillInStackTrace() {

truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/debug/JFRListener.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,20 @@ private static boolean isInstrumentedImpl(ResolvedJavaMethod method, Instrumente
285285
return false;
286286
}
287287

288-
if (("traceThrowable".equals(method.getName()) || "traceError".equals(method.getName())) &&
289-
(/* JDK-11 to JDK-21 */ "Ljdk/jfr/internal/instrument/ThrowableTracer;".equals(method.getDeclaringClass().getName()) ||
290-
/* JDK-22+ */ "Ljdk/internal/event/ThrowableTracer;".equals(method.getDeclaringClass().getName()))) {
288+
/*
289+
* Between JDK-11 and JDK-21, JFR utilizes instrumentation to inject calls to
290+
* jdk.jfr.internal.instrument.ThrowableTracer into constructors of Throwable and Error.
291+
* These calls must never be inlined. However, in JDK-22,
292+
* jdk.jfr.internal.instrument.ThrowableTracer was renamed to
293+
* jdk.internal.event.ThrowableTracer, and the calls are no longer injected via
294+
* instrumentation. Instead, a volatile field, Throwable#jfrTracing, is used. This field
295+
* necessitates a volatile read. To prevent this in a PE code, PartialEvaluator modifies the
296+
* reading of jfrTracing to a compilation constant `false`, effectively removing the JFR
297+
* code during bytecode parsing. See PartialEvaluator#appendJFRTracingPlugin. This should
298+
* not pose an issue because general-purpose exceptions are typically created after the
299+
* TruffleBoundary.
300+
*/
301+
if (("traceThrowable".equals(method.getName()) || "traceError".equals(method.getName())) && "Ljdk/jfr/internal/instrument/ThrowableTracer;".equals(method.getDeclaringClass().getName())) {
291302
return true;
292303
}
293304

0 commit comments

Comments
 (0)