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