src/share/vm/compiler/compileBroker.cpp
Print this page
@@ -632,23 +632,38 @@
// Get the next CompileTask from a CompileQueue
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.
+ 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();
}
}
CompileTask* task = CompilationPolicy::policy()->select_task(this);
remove(task);
@@ -1225,20 +1240,13 @@
if (method_code != NULL) {
if (compilation_is_complete(method, osr_bci, comp_level)) {
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
// seems like an assert of dubious value
assert(comp_level == CompLevel_highest_tier,
@@ -1583,13 +1591,10 @@
HandleMark hm(thread);
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();
// Give compiler threads an extra quanta. They tend to be bursty and
@@ -1941,11 +1946,15 @@
exit_globals(); // will delete tty
vm_direct_exit(CompileTheWorld ? 0 : 1);
}
#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::possibly_sweep();
+ NMethodSweeper::log_sweep("disable_compiler");
+ }
} else {
UseCompiler = false;
AlwaysCompileLoopMethods = false;
}
}