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