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