1 /*
   2 * Copyright (c) 2014, 2015, 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 TestObjectTenuringFlags
  26  * @key gc
  27  * @bug 6521376
  28  * @summary Tests argument processing for NeverTenure, AlwaysTenure,
  29  * and MaxTenuringThreshold
  30  * @library /testlibrary
  31  * @modules java.base/sun.misc
  32  *          java.management
  33  * @build TestObjectTenuringFlags FlagsValue
  34  * @run main/othervm TestObjectTenuringFlags
  35  */
  36 
  37 import jdk.test.lib.*;
  38 
  39 import java.util.*;
  40 
  41 public class TestObjectTenuringFlags {
  42   public static void main(String args[]) throws Exception {
  43     // default case
  44     runTenuringFlagsConsistencyTest(
  45         new String[]{},
  46         false /* shouldFail */,
  47         new ExpectedTenuringFlags(false /* alwaysTenure */, false /* neverTenure */, 7, 15));
  48 
  49     // valid cases
  50     runTenuringFlagsConsistencyTest(
  51         new String[]{"-XX:+NeverTenure"},
  52         false /* shouldFail */,
  53         new ExpectedTenuringFlags(false /* alwaysTenure */, true /* neverTenure */, 7, 16));
  54 
  55     runTenuringFlagsConsistencyTest(
  56         new String[]{"-XX:+AlwaysTenure"},
  57         false /* shouldFail */,
  58         new ExpectedTenuringFlags(true /* alwaysTenure */, false /* neverTenure */, 0, 0));
  59 
  60     runTenuringFlagsConsistencyTest(
  61         new String[]{"-XX:MaxTenuringThreshold=0"},
  62         false /* shouldFail */,
  63         new ExpectedTenuringFlags(true /* alwaysTenure */, false /* neverTenure */, 0, 0));
  64 
  65     runTenuringFlagsConsistencyTest(
  66         new String[]{"-XX:MaxTenuringThreshold=5"},
  67         false /* shouldFail */,
  68         new ExpectedTenuringFlags(false /* alwaysTenure */, false /* neverTenure */, 5, 5));
  69 
  70     runTenuringFlagsConsistencyTest(
  71         new String[]{"-XX:MaxTenuringThreshold=10"},
  72         false /* shouldFail */,
  73         new ExpectedTenuringFlags(false /* alwaysTenure */, false /* neverTenure */, 7, 10));
  74 
  75     runTenuringFlagsConsistencyTest(
  76         new String[]{"-XX:MaxTenuringThreshold=15"},
  77         false /* shouldFail */,
  78         new ExpectedTenuringFlags(false /* alwaysTenure */, false /* neverTenure */, 7, 15));
  79 
  80     runTenuringFlagsConsistencyTest(
  81         new String[]{"-XX:MaxTenuringThreshold=16"},
  82         false /* shouldFail */,
  83         new ExpectedTenuringFlags(false /* alwaysTenure */, false /* neverTenure */, 7, 16));
  84 
  85     runTenuringFlagsConsistencyTest(
  86         new String[]{"-XX:InitialTenuringThreshold=0"},
  87         false /* shouldFail */,
  88         new ExpectedTenuringFlags(false /* alwaysTenure */, false /* neverTenure */, 0, 15));
  89 
  90     runTenuringFlagsConsistencyTest(
  91         new String[]{"-XX:InitialTenuringThreshold=5"},
  92         false /* shouldFail */,
  93         new ExpectedTenuringFlags(false /* alwaysTenure */, false /* neverTenure */, 5, 15));
  94 
  95     runTenuringFlagsConsistencyTest(
  96         new String[]{"-XX:InitialTenuringThreshold=10"},
  97         false /* shouldFail */,
  98         new ExpectedTenuringFlags(false /* alwaysTenure */, false /* neverTenure */, 10, 15));
  99 
 100     runTenuringFlagsConsistencyTest(
 101         new String[]{"-XX:InitialTenuringThreshold=15"},
 102         false /* shouldFail */,
 103         new ExpectedTenuringFlags(false /* alwaysTenure */, false /* neverTenure */, 15, 15));
 104 
 105     // "Last option wins" cases
 106     runTenuringFlagsConsistencyTest(
 107         new String[]{"-XX:+AlwaysTenure", "-XX:+NeverTenure"},
 108         false /* shouldFail */,
 109         new ExpectedTenuringFlags(false /* alwaysTenure */, true /* neverTenure */, 7, 16));
 110 
 111     runTenuringFlagsConsistencyTest(
 112         new String[]{"-XX:+NeverTenure", "-XX:+AlwaysTenure"},
 113         false /* shouldFail */,
 114         new ExpectedTenuringFlags(true /* alwaysTenure */, false /* neverTenure */, 0, 0));
 115 
 116     runTenuringFlagsConsistencyTest(
 117         new String[]{"-XX:MaxTenuringThreshold=16", "-XX:+AlwaysTenure"},
 118         false /* shouldFail */,
 119         new ExpectedTenuringFlags(true /* alwaysTenure */, false /* neverTenure */, 0, 0));
 120 
 121     runTenuringFlagsConsistencyTest(
 122         new String[]{"-XX:+AlwaysTenure", "-XX:MaxTenuringThreshold=16"},
 123         false /* shouldFail */,
 124         new ExpectedTenuringFlags(false /* alwaysTenure */, false /* neverTenure */, 7, 16));
 125 
 126     runTenuringFlagsConsistencyTest(
 127         new String[]{"-XX:MaxTenuringThreshold=0", "-XX:+NeverTenure"},
 128         false /* shouldFail */,
 129         new ExpectedTenuringFlags(false /* alwaysTenure */, true /* neverTenure */, 7, 16));
 130 
 131     runTenuringFlagsConsistencyTest(
 132         new String[]{"-XX:+NeverTenure", "-XX:MaxTenuringThreshold=0"},
 133         false /* shouldFail */,
 134         new ExpectedTenuringFlags(true /* alwaysTenure */, false /* neverTenure */, 0, 0));
 135 
 136     // Illegal cases
 137     runTenuringFlagsConsistencyTest(
 138         new String[]{"-XX:MaxTenuringThreshold=17"},
 139         true /* shouldFail */,
 140         new ExpectedTenuringFlags());
 141 
 142     runTenuringFlagsConsistencyTest(
 143         new String[]{"-XX:InitialTenuringThreshold=16"},
 144         true /* shouldFail */,
 145         new ExpectedTenuringFlags());
 146 
 147     runTenuringFlagsConsistencyTest(
 148         new String[]{"-XX:InitialTenuringThreshold=17"},
 149         true /* shouldFail */,
 150         new ExpectedTenuringFlags());
 151   }
 152 
 153   private static void runTenuringFlagsConsistencyTest(String[] tenuringFlags,
 154           boolean shouldFail,
 155           ExpectedTenuringFlags expectedFlags) throws Exception {
 156     List<String> vmOpts = new ArrayList<>();
 157     if (tenuringFlags.length > 0) {
 158       Collections.addAll(vmOpts, tenuringFlags);
 159     }
 160     Collections.addAll(vmOpts, "-XX:+PrintFlagsFinal", "-version");
 161 
 162     ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(vmOpts.toArray(new String[vmOpts.size()]));
 163     OutputAnalyzer output = new OutputAnalyzer(pb.start());
 164 
 165     if (shouldFail) {
 166       output.shouldHaveExitValue(1);
 167     } else {
 168       output.shouldHaveExitValue(0);
 169       String stdout = output.getStdout();
 170       checkTenuringFlagsConsistency(stdout, expectedFlags);
 171     }
 172   }
 173 
 174   private static void checkTenuringFlagsConsistency(String output, ExpectedTenuringFlags expectedFlags) {
 175     if (expectedFlags.alwaysTenure != FlagsValue.getFlagBoolValue("AlwaysTenure", output)) {
 176       throw new RuntimeException(
 177             "Actual flag AlwaysTenure " + FlagsValue.getFlagBoolValue("AlwaysTenure", output) +
 178             " is not equal to expected flag AlwaysTenure " + expectedFlags.alwaysTenure);
 179     }
 180 
 181     if (expectedFlags.neverTenure != FlagsValue.getFlagBoolValue("NeverTenure", output)) {
 182       throw new RuntimeException(
 183             "Actual flag NeverTenure " + FlagsValue.getFlagBoolValue("NeverTenure", output) +
 184             " is not equal to expected flag NeverTenure " + expectedFlags.neverTenure);
 185     }
 186 
 187     if (expectedFlags.initialTenuringThreshold != FlagsValue.getFlagLongValue("InitialTenuringThreshold", output)) {
 188       throw new RuntimeException(
 189             "Actual flag InitialTenuringThreshold " + FlagsValue.getFlagLongValue("InitialTenuringThreshold", output) +
 190             " is not equal to expected flag InitialTenuringThreshold " + expectedFlags.initialTenuringThreshold);
 191     }
 192 
 193     if (expectedFlags.maxTenuringThreshold != FlagsValue.getFlagLongValue("MaxTenuringThreshold", output)) {
 194       throw new RuntimeException(
 195             "Actual flag MaxTenuringThreshold " + FlagsValue.getFlagLongValue("MaxTenuringThreshold", output) +
 196             " is not equal to expected flag MaxTenuringThreshold " + expectedFlags.maxTenuringThreshold);
 197     }
 198   }
 199 }
 200 
 201 class ExpectedTenuringFlags {
 202     public boolean alwaysTenure;
 203     public boolean neverTenure;
 204     public long initialTenuringThreshold;
 205     public long maxTenuringThreshold;
 206 
 207     public ExpectedTenuringFlags(boolean alwaysTenure,
 208             boolean neverTenure,
 209             long initialTenuringThreshold,
 210             long maxTenuringThreshold) {
 211       this.alwaysTenure = alwaysTenure;
 212       this.neverTenure = neverTenure;
 213       this.initialTenuringThreshold = initialTenuringThreshold;
 214       this.maxTenuringThreshold = maxTenuringThreshold;
 215     }
 216     public ExpectedTenuringFlags() {}
 217 }