1 /* 2 * Copyright (c) 2015, 2020, 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 25 // NOTE: the test takes a long time for each VM option combination, so we split 26 // it into 3 @test parts, so that they can be executed in parallel. If you make a 27 // change, please ensure all @test blocks are in sync. 28 29 30 /* 31 * @test 32 * @summary Test options that are incompatible with use of shared strings 33 * Also test mismatch in oops encoding between dump time and run time 34 * @requires vm.cds.archived.java.heap 35 * @comment This test explicitly chooses the type of GC to be used by sub-processes. It may conflict with the GC type set 36 * via the -vmoptions command line option of JTREG. vm.gc==null will help the test case to discard the explicitly passed 37 * vm options. 38 * @requires (vm.gc=="null") 39 * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds 40 * @build sun.hotspot.WhiteBox 41 * @run driver ClassFileInstaller sun.hotspot.WhiteBox 42 * @build HelloString 43 * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. IncompatibleOptions 0 44 */ 45 46 47 /* 48 * @test 49 * @requires vm.cds.archived.java.heap 50 * @requires (vm.gc=="null") 51 * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds 52 * @build sun.hotspot.WhiteBox 53 * @run driver ClassFileInstaller sun.hotspot.WhiteBox 54 * @build HelloString 55 * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. IncompatibleOptions 1 56 */ 57 58 /* 59 * @test 60 * @requires vm.cds.archived.java.heap 61 * @requires (vm.gc=="null") 62 * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds 63 * @build sun.hotspot.WhiteBox 64 * @run driver ClassFileInstaller sun.hotspot.WhiteBox 65 * @build HelloString 66 * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. IncompatibleOptions 2 67 */ 68 69 70 import jdk.test.lib.Asserts; 71 import jdk.test.lib.Platform; 72 import jdk.test.lib.process.OutputAnalyzer; 73 74 import sun.hotspot.code.Compiler; 75 import sun.hotspot.gc.GC; 76 77 public class IncompatibleOptions { 78 static final String COOPS_DUMP_WARNING = 79 "Cannot dump shared archive when UseCompressedOops or UseCompressedClassPointers is off"; 80 static final String GC_WARNING = 81 "Archived java heap is not supported"; 82 static final String OBJ_ALIGNMENT_MISMATCH = 83 "The shared archive file's ObjectAlignmentInBytes of .* does not equal the current ObjectAlignmentInBytes of"; 84 static final String COMPACT_STRING_MISMATCH = 85 "The shared archive file's CompactStrings setting .* does not equal the current CompactStrings setting"; 86 static final String COMPRESSED_OOPS_NOT_CONSISTENT = 87 "The saved state of UseCompressedOops and UseCompressedClassPointers is different from runtime, CDS will be disabled."; 88 static String appJar; 89 static String[] vmOptionsPrefix = {}; 90 91 public static void main(String[] args) throws Exception { 92 String[] noargs = {}; 93 SharedStringsUtils.run(Integer.parseInt(args[0]), 3, noargs, IncompatibleOptions::test); 94 // Add a new @test block if you get an assert ----^ about this number. See 95 // SharedStringsUtils.java for details. 96 } 97 98 public static void test(String[] args_ignored) throws Exception { 99 vmOptionsPrefix = SharedStringsUtils.getChildVMOptionsPrefix(); 100 appJar = JarBuilder.build("IncompatibleOptions", "HelloString"); 101 102 // Uncompressed OOPs 103 testDump(1, "-XX:+UseG1GC", "-XX:-UseCompressedOops", null, false); 104 if (GC.Z.isSupported()) { 105 testDump(1, "-XX:+UseZGC", "-XX:-UseCompressedOops", null, false); 106 } 107 108 // incompatible GCs 109 testDump(2, "-XX:+UseParallelGC", "", GC_WARNING, false); 110 testDump(3, "-XX:+UseSerialGC", "", GC_WARNING, false); 111 112 // Explicitly archive with compressed oops, run without. 113 testDump(5, "-XX:+UseG1GC", "-XX:+UseCompressedOops", null, false); 114 testExec(5, "-XX:+UseG1GC", "-XX:-UseCompressedOops", 115 COMPRESSED_OOPS_NOT_CONSISTENT, true); 116 117 // NOTE: No warning is displayed, by design 118 // Still run, to ensure no crash or exception 119 testExec(6, "-XX:+UseParallelGC", "", "", false); 120 testExec(7, "-XX:+UseSerialGC", "", "", false); 121 122 // Test various oops encodings, by varying ObjectAlignmentInBytes and heap sizes 123 testDump(9, "-XX:+UseG1GC", "-XX:ObjectAlignmentInBytes=8", null, false); 124 testExec(9, "-XX:+UseG1GC", "-XX:ObjectAlignmentInBytes=16", 125 OBJ_ALIGNMENT_MISMATCH, true); 126 127 // Implicitly archive with compressed oops, run without. 128 // Max heap size for compressed oops is around 31G. 129 // UseCompressedOops is turned on by default when heap 130 // size is under 31G, but will be turned off when heap 131 // size is greater than that. 132 testDump(10, "-XX:+UseG1GC", "-Xmx1g", null, false); 133 testExec(10, "-XX:+UseG1GC", "-Xmx32g", null, true); 134 // Explicitly archive without compressed oops and run with. 135 testDump(11, "-XX:+UseG1GC", "-XX:-UseCompressedOops", null, false); 136 testExec(11, "-XX:+UseG1GC", "-XX:+UseCompressedOops", null, true); 137 // Implicitly archive without compressed oops and run with. 138 testDump(12, "-XX:+UseG1GC", "-Xmx32G", null, false); 139 testExec(12, "-XX:+UseG1GC", "-Xmx1GG", null, true); 140 // CompactStrings must match between dump time and run time 141 testDump(13, "-XX:+UseG1GC", "-XX:-CompactStrings", null, false); 142 testExec(13, "-XX:+UseG1GC", "-XX:+CompactStrings", 143 COMPACT_STRING_MISMATCH, true); 144 testDump(14, "-XX:+UseG1GC", "-XX:+CompactStrings", null, false); 145 testExec(14, "-XX:+UseG1GC", "-XX:-CompactStrings", 146 COMPACT_STRING_MISMATCH, true); 147 } 148 149 static void testDump(int testCaseNr, String collectorOption, String extraOption, 150 String expectedWarning, boolean expectedToFail) throws Exception { 151 152 System.out.println("Testcase: " + testCaseNr); 153 OutputAnalyzer output = TestCommon.dump(appJar, TestCommon.list("Hello"), 154 TestCommon.concat(vmOptionsPrefix, 155 "-XX:+UseCompressedOops", 156 collectorOption, 157 "-XX:SharedArchiveConfigFile=" + TestCommon.getSourceFile("SharedStringsBasic.txt"), 158 "-Xlog:cds,cds+hashtables", 159 extraOption)); 160 161 if (expectedWarning != null) { 162 output.shouldContain(expectedWarning); 163 } 164 165 if (expectedToFail) { 166 Asserts.assertNE(output.getExitValue(), 0, 167 "JVM is expected to fail, but did not"); 168 } 169 } 170 171 static void testExec(int testCaseNr, String collectorOption, String extraOption, 172 String expectedWarning, boolean expectedToFail) throws Exception { 173 174 OutputAnalyzer output; 175 System.out.println("Testcase: " + testCaseNr); 176 177 // needed, otherwise system considers empty extra option as a 178 // main class param, and fails with "Could not find or load main class" 179 if (!extraOption.isEmpty()) { 180 output = TestCommon.exec(appJar, 181 TestCommon.concat(vmOptionsPrefix, 182 "-XX:+UseCompressedOops", 183 collectorOption, "-Xlog:cds", extraOption, "HelloString")); 184 } else { 185 output = TestCommon.exec(appJar, 186 TestCommon.concat(vmOptionsPrefix, 187 "-XX:+UseCompressedOops", 188 collectorOption, "-Xlog:cds", "HelloString")); 189 } 190 191 if (expectedWarning != null) { 192 output.shouldMatch(expectedWarning); 193 } 194 195 if (expectedToFail) { 196 Asserts.assertNE(output.getExitValue(), 0); 197 } else { 198 SharedStringsUtils.checkExec(output); 199 } 200 } 201 }