Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion test/hotspot/jtreg/compiler/lib/ir_framework/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,16 @@ The framework allows the use of additional compiler control annotations for help
- [@ForceCompile](./ForceCompile.java)
- [@ForceCompileClassInitializer](./ForceCompileClassInitializer.java)

### 2.5 Framework Debug and Stress Flags
### 2.5 IR Tests with Privileged Classes
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:
```
TestFramework testFramework = new TestFramework();
testFramework
.addTestClassesToBootClassPath()
.start();
```

### 2.6 Framework Debug and Stress Flags
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:

- `-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.
Expand Down
13 changes: 12 additions & 1 deletion test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ public class TestFramework {
private Set<Integer> scenarioIndices;
private List<String> flags;
private int defaultWarmup = -1;
private boolean testClassesOnBootClassPath;

/*
* Public interface methods
Expand Down Expand Up @@ -323,6 +324,15 @@ public TestFramework addScenarios(Scenario... scenarios) {
return this;
}

/**
* Add test classes to boot classpath. This adds all classes found on path {@link jdk.test.lib.Utils#TEST_CLASSES}
* to the boot classpath with "-Xbootclasspath/a". This is useful when trying to run tests in a privileged mode.
*/
public TestFramework addTestClassesToBootClassPath() {
this.testClassesOnBootClassPath = true;
return this;
}

/**
* Start the testing of the implicitly (by {@link #TestFramework()}) or explicitly (by {@link #TestFramework(Class)})
* set test class.
Expand Down Expand Up @@ -744,7 +754,8 @@ private boolean onlyWhitelistedJTregVMAndJavaOptsFlags() {
}

private void runTestVM(List<String> additionalFlags) {
TestVMProcess testVMProcess = new TestVMProcess(additionalFlags, testClass, helperClasses, defaultWarmup);
TestVMProcess testVMProcess = new TestVMProcess(additionalFlags, testClass, helperClasses, defaultWarmup,
testClassesOnBootClassPath);
if (shouldVerifyIR) {
try {
TestClassParser testClassParser = new TestClassParser(testClass);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;

import java.io.File;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -63,11 +64,12 @@ public class TestVMProcess {
private OutputAnalyzer oa;
private String irEncoding;

public TestVMProcess(List<String> additionalFlags, Class<?> testClass, Set<Class<?>> helperClasses, int defaultWarmup) {
public TestVMProcess(List<String> additionalFlags, Class<?> testClass, Set<Class<?>> helperClasses, int defaultWarmup,
boolean testClassesOnBootClassPath) {
this.cmds = new ArrayList<>();
TestFrameworkSocket socket = new TestFrameworkSocket();
try (socket) {
prepareTestVMFlags(additionalFlags, socket, testClass, helperClasses, defaultWarmup);
prepareTestVMFlags(additionalFlags, socket, testClass, helperClasses, defaultWarmup, testClassesOnBootClassPath);
start();
}
processSocketOutput(socket);
Expand All @@ -91,11 +93,16 @@ public static String getLastTestVMOutput() {
}

private void prepareTestVMFlags(List<String> additionalFlags, TestFrameworkSocket socket, Class<?> testClass,
Set<Class<?>> helperClasses, int defaultWarmup) {
Set<Class<?>> helperClasses, int defaultWarmup, boolean testClassesOnBootClassPath) {
// Set java.library.path so JNI tests which rely on jtreg nativepath setting work
cmds.add("-Djava.library.path=" + Utils.TEST_NATIVE_PATH);
// Need White Box access in test VM.
cmds.add("-Xbootclasspath/a:.");
String bootClassPath = "-Xbootclasspath/a:.";
if (testClassesOnBootClassPath) {
// Add test classes themselves to boot classpath to make them privileged.
bootClassPath += File.pathSeparator + Utils.TEST_CLASSES;
}
cmds.add(bootClassPath);
cmds.add("-XX:+UnlockDiagnosticVMOptions");
cmds.add("-XX:+WhiteBoxAPI");
// Ignore CompileCommand flags which have an impact on the profiling information.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ private static void run(Class<?> testClass) {
List<String> noAdditionalFlags = new ArrayList<>();
FlagVMProcess flagVMProcess = new FlagVMProcess(testClass, noAdditionalFlags);
List<String> testVMFlags = flagVMProcess.getTestVMFlags();
TestVMProcess testVMProcess = new TestVMProcess(testVMFlags, testClass, null, -1);
TestVMProcess testVMProcess = new TestVMProcess(testVMFlags, testClass, null, -1, false);
TestClassParser testClassParser = new TestClassParser(testClass);
Matchable testClassMatchable = testClassParser.parse(testVMProcess.getHotspotPidFileName(),
testVMProcess.getIrEncoding());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

package ir_framework.tests;

import compiler.lib.ir_framework.*;
import compiler.lib.ir_framework.driver.irmatching.IRViolationException;

import jdk.internal.vm.annotation.Stable;
import jdk.test.lib.Asserts;

/*
* @test
* @requires vm.flagless
* @summary Test that IR framework successfully adds test class to boot classpath in order to run in privileged mode.
* @modules java.base/jdk.internal.vm.annotation
* @library /test/lib /
* @run driver ir_framework.tests.TestPrivilegedMode
*/

public class TestPrivilegedMode {
static @Stable int iFld; // Treated as constant after first being set.

public static void main(String[] args) {
try {
TestFramework.run();
Asserts.fail("should not reach");
} catch (IRViolationException e) {
// Without adding test class to boot classpath, we fail to replace the field load by a constant.
Asserts.assertTrue(e.getExceptionInfo().contains("Matched forbidden node"));
Asserts.assertTrue(e.getExceptionInfo().contains("LoadI"));
}

// When adding the test class to the boot classpath, we can replace the field load by a constant.
new TestFramework().addTestClassesToBootClassPath().start();
}

@Test
@Arguments(setup = "setup")
@IR(failOn = IRNode.LOAD_I)
public int test() {
return iFld;
}

@Setup
public void setup() {
iFld = 34;
}
}