Skip to content

Commit c01f53a

Browse files
committed
8337876: [IR Framework] Add support for IR tests with @stable
Reviewed-by: shade, kvn
1 parent 00aac40 commit c01f53a

File tree

5 files changed

+103
-7
lines changed

5 files changed

+103
-7
lines changed

test/hotspot/jtreg/compiler/lib/ir_framework/README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,16 @@ The framework allows the use of additional compiler control annotations for help
157157
- [@ForceCompile](./ForceCompile.java)
158158
- [@ForceCompileClassInitializer](./ForceCompileClassInitializer.java)
159159

160-
### 2.5 Framework Debug and Stress Flags
160+
### 2.5 IR Tests with Privileged Classes
161+
To run tests in a privileged mode (e.g. when using `@Stable`, `@Contended`, `@ReservedStackAccess` etc.), one need to add the test classes to the boot classpath. This can easily be achieved by calling `TestFramework.addTestClassesToBootClassPath()` on the test framework object:
162+
```
163+
TestFramework testFramework = new TestFramework();
164+
testFramework
165+
.addTestClassesToBootClassPath()
166+
.start();
167+
```
168+
169+
### 2.6 Framework Debug and Stress Flags
161170
The framework provides various stress and debug flags. They should mainly be used as JTreg VM and/or Javaoptions (apart from `VerifyIR`). The following (property) flags are supported:
162171

163172
- `-DVerifyIR=false`: Explicitly disable IR verification. This is useful, for example, if some scenarios use VM flags that let `@IR` annotation rules fail and the user does not want to provide separate IR rules or add flag preconditions to the already existing IR rules.

