--- old/src/share/vm/runtime/sweeper.hpp 2012-02-14 16:37:44.778711000 -0800 +++ new/src/share/vm/runtime/sweeper.hpp 2012-02-14 16:37:44.549536000 -0800 @@ -32,11 +32,11 @@ class NMethodSweeper : public AllStatic { static long _traversals; // Stack traversal count - static nmethod* _current; // Current nmethod static int _seen; // Nof. nmethod we have currently processed in current pass of CodeCache + static int _invocations; // No. of invocations of the sweeper - static volatile int _invocations; // No. of invocations left until we are completed with this pass - static volatile int _sweep_started; // Flag to control conc sweeper + static volatile int _sweep_started; // Flag to control conc sweeper + static volatile nmethod* _current; // Current nmethod static bool _rescan; // Indicates that we should do a full rescan of the // of the code cache looking for work to do. --- old/src/share/vm/runtime/sweeper.cpp 2012-02-14 16:37:44.780494000 -0800 +++ new/src/share/vm/runtime/sweeper.cpp 2012-02-14 16:37:44.548004000 -0800 @@ -126,11 +126,11 @@ long NMethodSweeper::_traversals = 0; // No. of stack traversals performed -nmethod* NMethodSweeper::_current = NULL; // Current nmethod int NMethodSweeper::_seen = 0 ; // No. of nmethods we have currently processed in current pass of CodeCache +int NMethodSweeper::_invocations = 0; // No. of invocations of the sweeper -volatile int NMethodSweeper::_invocations = 0; // No. of invocations left until we are completed with this pass -volatile int NMethodSweeper::_sweep_started = 0; // Whether a sweep is in progress. +volatile int NMethodSweeper::_sweep_started = 0; // Whether a sweep is in progress. +volatile nmethod* NMethodSweeper::_current = NULL; // Current nmethod jint NMethodSweeper::_locked_seen = 0; jint NMethodSweeper::_not_entrant_seen_on_stack = 0; @@ -176,7 +176,7 @@ assert(CodeCache::find_blob_unsafe(_current) == _current, "Sweeper nmethod cached state invalid"); if (_current == NULL) { _seen = 0; - _invocations = NmethodSweepFraction; + _invocations = 0; _current = CodeCache::first_nmethod(); _traversals += 1; if (PrintMethodFlushing) { @@ -219,7 +219,7 @@ assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode"); if ((!MethodFlushing) || (!_do_sweep)) return; - if (_invocations > 0) { + if (_current != NULL) { // Only one thread at a time will sweep jint old = Atomic::cmpxchg( 1, &_sweep_started, 0 ); if (old != 0) { @@ -232,15 +232,15 @@ memset(_records, 0, sizeof(SweeperRecord) * SweeperLogEntries); } #endif - if (_invocations > 0) { + if (_current != NULL) { sweep_code_cache(); - _invocations--; } + _invocations++; _sweep_started = 0; } } -void NMethodSweeper::sweep_code_cache() { +void NMethodSweeper::sweep_code_cache(void) { #ifdef ASSERT jlong sweep_start; if (PrintMethodFlushing) { @@ -248,16 +248,9 @@ } #endif if (PrintMethodFlushing && Verbose) { - tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_nmethods(), _invocations); + tty->print_cr("### Sweep at %d out of %d, invocations %d", _seen, CodeCache::nof_nmethods(), _invocations); } - // We want to visit all nmethods after NmethodSweepFraction - // invocations so divide the remaining number of nmethods by the - // remaining number of invocations. This is only an estimate since - // the number of nmethods changes during the sweep so the final - // stage must iterate until it there are no more nmethods. - int todo = (CodeCache::nof_nmethods() - _seen) / _invocations; - assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here"); assert(!CodeCache_lock->owned_by_self(), "just checking"); @@ -265,8 +258,18 @@ MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); // The last invocation iterates until there are no more nmethods - for (int i = 0; (i < todo || _invocations == 1) && _current != NULL; i++) { + for (int i = 0; (i < NMethodSweepLimit || CompileTheWorld) && _current != NULL; i++) { + if (!CompileTheWorld && SafepointSynchronize::is_synchronizing()) { // Safepoint request + if (PrintMethodFlushing && Verbose) { + tty->print_cr("### Sweep at %d out of %d, safepoint", _seen, CodeCache::nof_nmethods()); + } + MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + assert(Thread::current()->is_Java_thread(), "should be java thread"); + JavaThread* thread = (JavaThread*)Thread::current(); + ThreadBlockInVM tbivm(thread); + thread->java_suspend_self(); + } // Since we will give up the CodeCache_lock, always skip ahead // to the next nmethod. Other blobs can be deleted by other // threads but nmethods are only reclaimed by the sweeper. @@ -282,8 +285,6 @@ } } - assert(_invocations > 1 || _current == NULL, "must have scanned the whole cache"); - if (_current == NULL && !_rescan && (_locked_seen || _not_entrant_seen_on_stack)) { // we've completed a scan without making progress but there were // nmethods we were unable to process either because they were @@ -303,7 +304,7 @@ } #endif - if (_invocations == 1) { + if (_current == NULL) { log_sweep("finished"); } } --- old/src/share/vm/runtime/arguments.cpp 2012-02-14 16:37:44.787924000 -0800 +++ new/src/share/vm/runtime/arguments.cpp 2012-02-14 16:37:44.550068000 -0800 @@ -3175,15 +3175,6 @@ DebugNonSafepoints = true; } -#ifndef PRODUCT - if (CompileTheWorld) { - // Force NmethodSweeper to sweep whole CodeCache each time. - if (FLAG_IS_DEFAULT(NmethodSweepFraction)) { - NmethodSweepFraction = 1; - } - } -#endif - if (PrintCommandLineFlags) { CommandLineFlags::printSetFlags(tty); } --- old/src/share/vm/runtime/globals.hpp 2012-02-14 16:37:44.804388000 -0800 +++ new/src/share/vm/runtime/globals.hpp 2012-02-14 16:37:44.574985000 -0800 @@ -3013,8 +3013,8 @@ product(intx, SafepointTimeoutDelay, 10000, \ "Delay in milliseconds for option SafepointTimeout") \ \ - product(intx, NmethodSweepFraction, 4, \ - "Number of invocations of sweeper to cover all nmethods") \ + product(intx, NMethodSweepLimit, 256, \ + "Maximum amount of nmethods to scan per sweeper invocation") \ \ product(intx, NmethodSweepCheckInterval, 5, \ "Compilers wake up every n seconds to possibly sweep nmethods") \