1 /* 2 * Copyright (c) 2014, 2016, 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 /* @test LimitSharedSizes 25 * @summary Test handling of limits on shared space size 26 * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true) 27 * @library /test/lib /runtime/CommandLine/OptionsValidation/common 28 * @modules java.base/jdk.internal.misc 29 * java.management 30 * jdk.attach/sun.tools.attach 31 * @run main LimitSharedSizes 32 */ 33 34 import jdk.test.lib.process.ProcessTools; 35 import jdk.test.lib.process.OutputAnalyzer; 36 import jdk.test.lib.Platform; 37 import optionsvalidation.JVMOptionsUtils; 38 39 public class LimitSharedSizes { 40 static enum Result { 41 OUT_OF_RANGE, 42 TOO_SMALL, 43 VALID, 44 VALID_ARCHIVE 45 } 46 47 static enum Region { 48 RO, RW, MD, MC 49 } 50 51 private static final boolean fitsRange(String name, String value) throws RuntimeException { 52 boolean fits = true; 53 try { 54 fits = JVMOptionsUtils.fitsRange(name, value); 55 } catch (Exception e) { 56 throw new RuntimeException(e.getMessage()); 57 } 58 return fits; 59 } 60 61 private static class SharedSizeTestData { 62 public String optionName; 63 public String optionValue; 64 public Result optionResult; 65 66 public SharedSizeTestData(Region region, String value) { 67 optionName = "-XX:"+getName(region); 68 optionValue = value; 69 if (fitsRange(getName(region), value) == false) { 70 optionResult = Result.OUT_OF_RANGE; 71 } else { 72 optionResult = Result.TOO_SMALL; 73 } 74 } 75 76 public SharedSizeTestData(Region region, String value, Result result) { 77 optionName = "-XX:"+getName(region); 78 optionValue = value; 79 optionResult = result; 80 } 81 82 private String getName(Region region) { 83 String name; 84 switch (region) { 85 case RO: 86 name = "SharedReadOnlySize"; 87 break; 88 case RW: 89 name = "SharedReadWriteSize"; 90 break; 91 case MD: 92 name = "SharedMiscDataSize"; 93 break; 94 case MC: 95 name = "SharedMiscCodeSize"; 96 break; 97 default: 98 name = "Unknown"; 99 break; 100 } 101 return name; 102 } 103 104 public Result getResult() { 105 return optionResult; 106 } 107 } 108 109 private static final SharedSizeTestData[] testTable = { 110 // Too small of a region size should not cause a vm crash. 111 // It should result in an error message either like the following #1: 112 // The shared miscellaneous code space is not large enough 113 // to preload requested classes. Use -XX:SharedMiscCodeSize= 114 // to increase the initial size of shared miscellaneous code space. 115 // or #2: 116 // The shared miscellaneous code space is outside the allowed range 117 new SharedSizeTestData(Region.RO, "4M"), 118 new SharedSizeTestData(Region.RW, "4M"), 119 new SharedSizeTestData(Region.MD, "50k"), 120 new SharedSizeTestData(Region.MC, "20k"), 121 122 // these values are larger than default ones, and should 123 // be acceptable and not cause failure 124 new SharedSizeTestData(Region.RO, "20M", Result.VALID), 125 new SharedSizeTestData(Region.RW, "20M", Result.VALID), 126 new SharedSizeTestData(Region.MD, "20M", Result.VALID), 127 new SharedSizeTestData(Region.MC, "20M", Result.VALID), 128 129 // test with sizes which just meet the minimum required sizes 130 // the following tests also attempt to use the shared archive 131 new SharedSizeTestData(Region.RO, Platform.is64bit() ? "10M":"9M", Result.VALID_ARCHIVE), 132 new SharedSizeTestData(Region.RW, Platform.is64bit() ? "12M":"7M", Result.VALID_ARCHIVE), 133 new SharedSizeTestData(Region.MD, Platform.is64bit() ? "4M":"2M", Result.VALID_ARCHIVE), 134 new SharedSizeTestData(Region.MC, "120k", Result.VALID_ARCHIVE), 135 }; 136 137 public static void main(String[] args) throws Exception { 138 int counter = 0; 139 for (SharedSizeTestData td : testTable) { 140 String fileName = "LimitSharedSizes" + counter + ".jsa"; 141 counter++; 142 143 String option = td.optionName + "=" + td.optionValue; 144 System.out.println("testing option number <" + counter + ">"); 145 System.out.println("testing option <" + option + ">"); 146 147 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 148 "-XX:+UnlockDiagnosticVMOptions", 149 "-XX:SharedArchiveFile=./" + fileName, 150 option, 151 "-Xshare:dump"); 152 153 OutputAnalyzer output = new OutputAnalyzer(pb.start()); 154 155 switch (td.getResult()) { 156 case VALID: 157 case VALID_ARCHIVE: 158 { 159 output.shouldNotContain("space is not large enough"); 160 output.shouldHaveExitValue(0); 161 162 if (td.getResult() == Result.VALID_ARCHIVE) { 163 // try to use the archive 164 pb = ProcessTools.createJavaProcessBuilder( 165 "-XX:+UnlockDiagnosticVMOptions", 166 "-XX:SharedArchiveFile=./" + fileName, 167 "-XX:+PrintSharedArchiveAndExit", 168 "-version"); 169 170 try { 171 output = new OutputAnalyzer(pb.start()); 172 output.shouldContain("archive is valid"); 173 } catch (RuntimeException e) { 174 // if sharing failed due to ASLR or similar reasons, 175 // check whether sharing was attempted at all (UseSharedSpaces) 176 if ((output.getOutput().contains("Unable to use shared archive") || 177 output.getOutput().contains("Unable to map ReadOnly shared space at required address.") || 178 output.getOutput().contains("Unable to map ReadWrite shared space at required address.") || 179 output.getOutput().contains("Unable to reserve shared space at required address")) && 180 output.getExitValue() == 1) { 181 System.out.println("Unable to use shared archive: test not executed; assumed passed"); 182 continue; 183 } 184 } 185 output.shouldHaveExitValue(0); 186 } 187 } 188 break; 189 case TOO_SMALL: 190 { 191 output.shouldContain("space is not large enough"); 192 output.shouldHaveExitValue(2); 193 } 194 break; 195 case OUT_OF_RANGE: 196 { 197 output.shouldContain("outside the allowed range"); 198 output.shouldHaveExitValue(1); 199 } 200 break; 201 } 202 } 203 } 204 }