8162881: Effect of -XX:CICompilerCount depends on ordering of other flags

Value of CICompilerCount should be range checked after ergo. Don't create C2 compiler threads with TieredStopAtLevel=1.

Reviewed-by: kvn
This commit is contained in:
Tobias Hartmann 2016-08-04 08:58:22 +02:00
parent 70110abb7a
commit 13fca14037
7 changed files with 98 additions and 49 deletions

View file

@ -667,7 +667,7 @@ WB_ENTRY(jboolean, WB_IsMethodQueuedForCompilation(JNIEnv* env, jobject o, jobje
WB_END WB_END
WB_ENTRY(jboolean, WB_IsIntrinsicAvailable(JNIEnv* env, jobject o, jobject method, jobject compilation_context, jint compLevel)) WB_ENTRY(jboolean, WB_IsIntrinsicAvailable(JNIEnv* env, jobject o, jobject method, jobject compilation_context, jint compLevel))
if (compLevel < CompLevel_none || compLevel > CompLevel_highest_tier) { if (compLevel < CompLevel_none || compLevel > TieredStopAtLevel) {
return false; // Intrinsic is not available on a non-existent compilation level. return false; // Intrinsic is not available on a non-existent compilation level.
} }
jmethodID method_id, compilation_context_id; jmethodID method_id, compilation_context_id;
@ -677,6 +677,7 @@ WB_ENTRY(jboolean, WB_IsIntrinsicAvailable(JNIEnv* env, jobject o, jobject metho
DirectiveSet* directive; DirectiveSet* directive;
AbstractCompiler* comp = CompileBroker::compiler((int)compLevel); AbstractCompiler* comp = CompileBroker::compiler((int)compLevel);
assert(comp != NULL, "compiler not available");
if (compilation_context != NULL) { if (compilation_context != NULL) {
compilation_context_id = reflected_method_to_jmid(thread, env, compilation_context); compilation_context_id = reflected_method_to_jmid(thread, env, compilation_context);
CHECK_JNI_EXCEPTION_(env, JNI_FALSE); CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
@ -686,7 +687,7 @@ WB_ENTRY(jboolean, WB_IsIntrinsicAvailable(JNIEnv* env, jobject o, jobject metho
// Calling with NULL matches default directive // Calling with NULL matches default directive
directive = DirectivesStack::getDefaultDirective(comp); directive = DirectivesStack::getDefaultDirective(comp);
} }
bool result = CompileBroker::compiler(compLevel)->is_intrinsic_available(mh, directive); bool result = comp->is_intrinsic_available(mh, directive);
DirectivesStack::release(directive); DirectivesStack::release(directive);
return result; return result;
WB_END WB_END

View file

@ -55,7 +55,8 @@ void AdvancedThresholdPolicy::initialize() {
// Simple log n seems to grow too slowly for tiered, try something faster: log n * log log n // Simple log n seems to grow too slowly for tiered, try something faster: log n * log log n
int log_cpu = log2_intptr(os::active_processor_count()); int log_cpu = log2_intptr(os::active_processor_count());
int loglog_cpu = log2_intptr(MAX2(log_cpu, 1)); int loglog_cpu = log2_intptr(MAX2(log_cpu, 1));
count = MAX2(log_cpu * loglog_cpu, 1) * 3 / 2; count = MAX2(log_cpu * loglog_cpu * 3 / 2, 2);
FLAG_SET_ERGO(intx, CICompilerCount, count);
} }
#else #else
// On 32-bit systems, the number of compiler threads is limited to 3. // On 32-bit systems, the number of compiler threads is limited to 3.
@ -67,12 +68,18 @@ void AdvancedThresholdPolicy::initialize() {
/// available to the VM and thus cause the VM to crash. /// available to the VM and thus cause the VM to crash.
if (FLAG_IS_DEFAULT(CICompilerCount)) { if (FLAG_IS_DEFAULT(CICompilerCount)) {
count = 3; count = 3;
FLAG_SET_ERGO(intx, CICompilerCount, count);
} }
#endif #endif
set_c1_count(MAX2(count / 3, 1)); if (TieredStopAtLevel < CompLevel_full_optimization) {
set_c2_count(MAX2(count - c1_count(), 1)); // No C2 compiler thread required
FLAG_SET_ERGO(intx, CICompilerCount, c1_count() + c2_count()); set_c1_count(count);
} else {
set_c1_count(MAX2(count / 3, 1));
set_c2_count(MAX2(count - c1_count(), 1));
}
assert(count == c1_count() + c2_count(), "inconsistent compiler thread count");
// Some inlining tuning // Some inlining tuning
#ifdef X86 #ifdef X86

View file

@ -2411,7 +2411,7 @@ public:
product(intx, CICompilerCount, CI_COMPILER_COUNT, \ product(intx, CICompilerCount, CI_COMPILER_COUNT, \
"Number of compiler threads to run") \ "Number of compiler threads to run") \
range(0, max_jint) \ range(0, max_jint) \
constraint(CICompilerCountConstraintFunc, AtParse) \ constraint(CICompilerCountConstraintFunc, AfterErgo) \
\ \
product(intx, CompilationPolicyChoice, 0, \ product(intx, CompilationPolicyChoice, 0, \
"which compilation policy (0-3)") \ "which compilation policy (0-3)") \

View file

@ -147,12 +147,18 @@ void SimpleThresholdPolicy::initialize() {
// performed on 32-bit systems because it can lead to exhaustion // performed on 32-bit systems because it can lead to exhaustion
// of the virtual memory address space available to the JVM. // of the virtual memory address space available to the JVM.
if (CICompilerCountPerCPU) { if (CICompilerCountPerCPU) {
count = MAX2(log2_intptr(os::active_processor_count()), 1) * 3 / 2; count = MAX2(log2_intptr(os::active_processor_count()) * 3 / 2, 2);
FLAG_SET_ERGO(intx, CICompilerCount, count);
} }
#endif #endif
set_c1_count(MAX2(count / 3, 1)); if (TieredStopAtLevel < CompLevel_full_optimization) {
set_c2_count(MAX2(count - c1_count(), 1)); // No C2 compiler thread required
FLAG_SET_ERGO(intx, CICompilerCount, c1_count() + c2_count()); set_c1_count(count);
} else {
set_c1_count(MAX2(count / 3, 1));
set_c2_count(MAX2(count - c1_count(), 1));
}
assert(count == c1_count() + c2_count(), "inconsistent compiler thread count");
} }
void SimpleThresholdPolicy::set_carry_if_necessary(InvocationCounter *counter) { void SimpleThresholdPolicy::set_carry_if_necessary(InvocationCounter *counter) {

View file

@ -23,8 +23,7 @@
/* /*
* @test CheckCheckCICompilerCount * @test CheckCheckCICompilerCount
* @bug 8130858 * @bug 8130858 8132525 8162881
* @bug 8132525
* @summary Check that correct range of values for CICompilerCount are allowed depending on whether tiered is enabled or not * @summary Check that correct range of values for CICompilerCount are allowed depending on whether tiered is enabled or not
* @library /testlibrary / * @library /testlibrary /
* @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.misc
@ -53,6 +52,13 @@ public class CheckCICompilerCount {
"-XX:CICompilerCount=1", "-XX:CICompilerCount=1",
"-version" "-version"
}, },
{
"-server",
"-XX:+PrintFlagsFinal",
"-XX:CICompilerCount=1",
"-XX:-TieredCompilation",
"-version"
},
{ {
"-client", "-client",
"-XX:-TieredCompilation", "-XX:-TieredCompilation",
@ -66,30 +72,31 @@ public class CheckCICompilerCount {
"-XX:+PrintFlagsFinal", "-XX:+PrintFlagsFinal",
"-XX:CICompilerCount=1", "-XX:CICompilerCount=1",
"-version" "-version"
},
{
"-client",
"-XX:+PrintFlagsFinal",
"-XX:CICompilerCount=1",
"-XX:-TieredCompilation",
"-version"
} }
}; };
private static final String[][] NON_TIERED_EXPECTED_OUTPUTS = { private static final String[] NON_TIERED_EXPECTED_OUTPUTS = {
{
"CICompilerCount (0) must be at least 1", "CICompilerCount (0) must be at least 1",
"Improperly specified VM option 'CICompilerCount=0'" "intx CICompilerCount = 1 {product} {command line}",
}, "intx CICompilerCount = 1 {product} {command line}",
{
"intx CICompilerCount = 1 {product} {command line}"
},
{
"CICompilerCount (0) must be at least 1", "CICompilerCount (0) must be at least 1",
"Improperly specified VM option 'CICompilerCount=0'" "intx CICompilerCount = 1 {product} {command line}",
},
{
"intx CICompilerCount = 1 {product} {command line}" "intx CICompilerCount = 1 {product} {command line}"
}
}; };
private static final int[] NON_TIERED_EXIT = { private static final int[] NON_TIERED_EXIT = {
1, 1,
0, 0,
0,
1, 1,
0,
0 0
}; };
@ -101,6 +108,22 @@ public class CheckCICompilerCount {
"-XX:CICompilerCount=1", "-XX:CICompilerCount=1",
"-version" "-version"
}, },
{
"-server",
"-XX:+TieredCompilation",
"-XX:TieredStopAtLevel=1",
"-XX:+PrintFlagsFinal",
"-XX:CICompilerCount=1",
"-version"
},
{
"-server",
"-XX:+TieredCompilation",
"-XX:+PrintFlagsFinal",
"-XX:CICompilerCount=1",
"-XX:TieredStopAtLevel=1",
"-version"
},
{ {
"-server", "-server",
"-XX:+TieredCompilation", "-XX:+TieredCompilation",
@ -115,6 +138,22 @@ public class CheckCICompilerCount {
"-XX:CICompilerCount=1", "-XX:CICompilerCount=1",
"-version" "-version"
}, },
{
"-client",
"-XX:+TieredCompilation",
"-XX:TieredStopAtLevel=1",
"-XX:+PrintFlagsFinal",
"-XX:CICompilerCount=1",
"-version"
},
{
"-client",
"-XX:+TieredCompilation",
"-XX:+PrintFlagsFinal",
"-XX:CICompilerCount=1",
"-XX:TieredStopAtLevel=1",
"-version"
},
{ {
"-client", "-client",
"-XX:+TieredCompilation", "-XX:+TieredCompilation",
@ -124,31 +163,29 @@ public class CheckCICompilerCount {
} }
}; };
private static final String[][] TIERED_EXPECTED_OUTPUTS = { private static final String[] TIERED_EXPECTED_OUTPUTS = {
{
"CICompilerCount (1) must be at least 2", "CICompilerCount (1) must be at least 2",
"Improperly specified VM option 'CICompilerCount=1'" "intx CICompilerCount = 1 {product} {command line}",
}, "intx CICompilerCount = 1 {product} {command line}",
{ "intx CICompilerCount = 2 {product} {command line}",
"intx CICompilerCount = 2 {product} {command line, ergonomic}"
},
{
"CICompilerCount (1) must be at least 2", "CICompilerCount (1) must be at least 2",
"Improperly specified VM option 'CICompilerCount=1'" "intx CICompilerCount = 1 {product} {command line}",
}, "intx CICompilerCount = 1 {product} {command line}",
{ "intx CICompilerCount = 2 {product} {command line}",
"intx CICompilerCount = 2 {product} {command line, ergonomic}"
}
}; };
private static final int[] TIERED_EXIT = { private static final int[] TIERED_EXIT = {
1, 1,
0, 0,
0,
0,
1, 1,
0,
0,
0 0
}; };
private static void verifyValidOption(String[] arguments, String[] expected_outputs, int exit, boolean tiered) throws Exception { private static void verifyValidOption(String[] arguments, String expected_output, int exit, boolean tiered) throws Exception {
ProcessBuilder pb; ProcessBuilder pb;
OutputAnalyzer out; OutputAnalyzer out;
@ -157,9 +194,7 @@ public class CheckCICompilerCount {
try { try {
out.shouldHaveExitValue(exit); out.shouldHaveExitValue(exit);
for (String expected_output : expected_outputs) { out.shouldContain(expected_output);
out.shouldContain(expected_output);
}
} catch (RuntimeException e) { } catch (RuntimeException e) {
// Check if tiered compilation is available in this JVM // Check if tiered compilation is available in this JVM
// Version. Throw exception only if it is available. // Version. Throw exception only if it is available.

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -114,7 +114,7 @@ public class IntrinsicAvailableTest extends CompilerWhiteBoxTest {
public void test() throws Exception { public void test() throws Exception {
Executable intrinsicMethod = testCase.getExecutable(); Executable intrinsicMethod = testCase.getExecutable();
if (Platform.isServer()) { if (Platform.isServer() && (TIERED_STOP_AT_LEVEL == COMP_LEVEL_FULL_OPTIMIZATION)) {
if (TIERED_COMPILATION) { if (TIERED_COMPILATION) {
checkIntrinsicForCompilationLevel(intrinsicMethod, COMP_LEVEL_SIMPLE); checkIntrinsicForCompilationLevel(intrinsicMethod, COMP_LEVEL_SIMPLE);
} }

View file

@ -59,9 +59,9 @@ public class IntrinsicDisabledTest {
private static final int COMP_LEVEL_FULL_OPTIMIZATION = 4; private static final int COMP_LEVEL_FULL_OPTIMIZATION = 4;
/* Determine if tiered compilation is enabled. */ /* Determine if tiered compilation is enabled. */
private static boolean isTieredCompilationEnabled() { private static final boolean TIERED_COMPILATION = wb.getBooleanVMFlag("TieredCompilation");
return Boolean.valueOf(Objects.toString(wb.getVMFlag("TieredCompilation")));
} private static final int TIERED_STOP_AT_LEVEL = wb.getIntxVMFlag("TieredStopAtLevel").intValue();
/* This test uses several methods from jdk.internal.misc.Unsafe. The method /* This test uses several methods from jdk.internal.misc.Unsafe. The method
* getMethod() returns a different Executable for each different * getMethod() returns a different Executable for each different
@ -202,8 +202,8 @@ public class IntrinsicDisabledTest {
} }
public static void main(String args[]) { public static void main(String args[]) {
if (Platform.isServer()) { if (Platform.isServer() && (TIERED_STOP_AT_LEVEL == COMP_LEVEL_FULL_OPTIMIZATION)) {
if (isTieredCompilationEnabled()) { if (TIERED_COMPILATION) {
test(COMP_LEVEL_SIMPLE); test(COMP_LEVEL_SIMPLE);
} }
test(COMP_LEVEL_FULL_OPTIMIZATION); test(COMP_LEVEL_FULL_OPTIMIZATION);