1 /* 2 * Copyright (c) 2013, 2021, 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 * @test 26 * @bug 8024927 27 * @summary Testing address of compressed class pointer space as best as possible. 28 * @requires vm.bits == 64 & !vm.graal.enabled 29 * @requires vm.flagless 30 * @library /test/lib 31 * @modules java.base/jdk.internal.misc 32 * java.management 33 * @run driver CompressedClassPointers 34 */ 35 36 import jdk.test.lib.Platform; 37 import jdk.test.lib.process.ProcessTools; 38 import jdk.test.lib.process.OutputAnalyzer; 39 import jtreg.SkippedException; 40 41 public class CompressedClassPointers { 42 43 static final String logging_option = "-Xlog:gc+metaspace=trace,cds=trace"; 44 45 // Returns true if we are to test the narrow klass base; we only do this on 46 // platforms where we can be reasonably shure that we get reproducable placement). 47 static boolean testNarrowKlassBase() { 48 if (Platform.isWindows()) { 49 return false; 50 } 51 return true; 52 53 } 54 55 // CDS off, small heap, ccs size default (1G) 56 // A small heap should allow us to place the ccs within the lower 32G and thus allow zero based encoding. 57 public static void smallHeapTest() throws Exception { 58 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 59 "-XX:+UnlockDiagnosticVMOptions", 60 "-XX:SharedBaseAddress=8g", 61 "-Xmx128m", 62 logging_option, 63 "-Xshare:off", 64 "-XX:+VerifyBeforeGC", "-version"); 65 OutputAnalyzer output = new OutputAnalyzer(pb.start()); 66 if (testNarrowKlassBase()) { 67 output.shouldContain("Narrow klass base: 0x0000000000000000"); 68 } 69 output.shouldHaveExitValue(0); 70 } 71 72 // CDS off, small heap, ccs size explicitely set to 1G 73 // A small heap should allow us to place the ccs within the lower 32G and thus allow zero based encoding. 74 public static void smallHeapTestWith1G() throws Exception { 75 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 76 "-XX:+UnlockDiagnosticVMOptions", 77 "-XX:CompressedClassSpaceSize=1g", 78 "-Xmx128m", 79 logging_option, 80 "-Xshare:off", 81 "-XX:+VerifyBeforeGC", "-version"); 82 OutputAnalyzer output = new OutputAnalyzer(pb.start()); 83 if (testNarrowKlassBase()) { 84 output.shouldContain("Narrow klass base: 0x0000000000000000, Narrow klass shift: 3"); 85 } 86 output.shouldHaveExitValue(0); 87 } 88 89 // CDS off, a very large heap, ccs size left to 1G default. 90 // We expect the ccs to be mapped somewhere far beyond the heap, such that it is not possible 91 // to use zero based encoding. 92 public static void largeHeapTest() throws Exception { 93 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 94 "-XX:+UnlockDiagnosticVMOptions", 95 "-XX:+UnlockExperimentalVMOptions", 96 "-Xmx30g", 97 logging_option, 98 "-Xshare:off", 99 "-XX:+VerifyBeforeGC", "-version"); 100 OutputAnalyzer output = new OutputAnalyzer(pb.start()); 101 if (testNarrowKlassBase() && !Platform.isPPC() && !Platform.isOSX()) { 102 // PPC: in most cases the heap cannot be placed below 32g so there 103 // is room for ccs and narrow klass base will be 0x0. Exception: 104 // Linux 4.1.42 or earlier (see ELF_ET_DYN_BASE in JDK-8244847). 105 // For simplicity we exclude PPC. 106 // OSX: similar. 107 output.shouldNotContain("Narrow klass base: 0x0000000000000000"); 108 output.shouldContain("Narrow klass shift: 0"); 109 } 110 output.shouldHaveExitValue(0); 111 } 112 113 // Settings as in largeHeapTest() except for max heap size. We make max heap 114 // size even larger such that it cannot fit into lower 32G but not too large 115 // for compressed oops. 116 // We expect a zerobased ccs. 117 public static void largeHeapAbove32GTest() throws Exception { 118 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 119 "-XX:+UnlockDiagnosticVMOptions", 120 "-XX:+UnlockExperimentalVMOptions", 121 "-Xmx31g", 122 logging_option, 123 "-Xshare:off", 124 "-XX:+VerifyBeforeGC", "-version"); 125 OutputAnalyzer output = new OutputAnalyzer(pb.start()); 126 if (testNarrowKlassBase()) { 127 if (!(Platform.isAArch64() && Platform.isOSX())) { // see JDK-8262895 128 output.shouldContain("Narrow klass base: 0x0000000000000000"); 129 if (!Platform.isAArch64() && !Platform.isOSX()) { 130 output.shouldContain("Narrow klass shift: 0"); 131 } 132 } 133 } 134 output.shouldHaveExitValue(0); 135 } 136 137 // Using large paged heap, metaspace uses small pages. 138 public static void largePagesForHeapTest() throws Exception { 139 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 140 "-XX:+UnlockDiagnosticVMOptions", 141 "-Xmx128m", 142 "-XX:+UseLargePages", 143 logging_option, 144 "-XX:+VerifyBeforeGC", "-version"); 145 OutputAnalyzer output = new OutputAnalyzer(pb.start()); 146 if (testNarrowKlassBase()) { 147 output.shouldContain("Narrow klass base:"); 148 } 149 output.shouldHaveExitValue(0); 150 } 151 152 public static void heapBaseMinAddressTest() throws Exception { 153 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 154 "-XX:HeapBaseMinAddress=1m", 155 "-Xlog:gc+heap+coops=debug", 156 "-version"); 157 OutputAnalyzer output = new OutputAnalyzer(pb.start()); 158 output.shouldContain("HeapBaseMinAddress must be at least"); 159 output.shouldHaveExitValue(0); 160 } 161 162 public static void sharingTest() throws Exception { 163 // Test small heaps 164 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 165 "-XX:+UnlockDiagnosticVMOptions", 166 "-XX:SharedArchiveFile=./CompressedClassPointers.jsa", 167 "-Xmx128m", 168 "-XX:SharedBaseAddress=8g", 169 "-XX:+VerifyBeforeGC", 170 "-Xshare:dump", 171 "-Xlog:cds,gc+heap+coops=debug"); 172 OutputAnalyzer output = new OutputAnalyzer(pb.start()); 173 if (output.firstMatch("Shared spaces are not supported in this VM") != null) { 174 return; 175 } 176 try { 177 output.shouldContain("Loading classes to share"); 178 output.shouldHaveExitValue(0); 179 180 pb = ProcessTools.createJavaProcessBuilder( 181 "-XX:+UnlockDiagnosticVMOptions", 182 "-XX:SharedArchiveFile=./CompressedClassPointers.jsa", 183 "-Xmx128m", 184 "-XX:SharedBaseAddress=8g", 185 "-Xlog:gc+heap+coops=debug", 186 "-Xshare:on", 187 "-version"); 188 output = new OutputAnalyzer(pb.start()); 189 output.shouldContain("sharing"); 190 output.shouldHaveExitValue(0); 191 192 } catch (RuntimeException e) { 193 output.shouldContain("Unable to use shared archive"); 194 output.shouldHaveExitValue(1); 195 } 196 } 197 198 public static void smallHeapTestNoCoop() throws Exception { 199 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 200 "-XX:-UseCompressedOops", 201 "-XX:+UseCompressedClassPointers", 202 "-XX:+UnlockDiagnosticVMOptions", 203 "-XX:SharedBaseAddress=8g", 204 "-Xmx128m", 205 "-Xlog:gc+metaspace=trace", 206 "-Xshare:off", 207 "-Xlog:cds=trace", 208 "-XX:+VerifyBeforeGC", "-version"); 209 OutputAnalyzer output = new OutputAnalyzer(pb.start()); 210 output.shouldContain("Narrow klass base: 0x0000000000000000"); 211 output.shouldHaveExitValue(0); 212 } 213 214 public static void smallHeapTestWith1GNoCoop() throws Exception { 215 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 216 "-XX:-UseCompressedOops", 217 "-XX:+UseCompressedClassPointers", 218 "-XX:+UnlockDiagnosticVMOptions", 219 "-XX:CompressedClassSpaceSize=1g", 220 "-Xmx128m", 221 "-Xlog:gc+metaspace=trace", 222 "-Xshare:off", 223 "-Xlog:cds=trace", 224 "-XX:+VerifyBeforeGC", "-version"); 225 OutputAnalyzer output = new OutputAnalyzer(pb.start()); 226 output.shouldContain("Narrow klass base: 0x0000000000000000"); 227 if (!Platform.isAArch64() && !Platform.isPPC()) { 228 // Currently relax this test for Aarch64 and ppc. 229 output.shouldContain("Narrow klass shift: 0"); 230 } 231 output.shouldHaveExitValue(0); 232 } 233 234 public static void largeHeapTestNoCoop() throws Exception { 235 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 236 "-XX:-UseCompressedOops", 237 "-XX:+UseCompressedClassPointers", 238 "-XX:+UnlockDiagnosticVMOptions", 239 "-XX:+UnlockExperimentalVMOptions", 240 "-Xmx30g", 241 "-Xlog:gc+metaspace=trace", 242 "-Xshare:off", 243 "-Xlog:cds=trace", 244 "-XX:+VerifyBeforeGC", "-version"); 245 OutputAnalyzer output = new OutputAnalyzer(pb.start()); 246 output.shouldContain("Narrow klass base: 0x0000000000000000"); 247 if (!Platform.isAArch64() && !Platform.isPPC()) { 248 // Currently relax this test for Aarch64 and ppc. 249 output.shouldContain("Narrow klass shift: 0"); 250 } 251 output.shouldHaveExitValue(0); 252 } 253 254 public static void largePagesTestNoCoop() throws Exception { 255 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 256 "-XX:-UseCompressedOops", 257 "-XX:+UseCompressedClassPointers", 258 "-XX:+UnlockDiagnosticVMOptions", 259 "-Xmx128m", 260 "-XX:+UseLargePages", 261 "-Xlog:gc+metaspace=trace", 262 "-XX:+VerifyBeforeGC", "-version"); 263 OutputAnalyzer output = new OutputAnalyzer(pb.start()); 264 output.shouldContain("Narrow klass base:"); 265 output.shouldHaveExitValue(0); 266 } 267 268 public static void heapBaseMinAddressTestNoCoop() throws Exception { 269 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 270 "-XX:-UseCompressedOops", 271 "-XX:+UseCompressedClassPointers", 272 "-XX:HeapBaseMinAddress=1m", 273 "-Xlog:gc+heap+coops=debug", 274 "-version"); 275 OutputAnalyzer output = new OutputAnalyzer(pb.start()); 276 output.shouldContain("HeapBaseMinAddress must be at least"); 277 output.shouldHaveExitValue(0); 278 } 279 280 public static void sharingTestNoCoop() throws Exception { 281 // Test small heaps 282 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( 283 "-XX:-UseCompressedOops", 284 "-XX:+UseCompressedClassPointers", 285 "-XX:+UnlockDiagnosticVMOptions", 286 "-XX:SharedArchiveFile=./CompressedClassPointers.jsa", 287 "-Xmx128m", 288 "-XX:SharedBaseAddress=8g", 289 "-XX:+VerifyBeforeGC", 290 "-Xshare:dump", 291 "-Xlog:cds,gc+heap+coops=debug"); 292 OutputAnalyzer output = new OutputAnalyzer(pb.start()); 293 if (output.firstMatch("Shared spaces are not supported in this VM") != null) { 294 return; 295 } 296 try { 297 output.shouldContain("Loading classes to share"); 298 output.shouldHaveExitValue(0); 299 300 pb = ProcessTools.createJavaProcessBuilder( 301 "-XX:-UseCompressedOops", 302 "-XX:+UseCompressedClassPointers", 303 "-XX:+UnlockDiagnosticVMOptions", 304 "-XX:SharedArchiveFile=./CompressedClassPointers.jsa", 305 "-Xmx128m", 306 "-XX:SharedBaseAddress=8g", 307 "-Xlog:gc+heap+coops=debug", 308 "-Xshare:on", 309 "-version"); 310 output = new OutputAnalyzer(pb.start()); 311 output.shouldContain("sharing"); 312 output.shouldHaveExitValue(0); 313 314 } catch (RuntimeException e) { 315 output.shouldContain("Unable to use shared archive"); 316 output.shouldHaveExitValue(1); 317 } 318 } 319 320 public static void main(String[] args) throws Exception { 321 smallHeapTest(); 322 smallHeapTestWith1G(); 323 largeHeapTest(); 324 largeHeapAbove32GTest(); 325 largePagesForHeapTest(); 326 heapBaseMinAddressTest(); 327 sharingTest(); 328 329 if (!Platform.isOSX()) { 330 // Testing compressed class pointers without compressed oops. 331 // This is only possible if the platform supports it. Notably, 332 // on macOS, when compressed oops is disabled and the heap is 333 // given an arbitrary address, that address occasionally collides 334 // with where we would ideally have placed the compressed class 335 // space. Therefore, macOS is omitted for now. 336 smallHeapTestNoCoop(); 337 smallHeapTestWith1GNoCoop(); 338 largeHeapTestNoCoop(); 339 largePagesTestNoCoop(); 340 heapBaseMinAddressTestNoCoop(); 341 sharingTestNoCoop(); 342 } 343 } 344 } --- EOF ---