diff --git a/src/hotspot/share/code/codeCache.hpp b/src/hotspot/share/code/codeCache.hpp index 89704dd..f76f131 100644 --- a/src/hotspot/share/code/codeCache.hpp +++ b/src/hotspot/share/code/codeCache.hpp @@ -334,13 +334,21 @@ class CodeCache : AllStatic { // Iterator to iterate over nmethods in the CodeCache. template class CodeBlobIterator : public StackObj { + public: + enum LivenessFilter { all_blobs, only_alive, only_alive_and_not_unloading }; + private: CodeBlob* _code_blob; // Current CodeBlob GrowableArrayIterator _heap; GrowableArrayIterator _end; + bool _only_alive; + bool _only_not_unloading; public: - CodeBlobIterator(T* nm = NULL) { + CodeBlobIterator(LivenessFilter filter, T* nm = NULL) + : _only_alive(filter == only_alive || filter == only_alive_and_not_unloading), + _only_not_unloading(filter == only_alive_and_not_unloading) + { if (Filter::heaps() == NULL) { return; } @@ -356,33 +364,47 @@ template class CodeBlobIterator : public StackObj { } } + CodeBlobIterator(const CodeBlobIterator& other) + : _code_blob(other._code_blob), + _heap(other._heap), + _end(other._end), + _only_alive(other._only_alive), + _only_not_unloading(other._only_not_unloading) + { } + // Advance iterator to next blob bool next() { assert_locked_or_safepoint(CodeCache_lock); - bool result = next_blob(); - while (!result && _heap != _end) { - // Advance to next code heap of segmented code cache - if (++_heap == _end) { - break; + for (;;) { + // Walk through heaps as required + if (!next_blob()) { + if (_heap == _end) { + return false; + } + ++_heap; + continue; } - result = next_blob(); - } - return result; - } + // Filter is_alive as required + if (_only_alive && !_code_blob->is_alive()) { + continue; + } + + // Filter is_unloading as required + if (_only_not_unloading) { + CompiledMethod* cm = _code_blob->as_compiled_method_or_null(); + if (cm != NULL && cm->is_unloading()) { + continue; + } + } - // Advance iterator to next alive blob - bool next_alive() { - bool result = next(); - while(result && !_code_blob->is_alive()) { - result = next(); + return true; } - return result; } - bool end() const { return _code_blob == NULL; } - T* method() const { return (T*)_code_blob; } + bool end() const { return _code_blob == NULL; } + T* method() const { return (T*)_code_blob; } private: @@ -422,7 +444,6 @@ struct NMethodFilter { static const GrowableArray* heaps() { return CodeCache::nmethod_heaps(); } }; - typedef CodeBlobIterator CompiledMethodIterator; typedef CodeBlobIterator NMethodIterator;