8236050: Some compiler tests fail when executed with custom TieredLevel

Make sure TieredStopAtLevel is properly supported for different compilation modes

Reviewed-by: redestad, thartmann
This commit is contained in:
Igor Veresov 2020-01-07 07:31:28 -08:00
parent 50a56141ba
commit cc99075c79
7 changed files with 142 additions and 28 deletions

@ -104,7 +104,7 @@ void CompilationPolicy::compile_if_required(const methodHandle& selected_method,
return;
}
CompileBroker::compile_method(selected_method, InvocationEntryBci,
CompilationPolicy::policy()->initial_compile_level(),
CompilationPolicy::policy()->initial_compile_level(selected_method),
methodHandle(), 0, CompileTask::Reason_MustBeCompiled, CHECK);
}
}

@ -59,7 +59,7 @@ public:
static CompileTask* select_task_helper(CompileQueue* compile_queue);
// Return initial compile level that is used with Xcomp
virtual CompLevel initial_compile_level() = 0;
virtual CompLevel initial_compile_level(const methodHandle& method) = 0;
virtual int compiler_count(CompLevel comp_level) = 0;
// main notification entry, return a pointer to an nmethod if the OSR is required,
// returns NULL otherwise.
@ -97,7 +97,7 @@ class SimpleCompPolicy : public CompilationPolicy {
void method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread);
public:
SimpleCompPolicy() : _compiler_count(0) { }
virtual CompLevel initial_compile_level() { return CompLevel_highest_tier; }
virtual CompLevel initial_compile_level(const methodHandle& m) { return CompLevel_highest_tier; }
virtual int compiler_count(CompLevel comp_level);
virtual void do_safepoint_work();
virtual void reprofile(ScopeDesc* trap_scope, bool is_osr);

