Path: blob/master/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java
41149 views
/*1* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223package compiler.ciReplay;2425import compiler.whitebox.CompilerWhiteBoxTest;26import java.io.IOException;27import java.io.File;28import java.io.BufferedReader;29import java.io.FileReader;30import java.nio.file.Files;31import java.nio.file.Path;32import java.nio.file.Paths;33import java.nio.file.StandardOpenOption;34import java.util.ArrayList;35import java.util.Arrays;36import java.util.List;37import java.util.Optional;38import java.util.regex.Pattern;39import java.util.regex.Matcher;40import jdk.test.lib.Platform;41import jdk.test.lib.process.ProcessTools;42import jdk.test.lib.process.OutputAnalyzer;43import jdk.test.lib.Asserts;44import jdk.test.lib.Utils;45import jdk.test.lib.util.CoreUtils;4647public abstract class CiReplayBase {48public static final String REPLAY_FILE_NAME = "test_replay.txt";49public static final boolean CLIENT_VM_AVAILABLE;50public static final boolean SERVER_VM_AVAILABLE;51public static final String TIERED_ENABLED_VM_OPTION = "-XX:+TieredCompilation";52public static final String TIERED_DISABLED_VM_OPTION = "-XX:-TieredCompilation";53public static final String ENABLE_COREDUMP_ON_CRASH = "-XX:+CreateCoredumpOnCrash";54public static final String DISABLE_COREDUMP_ON_CRASH = "-XX:-CreateCoredumpOnCrash";55public static final String CLIENT_VM_OPTION = "-client";56public static final String SERVER_VM_OPTION = "-server";57public static final String TEST_CORE_FILE_NAME = "test_core";58public static final String RUN_SHELL_NO_LIMIT = "ulimit -c unlimited && ";59private static final String REPLAY_FILE_OPTION = "-XX:ReplayDataFile=" + REPLAY_FILE_NAME;60private static final String LOCATIONS_STRING = "location: ";61private static final String HS_ERR_NAME = "hs_err_pid";62private static final String RUN_SHELL_ZERO_LIMIT = "ulimit -S -c 0 && ";63private static final String VERSION_OPTION = "-version";64private static final String[] REPLAY_GENERATION_OPTIONS = new String[]{"-Xms128m", "-Xmx128m",65"-XX:MetaspaceSize=4m", "-XX:MaxMetaspaceSize=16m", "-XX:InitialCodeCacheSize=512k",66"-XX:ReservedCodeCacheSize=4m", "-XX:ThreadStackSize=512", "-XX:VMThreadStackSize=512",67"-XX:CompilerThreadStackSize=512", "-XX:ParallelGCThreads=1", "-XX:CICompilerCount=2",68"-XX:-BackgroundCompilation", "-XX:CompileCommand=inline,java.io.PrintStream::*",69"-XX:+IgnoreUnrecognizedVMOptions", "-XX:TypeProfileLevel=222", // extra profile data as a stress test70"-XX:CICrashAt=1", "-XX:+DumpReplayDataOnError",71"-XX:+PreferInterpreterNativeStubs", REPLAY_FILE_OPTION};72private static final String[] REPLAY_OPTIONS = new String[]{DISABLE_COREDUMP_ON_CRASH,73"-XX:+IgnoreUnrecognizedVMOptions", "-XX:TypeProfileLevel=222",74"-XX:+ReplayCompiles", REPLAY_FILE_OPTION};75protected final Optional<Boolean> runServer;76private static int dummy;7778public static class TestMain {79public static void main(String[] args) {80for (int i = 0; i < 20_000; i++) {81test(i);82}83}8485static void test(int i) {86if ((i % 1000) == 0) {87System.out.println("Hello World!");88}89}90}9192static {93try {94CLIENT_VM_AVAILABLE = ProcessTools.executeTestJvm(CLIENT_VM_OPTION, VERSION_OPTION)95.getOutput().contains("Client");96SERVER_VM_AVAILABLE = ProcessTools.executeTestJvm(SERVER_VM_OPTION, VERSION_OPTION)97.getOutput().contains("Server");98} catch(Throwable t) {99throw new Error("Initialization failed: " + t, t);100}101}102103public CiReplayBase() {104runServer = Optional.empty();105}106107public CiReplayBase(String args[]) {108if (args.length != 1 || (!"server".equals(args[0]) && !"client".equals(args[0]))) {109throw new Error("Expected 1 argument: [server|client]");110}111runServer = Optional.of("server".equals(args[0]));112}113114public void runTest(boolean needCoreDump, String... args) {115cleanup();116if (generateReplay(needCoreDump, args)) {117testAction();118cleanup();119} else {120throw new Error("Host is not configured to generate cores");121}122}123124public abstract void testAction();125126private static void remove(String item) {127File toDelete = new File(item);128toDelete.delete();129if (Platform.isWindows()) {130Utils.waitForCondition(() -> !toDelete.exists());131}132}133134private static void removeFromCurrentDirectoryStartingWith(String prefix) {135Arrays.stream(new File(".").listFiles())136.filter(f -> f.getName().startsWith(prefix))137.forEach(File::delete);138}139140public static void cleanup() {141removeFromCurrentDirectoryStartingWith("core");142removeFromCurrentDirectoryStartingWith("replay");143removeFromCurrentDirectoryStartingWith(HS_ERR_NAME);144remove(TEST_CORE_FILE_NAME);145remove(REPLAY_FILE_NAME);146}147148public boolean generateReplay(boolean needCoreDump, String... vmopts) {149OutputAnalyzer crashOut;150String crashOutputString;151try {152List<String> options = new ArrayList<>();153options.addAll(Arrays.asList(REPLAY_GENERATION_OPTIONS));154options.addAll(Arrays.asList(vmopts));155options.add(needCoreDump ? ENABLE_COREDUMP_ON_CRASH : DISABLE_COREDUMP_ON_CRASH);156if (needCoreDump) {157// CiReplayBase$TestMain needs to be quoted because of shell eval158options.add("-XX:CompileOnly='" + TestMain.class.getName() + "::test'");159options.add("'" + TestMain.class.getName() + "'");160crashOut = ProcessTools.executeProcess(161CoreUtils.addCoreUlimitCommand(162ProcessTools.createTestJvm(options.toArray(new String[0]))));163} else {164options.add("-XX:CompileOnly=" + TestMain.class.getName() + "::test");165options.add(TestMain.class.getName());166crashOut = ProcessTools.executeProcess(ProcessTools.createTestJvm(options));167}168crashOutputString = crashOut.getOutput();169Asserts.assertNotEquals(crashOut.getExitValue(), 0, "Crash JVM exits gracefully");170Files.write(Paths.get("crash.out"), crashOutputString.getBytes(),171StandardOpenOption.CREATE, StandardOpenOption.WRITE,172StandardOpenOption.TRUNCATE_EXISTING);173} catch (Throwable t) {174throw new Error("Can't create replay: " + t, t);175}176if (needCoreDump) {177try {178String coreFileLocation = CoreUtils.getCoreFileLocation(crashOutputString, crashOut.pid());179Files.move(Paths.get(coreFileLocation), Paths.get(TEST_CORE_FILE_NAME));180} catch (IOException ioe) {181throw new Error("Can't move core file: " + ioe, ioe);182}183}184removeFromCurrentDirectoryStartingWith(HS_ERR_NAME);185return true;186}187188public void commonTests() {189positiveTest();190if (Platform.isTieredSupported()) {191positiveTest(TIERED_ENABLED_VM_OPTION);192}193}194195public int startTest(String... additionalVmOpts) {196try {197List<String> allAdditionalOpts = new ArrayList<>();198allAdditionalOpts.addAll(Arrays.asList(REPLAY_OPTIONS));199allAdditionalOpts.addAll(Arrays.asList(additionalVmOpts));200OutputAnalyzer oa = ProcessTools.executeProcess(getTestJvmCommandlineWithPrefix(201RUN_SHELL_ZERO_LIMIT, allAdditionalOpts.toArray(new String[0])));202return oa.getExitValue();203} catch (Throwable t) {204throw new Error("Can't run replay process: " + t, t);205}206}207208public void runVmTests() {209boolean runServerValue = runServer.orElseThrow(() -> new Error("runServer must be set"));210if (runServerValue) {211if (CLIENT_VM_AVAILABLE) {212negativeTest(CLIENT_VM_OPTION);213}214} else {215if (SERVER_VM_AVAILABLE) {216negativeTest(TIERED_DISABLED_VM_OPTION, SERVER_VM_OPTION);217if (Platform.isTieredSupported()) {218positiveTest(TIERED_ENABLED_VM_OPTION, SERVER_VM_OPTION);219}220}221}222nonTieredTests(runServerValue ? CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION223: CompilerWhiteBoxTest.COMP_LEVEL_SIMPLE);224}225226public int getCompLevelFromReplay() {227try(BufferedReader br = new BufferedReader(new FileReader(REPLAY_FILE_NAME))) {228return br.lines()229.filter(s -> s.startsWith("compile "))230.map(s -> s.split("\\s+")[5])231.map(Integer::parseInt)232.findAny()233.get();234} catch (IOException ioe) {235throw new Error("Failed to read replay data: " + ioe, ioe);236}237}238239public void positiveTest(String... additionalVmOpts) {240Asserts.assertEQ(startTest(additionalVmOpts), 0, "Unexpected exit code for positive case: "241+ Arrays.toString(additionalVmOpts));242}243244public void negativeTest(String... additionalVmOpts) {245Asserts.assertNE(startTest(additionalVmOpts), 0, "Unexpected exit code for negative case: "246+ Arrays.toString(additionalVmOpts));247}248249public void nonTieredTests(int compLevel) {250int replayDataCompLevel = getCompLevelFromReplay();251if (replayDataCompLevel == compLevel) {252positiveTest(TIERED_DISABLED_VM_OPTION);253} else {254negativeTest(TIERED_DISABLED_VM_OPTION);255}256}257258private String[] getTestJvmCommandlineWithPrefix(String prefix, String... args) {259try {260String cmd = ProcessTools.getCommandLine(ProcessTools.createTestJvm(args));261return new String[]{"sh", "-c", prefix262+ (Platform.isWindows() ? cmd.replace('\\', '/').replace(";", "\\;").replace("|", "\\|") : cmd)};263} catch(Throwable t) {264throw new Error("Can't create process builder: " + t, t);265}266}267}268269270