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