< prev index next >
src/share/vm/runtime/sweeper.cpp
Print this page
@@ -142,10 +142,11 @@
long NMethodSweeper::_time_counter = 0; // Virtual time used to periodically invoke sweeper
long NMethodSweeper::_last_sweep = 0; // Value of _time_counter when the last sweep happened
int NMethodSweeper::_seen = 0; // Nof. nmethod we have currently processed in current pass of CodeCache
volatile bool NMethodSweeper::_should_sweep = true; // Indicates if we should invoke the sweeper
+volatile bool NMethodSweeper::_force_sweep = false;// Indicates if we should force a sweep
volatile int NMethodSweeper::_bytes_changed = 0; // Counts the total nmethod size if the nmethod changed from:
// 1) alive -> not_entrant
// 2) not_entrant -> zombie
// 3) zombie -> marked_for_reclamation
int NMethodSweeper::_hotness_counter_reset_val = 0;
@@ -274,10 +275,27 @@
CodeCache_lock->notify();
}
}
/**
+ * Wakes up the sweeper thread and forces a sweep. Blocks until it finished.
+ */
+void NMethodSweeper::force_sweep() {
+ ThreadBlockInVM tbivm(JavaThread::current());
+ MutexLockerEx waiter(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ // Request forced sweep
+ _force_sweep = true;
+ while (_force_sweep) {
+ // Notify sweeper that we want to force a sweep and wait for completion.
+ // In case a sweep currently takes place we timeout and try again because
+ // we want to enforce a full sweep.
+ CodeCache_lock->notify();
+ CodeCache_lock->wait(Mutex::_no_safepoint_check_flag, 1000);
+ }
+}
+
+/**
* Handle a safepoint request
*/
void NMethodSweeper::handle_safepoint_request() {
if (SafepointSynchronize::is_synchronizing()) {
if (PrintMethodFlushing && Verbose) {
@@ -333,20 +351,23 @@
if ((wait_until_next_sweep <= 0.0) || !CompileBroker::should_compile_new_jobs()) {
_should_sweep = true;
}
}
+ // Remember if this was a forced sweep
+ bool forced = _force_sweep;
+
// Force stack scanning if there is only 10% free space in the code cache.
// We force stack scanning only non-profiled code heap gets full, since critical
// allocation go to the non-profiled heap and we must be make sure that there is
// enough space.
double free_percent = 1 / CodeCache::reverse_free_ratio(CodeBlobType::MethodNonProfiled) * 100;
if (free_percent <= StartAggressiveSweepingAt) {
do_stack_scanning();
}
- if (_should_sweep) {
+ if (_should_sweep || forced) {
init_sweeper_log();
sweep_code_cache();
}
// We are done with sweeping the code cache once.
@@ -360,10 +381,18 @@
// Reset _bytes_changed only if there was enough state change. _bytes_changed
// can further increase by calls to 'report_state_change'.
if (_should_sweep) {
_bytes_changed = 0;
}
+
+ if (forced) {
+ // Notify requester that forced sweep finished
+ assert(_force_sweep, "Should be a forced sweep");
+ MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ _force_sweep = false;
+ CodeCache_lock->notify();
+ }
}
void NMethodSweeper::sweep_code_cache() {
ResourceMark rm;
Ticks sweep_start_counter = Ticks::now();
< prev index next >