@ -57,9 +57,6 @@ bool CompilationModeFlag::initialize() {
jio_fprintf(defaultStream::error_stream(), "Unsupported compilation mode '%s', supported modes are: quick-only, high-only, high-only-quick-internal\n", CompilationMode);
return false;
}
if (disable_intermediate()) {
CompLevel_initial_compile = CompLevel_full_optimization;
}
}
return true;
}
@ -74,16 +71,6 @@ CompLevel CompLevel_highest_tier = CompLevel_simple; // pure C
CompLevel CompLevel_highest_tier = CompLevel_none;
#endif
#if defined(TIERED)
CompLevel CompLevel_initial_compile = CompLevel_full_profile; // tiered
#elif defined(COMPILER1) || INCLUDE_JVMCI
CompLevel CompLevel_initial_compile = CompLevel_simple; // pure C1 or JVMCI
#elif defined(COMPILER2)
CompLevel CompLevel_initial_compile = CompLevel_full_optimization; // pure C2
#else
CompLevel CompLevel_initial_compile = CompLevel_none;
#endif
#if defined(COMPILER2)
CompMode Compilation_mode = CompMode_server;
#elif defined(COMPILER1)
@ -145,7 +132,6 @@ intx CompilerConfig::scaled_freq_log(intx freq_log, double scale) {
void set_client_compilation_mode() {
Compilation_mode = CompMode_client;
CompLevel_highest_tier = CompLevel_simple;
CompLevel_initial_compile = CompLevel_simple;
FLAG_SET_ERGO(TieredCompilation, false);
FLAG_SET_ERGO(ProfileInterpreter, false);
#if INCLUDE_JVMCI

@ -83,7 +83,6 @@ public:
#endif
extern CompLevel CompLevel_highest_tier;
extern CompLevel CompLevel_initial_compile;
enum CompMode {
CompMode_none = 0,

@ -307,6 +307,78 @@ void TieredThresholdPolicy::initialize() {
set_start_time(os::javaTimeMillis());
}
#ifdef ASSERT
bool TieredThresholdPolicy::verify_level(CompLevel level) {
// AOT and interpreter levels are always valid.
if (level == CompLevel_aot || level == CompLevel_none) {
return true;
}
if (CompilationModeFlag::normal()) {
return true;
} else if (CompilationModeFlag::quick_only()) {
return level == CompLevel_simple;
} else if (CompilationModeFlag::high_only()) {
return level == CompLevel_full_optimization;
} else if (CompilationModeFlag::high_only_quick_internal()) {
return level == CompLevel_full_optimization || level == CompLevel_simple;
}
return false;
}
#endif
CompLevel TieredThresholdPolicy::limit_level(CompLevel level) {
if (CompilationModeFlag::quick_only()) {
level = MIN2(level, CompLevel_simple);
}
assert(verify_level(level), "Invalid compilation level %d", level);
if (level <= TieredStopAtLevel) {
return level;
}
// Some compilation levels are not valid depending on a compilation mode:
// a) quick_only - levels 2,3,4 are invalid; levels -1,0,1 are valid;
// b) high_only - levels 1,2,3 are invalid; levels -1,0,4 are valid;
// c) high_only_quick_internal - levels 2,3 are invalid; levels -1,0,1,4 are valid.
// The invalid levels are actually sequential so a single comparison is sufficient.
// Down here we already have (level > TieredStopAtLevel), which also implies that
// (TieredStopAtLevel < Highest Possible Level), so we need to return a level that is:
// a) a max level that is strictly less than the highest for a given compilation mode
// b) less or equal to TieredStopAtLevel
if (CompilationModeFlag::normal() || CompilationModeFlag::quick_only()) {
return (CompLevel)TieredStopAtLevel;
}
if (CompilationModeFlag::high_only() || CompilationModeFlag::high_only_quick_internal()) {
return MIN2(CompLevel_none, (CompLevel)TieredStopAtLevel);
}
ShouldNotReachHere();
return CompLevel_any;
}
CompLevel TieredThresholdPolicy::initial_compile_level_helper(const methodHandle& method) {
if (CompilationModeFlag::normal()) {
return CompLevel_full_profile;
} else if (CompilationModeFlag::quick_only()) {
return CompLevel_simple;
} else if (CompilationModeFlag::high_only()) {
return CompLevel_full_optimization;
} else if (CompilationModeFlag::high_only_quick_internal()) {
if (force_comp_at_level_simple(method)) {
return CompLevel_simple;
} else {
return CompLevel_full_optimization;
}
}
ShouldNotReachHere();
return CompLevel_any;
}
CompLevel TieredThresholdPolicy::initial_compile_level(const methodHandle& method) {
return limit_level(initial_compile_level_helper(method));
}
void TieredThresholdPolicy::set_carry_if_necessary(InvocationCounter *counter) {
if (!counter->carry() && counter->count() > InvocationCounter::count_limit / 2) {
counter->set_carry_flag();
@ -457,12 +529,7 @@ nmethod* TieredThresholdPolicy::event(const methodHandle& method, const methodHa
// Check if the method can be compiled, change level if necessary
void TieredThresholdPolicy::compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) {
assert(level <= TieredStopAtLevel, "Invalid compilation level");
if (CompilationModeFlag::quick_only()) {
assert(level <= CompLevel_simple, "Invalid compilation level");
} else if (CompilationModeFlag::disable_intermediate()) {
assert(level != CompLevel_full_profile && level != CompLevel_limited_profile, "C1 profiling levels shouldn't be used with intermediate levels disabled");
}
assert(verify_level(level) && level <= TieredStopAtLevel, "Invalid compilation level %d", level);
if (level == CompLevel_none) {
if (mh->has_compiled_code()) {
@ -924,9 +991,11 @@ CompLevel TieredThresholdPolicy::common(Predicate p, const methodHandle& method,
}
}
}
return MIN2(next_level, CompilationModeFlag::quick_only() ? CompLevel_simple : (CompLevel)TieredStopAtLevel);
return limit_level(next_level);
}
// Determine if a method should be compiled with a normal entry point at a different level.
CompLevel TieredThresholdPolicy::call_event(const methodHandle& method, CompLevel cur_level, JavaThread* thread) {
CompLevel osr_level = MIN2((CompLevel) method->highest_osr_comp_level(),
@ -1027,7 +1096,7 @@ void TieredThresholdPolicy::method_back_branch_event(const methodHandle& mh, con
if (level == CompLevel_aot) {
// Recompile the enclosing method to prevent infinite OSRs. Stay at AOT level while it's compiling.
if (max_osr_level != CompLevel_none && !CompileBroker::compilation_is_in_queue(mh)) {
CompLevel enclosing_level = MIN2(CompilationModeFlag::quick_only() ? CompLevel_simple : (CompLevel)TieredStopAtLevel, CompLevel_full_profile);
CompLevel enclosing_level = limit_level(CompLevel_full_profile);
compile(mh, InvocationEntryBci, enclosing_level, thread);
}
} else {

@ -170,8 +170,14 @@ class TieredThresholdPolicy : public CompilationPolicy {
inline void set_carry_if_necessary(InvocationCounter *counter);
// Set carry flags in the counters (in Method* and MDO).
inline void handle_counter_overflow(Method* method);
// Verify that a level is consistent with the compilation mode
bool verify_level(CompLevel level);
// Clamp the request level according to various constraints.
inline CompLevel limit_level(CompLevel level);
// Return desired initial compilation level for Xcomp
CompLevel initial_compile_level_helper(const methodHandle& method);
// Call and loop predicates determine whether a transition to a higher compilation
// level should be performed (pointers to predicate functions are passed to common_TF().
// level should be performed (pointers to predicate functions are passed to common().
// Predicates also take compiler load into account.
typedef bool (TieredThresholdPolicy::*Predicate)(int i, int b, CompLevel cur_level, const methodHandle& method);
bool call_predicate(int i, int b, CompLevel cur_level, const methodHandle& method);
@ -253,7 +259,8 @@ public:
if (is_c2_compile(comp_level)) return c2_count();
return 0;
}
virtual CompLevel initial_compile_level() { return MIN2((CompLevel)TieredStopAtLevel, CompLevel_initial_compile); }
// Return initial compile level to use with Xcomp (depends on compilation mode).
virtual CompLevel initial_compile_level(const methodHandle& method);
virtual void do_safepoint_work() { }
virtual void delay_compilation(Method* method) { }
virtual void disable_compilation(Method* method) { }

@ -0,0 +1,53 @@
/*
* Copyright (c) 2020, Oracle and/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 TieredModesTest
* @summary Check that non-default tiered compilation modes tolerate invalid TieredStopAtLevel values
* @modules java.base/jdk.internal.misc
* java.management
*
* @run main/othervm -XX:+TieredCompilation -XX:CompilationMode=quick-only -XX:TieredStopAtLevel=3
* -XX:CompileCommand=compileonly,compiler.tiered.TieredModesTest::test
* compiler.tiered.TieredModesTest
* @run main/othervm -XX:+TieredCompilation -XX:CompilationMode=high-only -XX:TieredStopAtLevel=3
* -XX:CompileCommand=compileonly,compiler.tiered.TieredModesTest::test
* compiler.tiered.TieredModesTest
* @run main/othervm -XX:+TieredCompilation -XX:CompilationMode=high-only-quick-internal -XX:TieredStopAtLevel=3
* -XX:CompileCommand=compileonly,compiler.tiered.TieredModesTest::test
* compiler.tiered.TieredModesTest
*/
package compiler.tiered;
public class TieredModesTest {
public static int sideEffect = 0;
private static void test() {
sideEffect++;
}
public static void main(String... args) {
for (int i = 0; i < 100_000; i++) {
test();
}
}
}