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