--- old/src/share/vm/runtime/sweeper.cpp 2013-10-11 15:44:37.473819596 +0200 +++ new/src/share/vm/runtime/sweeper.cpp 2013-10-11 15:44:37.281819603 +0200 @@ -127,7 +127,8 @@ #define SWEEP(nm) #endif -nmethod* NMethodSweeper::_current = NULL; // Current nmethod +nmethod* NMethodSweeper::_current_nmethod = NULL; // Current nmethod +int NMethodSweeper::_current_type = 0; // Current CodeBlobType long NMethodSweeper::_traversals = 0; // Nof. stack traversals performed int NMethodSweeper::_seen = 0; // Nof. nmethods we have currently processed in current pass of CodeCache int NMethodSweeper::_flushed_count = 0; // Nof. nmethods flushed in current sweep @@ -183,7 +184,7 @@ return _hotness_counter_reset_val; } bool NMethodSweeper::sweep_in_progress() { - return (_current != NULL); + return (_current_nmethod != NULL); } // Scans the stacks of all Java threads and marks activations of not-entrant methods. @@ -198,13 +199,14 @@ } // Check for restart - assert(CodeCache::find_blob_unsafe(_current) == _current, "Sweeper nmethod cached state invalid"); + assert(CodeCache::find_blob_unsafe(_current_nmethod) == _current_nmethod, "Sweeper nmethod cached state invalid"); if (!sweep_in_progress() && need_marking_phase()) { - _seen = 0; - _invocations = NmethodSweepFraction; - _current = CodeCache::first_nmethod(); - _traversals += 1; - _total_time_this_sweep = 0; + _seen = 0; + _invocations = NmethodSweepFraction; + _current_nmethod = (nmethod*)CodeCache::first_blob(CodeBlobType::MethodNonProfiled); + _current_type = CodeBlobType::MethodNonProfiled; + _traversals += 1; + _total_time_this_sweep = 0; if (PrintMethodFlushing) { tty->print_cr("### Sweep: stack traversal %d", _traversals); @@ -251,7 +253,6 @@ } void NMethodSweeper::sweep_code_cache() { - jlong sweep_start_counter = os::elapsed_counter(); _flushed_count = 0; @@ -286,7 +287,7 @@ 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++) { + while ((swept_count < todo || _invocations == 1) && _current_nmethod != NULL) { swept_count++; if (SafepointSynchronize::is_synchronizing()) { // Safepoint request if (PrintMethodFlushing && Verbose) { @@ -302,19 +303,26 @@ // 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. - nmethod* next = CodeCache::next_nmethod(_current); + nmethod* next = (nmethod*)CodeCache::next_blob(_current_nmethod, _current_type); // Now ready to process nmethod and give up CodeCache_lock { MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - freed_memory += process_nmethod(_current); + freed_memory += process_nmethod(_current_nmethod, _current_type); } _seen++; - _current = next; + + while (next == NULL && _current_type < CodeBlobType::MethodProfiled) { + // We reached the last method of the type + // Go to next type that has methods available + _current_type++; + next = (nmethod*)CodeCache::first_blob(_current_type); + } + _current_nmethod = next; } } - assert(_invocations > 1 || _current == NULL, "must have scanned the whole cache"); + assert(_invocations > 1 || _current_nmethod == NULL, "must have scanned the whole cache"); if (!sweep_in_progress() && !need_marking_phase() && (_locked_seen || _not_entrant_seen_on_stack)) { // we've completed a scan without making progress but there were @@ -407,7 +415,7 @@ nm->flush(); } -int NMethodSweeper::process_nmethod(nmethod *nm) { +int NMethodSweeper::process_nmethod(nmethod *nm, int code_blob_type) { assert(!CodeCache_lock->owned_by_self(), "just checking"); int freed_memory = 0; @@ -499,7 +507,7 @@ // ReservedCodeCacheSize int reset_val = hotness_counter_reset_val(); int time_since_reset = reset_val - nm->hotness_counter(); - double threshold = -reset_val + (CodeCache::reverse_free_ratio() * NmethodSweepActivity); + double threshold = -reset_val + (CodeCache::reverse_free_ratio(code_blob_type) * NmethodSweepActivity); // The less free space in the code cache we have - the bigger reverse_free_ratio() is. // I.e., 'threshold' increases with lower available space in the code cache and a higher // NmethodSweepActivity. If the current hotness counter - which decreases from its initial