test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ public class TestFramework {
172172
private Set<Integer> scenarioIndices;
173173
private List<String> flags;
174174
private int defaultWarmup = -1;
175+
private boolean testClassesOnBootClassPath;
175176

176177
/*
177178
* Public interface methods
@@ -323,6 +324,15 @@ public TestFramework addScenarios(Scenario... scenarios) {
323324
return this;
324325
}
325326

327+
/**
328+
* Add test classes to boot classpath. This adds all classes found on path {@link jdk.test.lib.Utils#TEST_CLASSES}
329+
* to the boot classpath with "-Xbootclasspath/a". This is useful when trying to run tests in a privileged mode.
330+
*/
331+
public TestFramework addTestClassesToBootClassPath() {
332+
this.testClassesOnBootClassPath = true;
333+
return this;
334+
}
335+
326336
/**
327337
* Start the testing of the implicitly (by {@link #TestFramework()}) or explicitly (by {@link #TestFramework(Class)})
328338
* set test class.
@@ -744,7 +754,8 @@ private boolean onlyWhitelistedJTregVMAndJavaOptsFlags() {
744754
}
745755

746756
private void runTestVM(List<String> additionalFlags) {
747-
TestVMProcess testVMProcess = new TestVMProcess(additionalFlags, testClass, helperClasses, defaultWarmup);
757+
TestVMProcess testVMProcess = new TestVMProcess(additionalFlags, testClass, helperClasses, defaultWarmup,
758+
testClassesOnBootClassPath);
748759
if (shouldVerifyIR) {
749760
try {
750761
TestClassParser testClassParser = new TestClassParser(testClass);

test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import jdk.test.lib.process.OutputAnalyzer;
3535
import jdk.test.lib.process.ProcessTools;
3636

37+
import java.io.File;
3738
import java.util.*;
3839
import java.util.regex.Matcher;
3940
import java.util.regex.Pattern;
@@ -63,11 +64,12 @@ public class TestVMProcess {
6364
private OutputAnalyzer oa;
6465
private String irEncoding;
6566

66-
public TestVMProcess(List<String> additionalFlags, Class<?> testClass, Set<Class<?>> helperClasses, int defaultWarmup) {
67+
public TestVMProcess(List<String> additionalFlags, Class<?> testClass, Set<Class<?>> helperClasses, int defaultWarmup,
68+
boolean testClassesOnBootClassPath) {
6769
this.cmds = new ArrayList<>();
6870
TestFrameworkSocket socket = new TestFrameworkSocket();
6971
try (socket) {
70-
prepareTestVMFlags(additionalFlags, socket, testClass, helperClasses, defaultWarmup);
72+
prepareTestVMFlags(additionalFlags, socket, testClass, helperClasses, defaultWarmup, testClassesOnBootClassPath);
7173
start();
7274
}
7375
processSocketOutput(socket);
@@ -91,11 +93,16 @@ public static String getLastTestVMOutput() {
9193
}
9294

9395
private void prepareTestVMFlags(List<String> additionalFlags, TestFrameworkSocket socket, Class<?> testClass,
94-
Set<Class<?>> helperClasses, int defaultWarmup) {
96+
Set<Class<?>> helperClasses, int defaultWarmup, boolean testClassesOnBootClassPath) {
9597
// Set java.library.path so JNI tests which rely on jtreg nativepath setting work
9698
cmds.add("-Djava.library.path=" + Utils.TEST_NATIVE_PATH);
9799
// Need White Box access in test VM.
98-
cmds.add("-Xbootclasspath/a:.");
100+
String bootClassPath = "-Xbootclasspath/a:.";
101+
if (testClassesOnBootClassPath) {
102+
// Add test classes themselves to boot classpath to make them privileged.
103+
bootClassPath += File.pathSeparator + Utils.TEST_CLASSES;
104+
}
105+
cmds.add(bootClassPath);
99106
cmds.add("-XX:+UnlockDiagnosticVMOptions");
100107
cmds.add("-XX:+WhiteBoxAPI");
101108
// Ignore CompileCommand flags which have an impact on the profiling information.

test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPhaseIRMatching.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ private static void run(Class<?> testClass) {
6666
List<String> noAdditionalFlags = new ArrayList<>();
6767
FlagVMProcess flagVMProcess = new FlagVMProcess(testClass, noAdditionalFlags);
6868
List<String> testVMFlags = flagVMProcess.getTestVMFlags();
69-
TestVMProcess testVMProcess = new TestVMProcess(testVMFlags, testClass, null, -1);
69+
TestVMProcess testVMProcess = new TestVMProcess(testVMFlags, testClass, null, -1, false);
7070
TestClassParser testClassParser = new TestClassParser(testClass);
7171
Matchable testClassMatchable = testClassParser.parse(testVMProcess.getHotspotPidFileName(),
7272
testVMProcess.getIrEncoding());
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
package ir_framework.tests;
25+
26+
import compiler.lib.ir_framework.*;
27+
import compiler.lib.ir_framework.driver.irmatching.IRViolationException;
28+
29+
import jdk.internal.vm.annotation.Stable;
30+
import jdk.test.lib.Asserts;
31+
32+
/*
33+
* @test
34+
* @requires vm.flagless
35+
* @summary Test that IR framework successfully adds test class to boot classpath in order to run in privileged mode.
36+
* @modules java.base/jdk.internal.vm.annotation
37+
* @library /test/lib /
38+
* @run driver ir_framework.tests.TestPrivilegedMode
39+
*/
40+
41+
public class TestPrivilegedMode {
42+
static @Stable int iFld; // Treated as constant after first being set.
43+
44+
public static void main(String[] args) {
45+
try {
46+
TestFramework.run();
47+
Asserts.fail("should not reach");
48+
} catch (IRViolationException e) {
49+
// Without adding test class to boot classpath, we fail to replace the field load by a constant.
50+
Asserts.assertTrue(e.getExceptionInfo().contains("Matched forbidden node"));
51+
Asserts.assertTrue(e.getExceptionInfo().contains("LoadI"));
52+
}
53+
54+
// When adding the test class to the boot classpath, we can replace the field load by a constant.
55+
new TestFramework().addTestClassesToBootClassPath().start();
56+
}
57+
58+
@Test
59+
@Arguments(setup = "setup")
60+
@IR(failOn = IRNode.LOAD_I)
61+
public int test() {
62+
return iFld;
63+
}
64+
65+
@Setup
66+
public void setup() {
67+
iFld = 34;
68+
}
69+
}

0 commit comments

Comments
 (0)