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