test/gc/arguments/TestUseCompressedOopsErgoTools.java

Wed, 11 Sep 2013 16:25:02 +0200

author
tschatzl
date
Wed, 11 Sep 2013 16:25:02 +0200
changeset 5701
40136aa2cdb1
child 5717
2f426063daea
permissions
-rw-r--r--

8010722: assert: failed: heap size is too big for compressed oops
Summary: Use conservative assumptions of required alignment for the various garbage collector components into account when determining the maximum heap size that supports compressed oops. Using this conservative value avoids several circular dependencies in the calculation.
Reviewed-by: stefank, dholmes

tschatzl@5701 1 /*
tschatzl@5701 2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
tschatzl@5701 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
tschatzl@5701 4 *
tschatzl@5701 5 * This code is free software; you can redistribute it and/or modify it
tschatzl@5701 6 * under the terms of the GNU General Public License version 2 only, as
tschatzl@5701 7 * published by the Free Software Foundation.
tschatzl@5701 8 *
tschatzl@5701 9 * This code is distributed in the hope that it will be useful, but WITHOUT
tschatzl@5701 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
tschatzl@5701 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
tschatzl@5701 12 * version 2 for more details (a copy is included in the LICENSE file that
tschatzl@5701 13 * accompanied this code).
tschatzl@5701 14 *
tschatzl@5701 15 * You should have received a copy of the GNU General Public License version
tschatzl@5701 16 * 2 along with this work; if not, write to the Free Software Foundation,
tschatzl@5701 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
tschatzl@5701 18 *
tschatzl@5701 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
tschatzl@5701 20 * or visit www.oracle.com if you need additional information or have any
tschatzl@5701 21 * questions.
tschatzl@5701 22 */
tschatzl@5701 23
tschatzl@5701 24 import sun.management.ManagementFactoryHelper;
tschatzl@5701 25 import com.sun.management.HotSpotDiagnosticMXBean;
tschatzl@5701 26 import com.sun.management.VMOption;
tschatzl@5701 27
tschatzl@5701 28 import java.util.regex.Matcher;
tschatzl@5701 29 import java.util.regex.Pattern;
tschatzl@5701 30 import java.util.ArrayList;
tschatzl@5701 31 import java.util.Arrays;
tschatzl@5701 32
tschatzl@5701 33 import com.oracle.java.testlibrary.*;
tschatzl@5701 34 import sun.hotspot.WhiteBox;
tschatzl@5701 35
tschatzl@5701 36 class DetermineMaxHeapForCompressedOops {
tschatzl@5701 37 public static void main(String[] args) throws Exception {
tschatzl@5701 38 WhiteBox wb = WhiteBox.getWhiteBox();
tschatzl@5701 39 System.out.print(wb.getCompressedOopsMaxHeapSize());
tschatzl@5701 40 }
tschatzl@5701 41 }
tschatzl@5701 42
tschatzl@5701 43 class TestUseCompressedOopsErgoTools {
tschatzl@5701 44
tschatzl@5701 45 private static long getClassMetaspaceSize() {
tschatzl@5701 46 HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean();
tschatzl@5701 47
tschatzl@5701 48 VMOption option = diagnostic.getVMOption("ClassMetaspaceSize");
tschatzl@5701 49 return Long.parseLong(option.getValue());
tschatzl@5701 50 }
tschatzl@5701 51
tschatzl@5701 52
tschatzl@5701 53 public static long getMaxHeapForCompressedOops(String[] vmargs) throws Exception {
tschatzl@5701 54 OutputAnalyzer output = runWhiteBoxTest(vmargs, DetermineMaxHeapForCompressedOops.class.getName(), new String[] {}, false);
tschatzl@5701 55 return Long.parseLong(output.getStdout());
tschatzl@5701 56 }
tschatzl@5701 57
tschatzl@5701 58 public static boolean is64bitVM() {
tschatzl@5701 59 String val = System.getProperty("sun.arch.data.model");
tschatzl@5701 60 if (val == null) {
tschatzl@5701 61 throw new RuntimeException("Could not read sun.arch.data.model");
tschatzl@5701 62 }
tschatzl@5701 63 if (val.equals("64")) {
tschatzl@5701 64 return true;
tschatzl@5701 65 } else if (val.equals("32")) {
tschatzl@5701 66 return false;
tschatzl@5701 67 }
tschatzl@5701 68 throw new RuntimeException("Unexpected value " + val + " of sun.arch.data.model");
tschatzl@5701 69 }
tschatzl@5701 70
tschatzl@5701 71 /**
tschatzl@5701 72 * Executes a new VM process with the given class and parameters.
tschatzl@5701 73 * @param vmargs Arguments to the VM to run
tschatzl@5701 74 * @param classname Name of the class to run
tschatzl@5701 75 * @param arguments Arguments to the class
tschatzl@5701 76 * @param useTestDotJavaDotOpts Use test.java.opts as part of the VM argument string
tschatzl@5701 77 * @return The OutputAnalyzer with the results for the invocation.
tschatzl@5701 78 */
tschatzl@5701 79 public static OutputAnalyzer runWhiteBoxTest(String[] vmargs, String classname, String[] arguments, boolean useTestDotJavaDotOpts) throws Exception {
tschatzl@5701 80 ArrayList<String> finalargs = new ArrayList<String>();
tschatzl@5701 81
tschatzl@5701 82 String[] whiteboxOpts = new String[] {
tschatzl@5701 83 "-Xbootclasspath/a:.",
tschatzl@5701 84 "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
tschatzl@5701 85 "-cp", System.getProperty("java.class.path"),
tschatzl@5701 86 };
tschatzl@5701 87
tschatzl@5701 88 if (useTestDotJavaDotOpts) {
tschatzl@5701 89 // System.getProperty("test.java.opts") is '' if no options is set,
tschatzl@5701 90 // we need to skip such a result
tschatzl@5701 91 String[] externalVMOpts = new String[0];
tschatzl@5701 92 if (System.getProperty("test.java.opts") != null && System.getProperty("test.java.opts").length() != 0) {
tschatzl@5701 93 externalVMOpts = System.getProperty("test.java.opts").split(" ");
tschatzl@5701 94 }
tschatzl@5701 95 finalargs.addAll(Arrays.asList(externalVMOpts));
tschatzl@5701 96 }
tschatzl@5701 97
tschatzl@5701 98 finalargs.addAll(Arrays.asList(vmargs));
tschatzl@5701 99 finalargs.addAll(Arrays.asList(whiteboxOpts));
tschatzl@5701 100 finalargs.add(classname);
tschatzl@5701 101 finalargs.addAll(Arrays.asList(arguments));
tschatzl@5701 102
tschatzl@5701 103 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(finalargs.toArray(new String[0]));
tschatzl@5701 104 OutputAnalyzer output = new OutputAnalyzer(pb.start());
tschatzl@5701 105 output.shouldHaveExitValue(0);
tschatzl@5701 106 return output;
tschatzl@5701 107 }
tschatzl@5701 108
tschatzl@5701 109 private static String[] join(String[] part1, String part2) {
tschatzl@5701 110 ArrayList<String> result = new ArrayList<String>();
tschatzl@5701 111 result.addAll(Arrays.asList(part1));
tschatzl@5701 112 result.add(part2);
tschatzl@5701 113 return result.toArray(new String[0]);
tschatzl@5701 114 }
tschatzl@5701 115
tschatzl@5701 116 public static void checkCompressedOopsErgo(String[] gcflags) throws Exception {
tschatzl@5701 117 long maxHeapForCompressedOops = getMaxHeapForCompressedOops(gcflags);
tschatzl@5701 118
tschatzl@5701 119 checkUseCompressedOops(gcflags, maxHeapForCompressedOops, true);
tschatzl@5701 120 checkUseCompressedOops(gcflags, maxHeapForCompressedOops - 1, true);
tschatzl@5701 121 checkUseCompressedOops(gcflags, maxHeapForCompressedOops + 1, false);
tschatzl@5701 122
tschatzl@5701 123 // the use of HeapBaseMinAddress should not change the outcome
tschatzl@5701 124 checkUseCompressedOops(join(gcflags, "-XX:HeapBaseMinAddress=32G"), maxHeapForCompressedOops, true);
tschatzl@5701 125 checkUseCompressedOops(join(gcflags, "-XX:HeapBaseMinAddress=32G"), maxHeapForCompressedOops - 1, true);
tschatzl@5701 126 checkUseCompressedOops(join(gcflags, "-XX:HeapBaseMinAddress=32G"), maxHeapForCompressedOops + 1, false);
tschatzl@5701 127
tschatzl@5701 128 // use a different object alignment
tschatzl@5701 129 maxHeapForCompressedOops = getMaxHeapForCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"));
tschatzl@5701 130
tschatzl@5701 131 checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops, true);
tschatzl@5701 132 checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops - 1, true);
tschatzl@5701 133 checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops + 1, false);
tschatzl@5701 134
tschatzl@5701 135 // use a different ClassMetaspaceSize
tschatzl@5701 136 String classMetaspaceSizeArg = "-XX:ClassMetaspaceSize=" + 2 * getClassMetaspaceSize();
tschatzl@5701 137 maxHeapForCompressedOops = getMaxHeapForCompressedOops(join(gcflags, classMetaspaceSizeArg));
tschatzl@5701 138
tschatzl@5701 139 checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops, true);
tschatzl@5701 140 checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops - 1, true);
tschatzl@5701 141 checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops + 1, false);
tschatzl@5701 142 }
tschatzl@5701 143
tschatzl@5701 144 private static void checkUseCompressedOops(String[] args, long heapsize, boolean expectUseCompressedOops) throws Exception {
tschatzl@5701 145 ArrayList<String> finalargs = new ArrayList<String>();
tschatzl@5701 146 finalargs.addAll(Arrays.asList(args));
tschatzl@5701 147 finalargs.add("-Xmx" + heapsize);
tschatzl@5701 148 finalargs.add("-XX:+PrintFlagsFinal");
tschatzl@5701 149 finalargs.add("-version");
tschatzl@5701 150
tschatzl@5701 151 String output = expectValid(finalargs.toArray(new String[0]));
tschatzl@5701 152
tschatzl@5701 153 boolean actualUseCompressedOops = getFlagBoolValue(" UseCompressedOops", output);
tschatzl@5701 154
tschatzl@5701 155 if (expectUseCompressedOops != actualUseCompressedOops) {
tschatzl@5701 156 throw new RuntimeException("Expected use of compressed oops: " + expectUseCompressedOops + " but was: " + actualUseCompressedOops);
tschatzl@5701 157 }
tschatzl@5701 158 }
tschatzl@5701 159
tschatzl@5701 160 private static boolean getFlagBoolValue(String flag, String where) {
tschatzl@5701 161 Matcher m = Pattern.compile(flag + "\\s+:?= (true|false)").matcher(where);
tschatzl@5701 162 if (!m.find()) {
tschatzl@5701 163 throw new RuntimeException("Could not find value for flag " + flag + " in output string");
tschatzl@5701 164 }
tschatzl@5701 165 String match = m.group(1).equals("true");
tschatzl@5701 166 }
tschatzl@5701 167
tschatzl@5701 168 private static String expect(String[] flags, boolean hasWarning, boolean hasError, int errorcode) throws Exception {
tschatzl@5701 169 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flags);
tschatzl@5701 170 OutputAnalyzer output = new OutputAnalyzer(pb.start());
tschatzl@5701 171 output.shouldHaveExitValue(errorcode);
tschatzl@5701 172 return output.getStdout();
tschatzl@5701 173 }
tschatzl@5701 174
tschatzl@5701 175 private static String expectValid(String[] flags) throws Exception {
tschatzl@5701 176 return expect(flags, false, false, 0);
tschatzl@5701 177 }
tschatzl@5701 178 }
tschatzl@5701 179

mercurial