178 lines
7.2 KiB
Java
178 lines
7.2 KiB
Java
/*
|
|
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
/*
|
|
* @test
|
|
* @library /test/lib /
|
|
* @bug 8356000
|
|
* @requires vm.flagless
|
|
* @requires vm.bits == "64"
|
|
* @run driver compiler.arguments.TestCompilerCounts
|
|
*/
|
|
|
|
package compiler.arguments;
|
|
|
|
import java.io.IOException;
|
|
import java.util.List;
|
|
import java.util.Arrays;
|
|
import java.util.ArrayList;
|
|
import java.util.function.Function;
|
|
import jdk.test.lib.Asserts;
|
|
import jdk.test.lib.process.ProcessTools;
|
|
import jdk.test.lib.process.OutputAnalyzer;
|
|
import jdk.test.lib.cli.CommandLineOptionTest;
|
|
|
|
public class TestCompilerCounts {
|
|
|
|
// Try not to go over max CPU count on the machine, since we do not
|
|
// know if the rest of runtime would accept it.
|
|
// For local testing, feel free to override this to a larger value
|
|
// if you want to see how heuristics works on even larger machines.
|
|
static final int MAX_CPUS = Runtime.getRuntime().availableProcessors();
|
|
|
|
// Test at most 16 CPUs linearly, to limit test execution time.
|
|
// After this limit, go for exponential steps.
|
|
static final int MAX_LINEAR_CPUS = Math.min(16, MAX_CPUS);
|
|
|
|
public static void main(String[] args) throws Throwable {
|
|
// CICompilerCount=0 is incorrect in default modes.
|
|
fail("-XX:CICompilerCount=0");
|
|
|
|
// Interpreter-only mode accepts all values, but sets 0 threads
|
|
pass(0, "-XX:CICompilerCount=1", "-XX:TieredStopAtLevel=0");
|
|
|
|
// C1/C2 only modes accept CICompilerCount=1
|
|
pass(1, "-XX:CICompilerCount=1", "-XX:TieredStopAtLevel=1");
|
|
pass(1, "-XX:CICompilerCount=1", "-XX:TieredStopAtLevel=2");
|
|
pass(1, "-XX:CICompilerCount=1", "-XX:TieredStopAtLevel=3");
|
|
pass(1, "-XX:CICompilerCount=1", "-XX:-TieredCompilation");
|
|
|
|
// C1+C2 modes need at least 2 threads
|
|
fail("-XX:CICompilerCount=1");
|
|
fail("-XX:CICompilerCount=1", "-XX:TieredStopAtLevel=4");
|
|
|
|
// Overriding the CICompilerCount overrides compiler counts hard.
|
|
for (int count = 2; count <= MAX_CPUS; count += (count >= MAX_LINEAR_CPUS ? count : 1)) {
|
|
String opt = "-XX:CICompilerCount=" + count;
|
|
|
|
// Interpreter-only mode always sets 0 threads
|
|
pass(0, opt, "-XX:TieredStopAtLevel=0");
|
|
|
|
// All compiled modes accept reasonable CICompilerCount
|
|
pass(count, opt);
|
|
pass(count, opt, "-XX:TieredStopAtLevel=1");
|
|
pass(count, opt, "-XX:TieredStopAtLevel=2");
|
|
pass(count, opt, "-XX:TieredStopAtLevel=3");
|
|
pass(count, opt, "-XX:TieredStopAtLevel=4");
|
|
pass(count, opt, "-XX:-TieredCompilation");
|
|
}
|
|
|
|
// Per CPU heuristics is disabled, we are going to set up defaults.
|
|
|
|
for (int cpus = 2; cpus <= MAX_CPUS; cpus += (cpus >= MAX_LINEAR_CPUS ? cpus : 1)) {
|
|
String opt = "-XX:ActiveProcessorCount=" + cpus;
|
|
String opt2 = "-XX:-CICompilerCountPerCPU";
|
|
|
|
// Interpreter-only mode always set 0 threads
|
|
pass(0, opt, opt2, "-XX:TieredStopAtLevel=0");
|
|
|
|
// All compiled modes default to 2 threads, statically compiled in
|
|
pass(2, opt, opt2);
|
|
pass(2, opt, opt2, "-XX:TieredStopAtLevel=1");
|
|
pass(2, opt, opt2, "-XX:TieredStopAtLevel=2");
|
|
pass(2, opt, opt2, "-XX:TieredStopAtLevel=3");
|
|
pass(2, opt, opt2, "-XX:TieredStopAtLevel=4");
|
|
pass(2, opt, opt2, "-XX:-TieredCompilation");
|
|
}
|
|
|
|
// Otherwise, we set CICompilerCount heuristically.
|
|
|
|
// Check hitting the lower values exactly first.
|
|
for (int cpus = 1; cpus <= 3; cpus++) {
|
|
String opt = "-XX:ActiveProcessorCount=" + cpus;
|
|
|
|
// Interpreter-only mode always set 0 threads
|
|
pass(0, opt, "-XX:TieredStopAtLevel=0");
|
|
|
|
// Non-tiered modes set 1 thread
|
|
pass(1, opt, "-XX:TieredStopAtLevel=1");
|
|
pass(1, opt, "-XX:TieredStopAtLevel=2");
|
|
pass(1, opt, "-XX:TieredStopAtLevel=3");
|
|
pass(1, opt, "-XX:-TieredCompilation");
|
|
|
|
// Tiered modes set 2 threads
|
|
pass(2, opt);
|
|
pass(2, opt, "-XX:TieredStopAtLevel=4");
|
|
}
|
|
|
|
// Check what heuristics sets past the trivial number of CPUs.
|
|
for (int cpus = 4; cpus <= MAX_CPUS; cpus += (cpus >= MAX_LINEAR_CPUS ? cpus : 1)) {
|
|
String opt = "-XX:ActiveProcessorCount=" + cpus;
|
|
|
|
// Interpreter-only mode always set 0 threads
|
|
pass(0, opt, "-XX:TieredStopAtLevel=0");
|
|
|
|
// Non-tiered modes
|
|
int nonTieredCount = heuristicCount(cpus, false);
|
|
pass(nonTieredCount, opt, "-XX:TieredStopAtLevel=1");
|
|
pass(nonTieredCount, opt, "-XX:TieredStopAtLevel=2");
|
|
pass(nonTieredCount, opt, "-XX:TieredStopAtLevel=3");
|
|
pass(nonTieredCount, opt, "-XX:-TieredCompilation");
|
|
|
|
// Tiered modes
|
|
int tieredCount = heuristicCount(cpus, true);
|
|
pass(tieredCount, opt);
|
|
pass(tieredCount, opt, "-XX:TieredStopAtLevel=4");
|
|
|
|
// Also check that heuristics did not set up more threads than CPUs available
|
|
Asserts.assertTrue(nonTieredCount <= cpus,
|
|
"Non-tiered count is larger than number of CPUs: " + nonTieredCount + " > " + cpus);
|
|
Asserts.assertTrue(tieredCount <= cpus,
|
|
"Tiered count is larger than number of CPUs: " + tieredCount + " > " + cpus);
|
|
}
|
|
}
|
|
|
|
// Direct translation from CompilationPolicy::initialize:
|
|
public static int heuristicCount(int cpus, boolean tiered) {
|
|
int log_cpu = log2(cpus);
|
|
int loglog_cpu = log2(Math.max(log_cpu, 1));
|
|
int min_count = tiered ? 2 : 1;
|
|
return Math.max(log_cpu * loglog_cpu * 3 / 2, min_count);
|
|
}
|
|
|
|
public static int log2(int v) {
|
|
return (int)(Math.log(v) / Math.log(2));
|
|
}
|
|
|
|
public static void pass(int count, String... args) throws Throwable {
|
|
CommandLineOptionTest.verifyOptionValueForSameVM("CICompilerCount", "" + count, "", args);
|
|
}
|
|
|
|
public static void fail(String... args) throws Throwable {
|
|
ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(args);
|
|
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
|
output.shouldNotHaveExitValue(0);
|
|
}
|
|
|
|
}
|