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 /* 25 * @test 26 * @bug 8022865 27 * @summary Tests for different combination of UseCompressedOops options 28 * @library /test/lib 29 * @ignore 8079353 30 * @modules java.base/jdk.internal.misc 31 * java.management 32 * @run main UseCompressedOops 33 */ 34 import java.util.ArrayList; 35 import java.util.Collections; 36 import jdk.test.lib.Platform; 37 import jdk.test.lib.process.ProcessTools; 38 import jdk.test.lib.process.OutputAnalyzer; 39 40 public class UseCompressedOops { 41 42 public static void main(String[] args) throws Exception { 43 testCompressedOopsModesGCs(); 44 testCompressedOopsModesGCs("-XX:+UseLargePages"); 45 } 46 47 public static void testCompressedOopsModesGCs(String... flags) throws Exception { 48 ArrayList<String> args = new ArrayList<>(); 49 Collections.addAll(args, flags); 50 51 // Test default. 52 testCompressedOopsModes(args); 53 // Test GCs. 54 testCompressedOopsModes(args, "-XX:+UseG1GC"); 55 testCompressedOopsModes(args, "-XX:+UseConcMarkSweepGC"); 56 testCompressedOopsModes(args, "-XX:+UseSerialGC"); 57 testCompressedOopsModes(args, "-XX:+UseParallelGC"); 58 testCompressedOopsModes(args, "-XX:+UseParallelOldGC"); 59 } 60 61 public static void testCompressedOopsModes(ArrayList<String> flags1, String... flags2) throws Exception { 62 ArrayList<String> args = new ArrayList<>(); 63 args.addAll(flags1); 64 Collections.addAll(args, flags2); 65 66 if (Platform.is64bit()) { 67 // Explicitly turn of compressed oops 68 testCompressedOops(args, "-XX:-UseCompressedOops", "-Xmx32m") 69 .shouldNotContain("Compressed Oops") 70 .shouldHaveExitValue(0); 71 72 // Compressed oops should be on by default 73 testCompressedOops(args, "-Xmx32m") 74 .shouldContain("Compressed Oops mode") 75 .shouldHaveExitValue(0); 76 77 // Explicly enabling compressed oops 78 testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32m") 79 .shouldContain("Compressed Oops mode") 80 .shouldHaveExitValue(0); 81 82 // Skip the following three test cases if we're on OSX or Solaris. 83 // 84 // OSX doesn't seem to care about HeapBaseMinAddress and Solaris 85 // puts the heap way up, forcing different behaviour. 86 if (!Platform.isOSX() && !Platform.isSolaris()) { 87 // Larger than 4gb heap should result in zero based with shift 3 88 testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx5g") 89 .shouldContain("Zero based") 90 .shouldContain("Oop shift amount: 3") 91 .shouldHaveExitValue(0); 92 93 // Larger than 3gb heap and HeapBaseMinAddress=1g should result in zero based with shift 3 94 testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx3200m", "-XX:HeapBaseMinAddress=1g") 95 .shouldContain("Zero based") 96 .shouldContain("Oop shift amount: 3") 97 .shouldHaveExitValue(0); 98 99 // Small heap above 4gb should result in zero based with shift 3 100 testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32m", "-XX:HeapBaseMinAddress=4g") 101 .shouldContain("Zero based") 102 .shouldContain("Oop shift amount: 3") 103 .shouldHaveExitValue(0); 104 105 // Small heap above 32gb should result in non-zero based with shift 3 106 testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32m", "-XX:HeapBaseMinAddress=32g") 107 .shouldContain("Non-zero disjoint base") 108 .shouldContain("Oop shift amount: 3") 109 .shouldHaveExitValue(0); 110 111 // Small heap above 32gb should result in non-zero based with shift 3 112 testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32m", "-XX:HeapBaseMinAddress=72704m") 113 .shouldContain("Non-zero based") 114 .shouldContain("Oop shift amount: 3") 115 .shouldHaveExitValue(0); 116 117 // 32gb heap with heap base above 64gb and object alignment set to 16 bytes should result 118 // in non-zero based with shift 4 119 testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32g", "-XX:ObjectAlignmentInBytes=16", 120 "-XX:HeapBaseMinAddress=64g") 121 .shouldContain("Non-zero disjoint base") 122 .shouldContain("Oop shift amount: 4") 123 .shouldHaveExitValue(0); 124 125 // 32gb heap with object alignment set to 16 bytes should result in zero based with shift 4 126 testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32g", "-XX:ObjectAlignmentInBytes=16") 127 .shouldContain("Zero based") 128 .shouldContain("Oop shift amount: 4") 129 .shouldHaveExitValue(0); 130 } 131 132 // This is a pathologic case for the heap allocation algorithm. Regression test. 133 // HeapBaseMinAddress must be 2g and should not be set on the command line. 134 testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx2g") 135 .shouldNotContain("Max heap size too large for Compressed Oops") 136 .shouldHaveExitValue(0); 137 testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx29g", "-XX:CompressedClassSpaceSize=1g") 138 .shouldNotContain("Max heap size too large for Compressed Oops") 139 .shouldHaveExitValue(0); 140 141 // Explicitly enabling compressed oops with 32gb heap should result a warning 142 testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32g") 143 .shouldContain("Max heap size too large for Compressed Oops") 144 .shouldHaveExitValue(0); 145 146 // 32gb heap should not result a warning 147 testCompressedOops(args, "-Xmx32g") 148 .shouldNotContain("Max heap size too large for Compressed Oops") 149 .shouldHaveExitValue(0); 150 151 // Explicitly enabling compressed oops with 32gb heap and object 152 // alignment set to 8 byte should result a warning 153 testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32g", "-XX:ObjectAlignmentInBytes=8") 154 .shouldContain("Max heap size too large for Compressed Oops") 155 .shouldHaveExitValue(0); 156 157 // 64gb heap and object alignment set to 16 bytes should result in a warning 158 testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx64g", "-XX:ObjectAlignmentInBytes=16") 159 .shouldContain("Max heap size too large for Compressed Oops") 160 .shouldHaveExitValue(0); 161 162 } else { 163 // Compressed oops should only apply to 64bit platforms 164 testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32m") 165 .shouldContain("Unrecognized VM option 'UseCompressedOops'") 166 .shouldHaveExitValue(1); 167 } 168 } 169 170 private static OutputAnalyzer testCompressedOops(ArrayList<String> flags1, String... flags2) throws Exception { 171 ArrayList<String> args = new ArrayList<>(); 172 173 // Always run with these three: 174 args.add("-XX:+PrintCompressedOopsMode"); 175 args.add("-Xms32m"); 176 177 // Add the extra flags 178 args.addAll(flags1); 179 Collections.addAll(args, flags2); 180 181 args.add("-version"); 182 183 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args.toArray(new String[0])); 184 return new OutputAnalyzer(pb.start()); 185 } 186 }