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