Skip to content

Commit

Permalink
8337876: [IR Framework] Add support for IR tests with @stable
Browse files Browse the repository at this point in the history
8338112: Test testlibrary_tests/ir_framework/tests/TestPrivilegedMode.java fails with release build

Reviewed-by: eastigeevich, phh
Backport-of: c01f53a
  • Loading branch information
shipilev committed Sep 25, 2024
1 parent 547a229 commit 5979904
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 7 deletions.
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.debug == true & vm.compiler2.enabled & 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;
}
}

1 comment on commit 5979904

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.