mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-25 05:45:11 +02:00
4360113: Evict nmethods when code cache gets full
Speculatively unload the oldest nmethods when code cache gets full. Reviewed-by: never, kvn
This commit is contained in:
parent
9aa675b7e6
commit
a57d68e35b
19 changed files with 452 additions and 76 deletions
|
@ -69,6 +69,7 @@ HS_DTRACE_PROBE_DECL9(hotspot, method__compile__end,
|
|||
|
||||
bool CompileBroker::_initialized = false;
|
||||
volatile bool CompileBroker::_should_block = false;
|
||||
volatile jint CompileBroker::_should_compile_new_jobs = run_compilation;
|
||||
|
||||
// The installed compiler(s)
|
||||
AbstractCompiler* CompileBroker::_compilers[2];
|
||||
|
@ -986,6 +987,13 @@ nmethod* CompileBroker::compile_method(methodHandle method, int osr_bci,
|
|||
return method_code;
|
||||
}
|
||||
if (method->is_not_compilable(comp_level)) return NULL;
|
||||
|
||||
nmethod* saved = CodeCache::find_and_remove_saved_code(method());
|
||||
if (saved != NULL) {
|
||||
method->set_code(method, saved);
|
||||
return saved;
|
||||
}
|
||||
|
||||
} else {
|
||||
// osr compilation
|
||||
#ifndef TIERED
|
||||
|
@ -1037,6 +1045,14 @@ nmethod* CompileBroker::compile_method(methodHandle method, int osr_bci,
|
|||
method->jmethod_id();
|
||||
}
|
||||
|
||||
// If the compiler is shut off due to code cache flushing or otherwise,
|
||||
// fail out now so blocking compiles dont hang the java thread
|
||||
if (!should_compile_new_jobs() || (UseCodeCacheFlushing && CodeCache::needs_flushing())) {
|
||||
method->invocation_counter()->decay();
|
||||
method->backedge_counter()->decay();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// do the compilation
|
||||
if (method->is_native()) {
|
||||
if (!PreferInterpreterNativeStubs) {
|
||||
|
@ -1325,26 +1341,13 @@ void CompileBroker::compiler_thread_loop() {
|
|||
{
|
||||
// We need this HandleMark to avoid leaking VM handles.
|
||||
HandleMark hm(thread);
|
||||
|
||||
if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) {
|
||||
// The CodeCache is full. Print out warning and disable compilation.
|
||||
UseInterpreter = true;
|
||||
if (UseCompiler || AlwaysCompileLoopMethods ) {
|
||||
if (log != NULL) {
|
||||
log->begin_elem("code_cache_full");
|
||||
log->stamp();
|
||||
log->end_elem();
|
||||
}
|
||||
#ifndef PRODUCT
|
||||
warning("CodeCache is full. Compiler has been disabled");
|
||||
if (CompileTheWorld || ExitOnFullCodeCache) {
|
||||
before_exit(thread);
|
||||
exit_globals(); // will delete tty
|
||||
vm_direct_exit(CompileTheWorld ? 0 : 1);
|
||||
}
|
||||
#endif
|
||||
UseCompiler = false;
|
||||
AlwaysCompileLoopMethods = false;
|
||||
}
|
||||
// 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();
|
||||
|
@ -1369,7 +1372,7 @@ void CompileBroker::compiler_thread_loop() {
|
|||
// Never compile a method if breakpoints are present in it
|
||||
if (method()->number_of_breakpoints() == 0) {
|
||||
// Compile the method.
|
||||
if (UseCompiler || AlwaysCompileLoopMethods) {
|
||||
if ((UseCompiler || AlwaysCompileLoopMethods) && CompileBroker::should_compile_new_jobs()) {
|
||||
#ifdef COMPILER1
|
||||
// Allow repeating compilations for the purpose of benchmarking
|
||||
// compile speed. This is not useful for customers.
|
||||
|
@ -1613,6 +1616,38 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
|
|||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// CompileBroker::handle_full_code_cache
|
||||
//
|
||||
// The CodeCache is full. Print out warning and disable compilation or
|
||||
// try code cache cleaning so compilation can continue later.
|
||||
void CompileBroker::handle_full_code_cache() {
|
||||
UseInterpreter = true;
|
||||
if (UseCompiler || AlwaysCompileLoopMethods ) {
|
||||
CompilerThread* thread = CompilerThread::current();
|
||||
CompileLog* log = thread->log();
|
||||
if (log != NULL) {
|
||||
log->begin_elem("code_cache_full");
|
||||
log->stamp();
|
||||
log->end_elem();
|
||||
}
|
||||
#ifndef PRODUCT
|
||||
warning("CodeCache is full. Compiler has been disabled");
|
||||
if (CompileTheWorld || ExitOnFullCodeCache) {
|
||||
before_exit(JavaThread::current());
|
||||
exit_globals(); // will delete tty
|
||||
vm_direct_exit(CompileTheWorld ? 0 : 1);
|
||||
}
|
||||
#endif
|
||||
if (UseCodeCacheFlushing) {
|
||||
NMethodSweeper::handle_full_code_cache(true);
|
||||
} else {
|
||||
UseCompiler = false;
|
||||
AlwaysCompileLoopMethods = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// CompileBroker::set_last_compile
|
||||
//
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue