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:
parent
50a56141ba
commit
cc99075c79
src/hotspot/share/compiler
compilationPolicy.cppcompilationPolicy.hppcompilerDefinitions.cppcompilerDefinitions.hpptieredThresholdPolicy.cpptieredThresholdPolicy.hpp
test/hotspot/jtreg/compiler/tiered
@ -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) { }
|
||||
|
53
test/hotspot/jtreg/compiler/tiered/TieredModesTest.java
Normal file
53
test/hotspot/jtreg/compiler/tiered/TieredModesTest.java
Normal file
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user