mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-25 05:45:11 +02:00
8020151: PSR:PERF Large performance regressions when code cache is filled
Code cache sweeping based on method hotness; removed speculatively disconnect Reviewed-by: kvn, iveresov
This commit is contained in:
parent
441f1d74cf
commit
0dee555ead
15 changed files with 240 additions and 418 deletions
|
@ -634,19 +634,36 @@ CompileTask* CompileQueue::get() {
|
|||
NMethodSweeper::possibly_sweep();
|
||||
|
||||
MutexLocker locker(lock());
|
||||
// Wait for an available CompileTask.
|
||||
// If _first is NULL we have no more compile jobs. There are two reasons for
|
||||
// having no compile jobs: First, we compiled everything we wanted. Second,
|
||||
// we ran out of code cache so compilation has been disabled. In the latter
|
||||
// case we perform code cache sweeps to free memory such that we can re-enable
|
||||
// compilation.
|
||||
while (_first == NULL) {
|
||||
// There is no work to be done right now. Wait.
|
||||
if (UseCodeCacheFlushing && (!CompileBroker::should_compile_new_jobs() || CodeCache::needs_flushing())) {
|
||||
// During the emergency sweeping periods, wake up and sweep occasionally
|
||||
bool timedout = lock()->wait(!Mutex::_no_safepoint_check_flag, NmethodSweepCheckInterval*1000);
|
||||
if (timedout) {
|
||||
if (UseCodeCacheFlushing && !CompileBroker::should_compile_new_jobs()) {
|
||||
// Wait a certain amount of time to possibly do another sweep.
|
||||
// We must wait until stack scanning has happened so that we can
|
||||
// transition a method's state from 'not_entrant' to 'zombie'.
|
||||
long wait_time = NmethodSweepCheckInterval * 1000;
|
||||
if (FLAG_IS_DEFAULT(NmethodSweepCheckInterval)) {
|
||||
// Only one thread at a time can do sweeping. Scale the
|
||||
// wait time according to the number of compiler threads.
|
||||
// As a result, the next sweep is likely to happen every 100ms
|
||||
// with an arbitrary number of threads that do sweeping.
|
||||
wait_time = 100 * CICompilerCount;
|
||||
}
|
||||
bool timeout = lock()->wait(!Mutex::_no_safepoint_check_flag, wait_time);
|
||||
if (timeout) {
|
||||
MutexUnlocker ul(lock());
|
||||
// When otherwise not busy, run nmethod sweeping
|
||||
NMethodSweeper::possibly_sweep();
|
||||
}
|
||||
} else {
|
||||
// During normal operation no need to wake up on timer
|
||||
// If there are no compilation tasks and we can compile new jobs
|
||||
// (i.e., there is enough free space in the code cache) there is
|
||||
// no need to invoke the sweeper. As a result, the hotness of methods
|
||||
// remains unchanged. This behavior is desired, since we want to keep
|
||||
// the stable state, i.e., we do not want to evict methods from the
|
||||
// code cache if it is unnecessary.
|
||||
lock()->wait();
|
||||
}
|
||||
}
|
||||
|
@ -1227,16 +1244,9 @@ nmethod* CompileBroker::compile_method(methodHandle method, int osr_bci,
|
|||
return method_code;
|
||||
}
|
||||
}
|
||||
if (method->is_not_compilable(comp_level)) return NULL;
|
||||
|
||||
if (UseCodeCacheFlushing) {
|
||||
nmethod* saved = CodeCache::reanimate_saved_code(method());
|
||||
if (saved != NULL) {
|
||||
method->set_code(method, saved);
|
||||
return saved;
|
||||
}
|
||||
if (method->is_not_compilable(comp_level)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} else {
|
||||
// osr compilation
|
||||
#ifndef TIERED
|
||||
|
@ -1585,9 +1595,6 @@ void CompileBroker::compiler_thread_loop() {
|
|||
if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) {
|
||||
// the code cache is really full
|
||||
handle_full_code_cache();
|
||||
} else if (UseCodeCacheFlushing && CodeCache::needs_flushing()) {
|
||||
// Attempt to start cleaning the code cache while there is still a little headroom
|
||||
NMethodSweeper::handle_full_code_cache(false);
|
||||
}
|
||||
|
||||
CompileTask* task = queue->get();
|
||||
|
@ -1943,7 +1950,11 @@ void CompileBroker::handle_full_code_cache() {
|
|||
}
|
||||
#endif
|
||||
if (UseCodeCacheFlushing) {
|
||||
NMethodSweeper::handle_full_code_cache(true);
|
||||
// Since code cache is full, immediately stop new compiles
|
||||
if (CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation)) {
|
||||
NMethodSweeper::log_sweep("disable_compiler");
|
||||
NMethodSweeper::possibly_sweep();
|
||||
}
|
||||
} else {
|
||||
UseCompiler = false;
|
||||
AlwaysCompileLoopMethods = false;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue