< prev index next >
src/hotspot/share/code/codeCache.hpp
template <class T, class Filter> class CodeBlobIterator : public StackObj {
private:
CodeBlob* _code_blob; // Current CodeBlob
GrowableArrayIterator<CodeHeap*> _heap;
GrowableArrayIterator<CodeHeap*> _end;
public:
! CodeBlobIterator(T* nm = NULL) {
if (Filter::heaps() == NULL) {
return;
}
_heap = Filter::heaps()->begin();
_end = Filter::heaps()->end();
template <class T, class Filter> class CodeBlobIterator : public StackObj {
private:
CodeBlob* _code_blob; // Current CodeBlob
GrowableArrayIterator<CodeHeap*> _heap;
GrowableArrayIterator<CodeHeap*> _end;
+ bool _only_alive;
+ bool _only_not_unloading;
public:
! CodeBlobIterator(bool only_alive, bool only_not_unloading, T* nm = NULL)
! : _only_alive(only_alive),
! _only_not_unloading(only_not_unloading)
! {
if (Filter::heaps() == NULL) {
return;
}
_heap = Filter::heaps()->begin();
_end = Filter::heaps()->end();
***************
}
assert((*_heap)->contains_blob(_code_blob), "match not found");
}
}
// 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;
}
- result = next_blob();
- }
! return result;
! }
! // Advance iterator to next alive blob
! bool next_alive() {
! bool result = next();
! while(result && !_code_blob->is_alive()) {
! result = next();
}
- return result;
}
! bool end() const { return _code_blob == NULL; }
! T* method() const { return (T*)_code_blob; }
private:
// Advance iterator to the next blob in the current code heap
bool next_blob() {
}
assert((*_heap)->contains_blob(_code_blob), "match not found");
}
}
+ 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);
! for (;;) {
! // Walk through heaps as required
! if (!next_blob()) {
! if (_heap == _end) {
! return false;
! }
! ++_heap;
! continue;
}
! // 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;
! }
! }
! return true;
}
}
! bool end() const { return _code_blob == NULL; }
! T* method() const { return (T*)_code_blob; }
private:
// Advance iterator to the next blob in the current code heap
bool next_blob() {
***************
struct NMethodFilter {
static bool apply(CodeBlob* cb) { return cb->is_nmethod(); }
static const GrowableArray<CodeHeap*>* heaps() { return CodeCache::nmethod_heaps(); }
};
-
typedef CodeBlobIterator<CompiledMethod, CompiledMethodFilter> CompiledMethodIterator;
typedef CodeBlobIterator<nmethod, NMethodFilter> NMethodIterator;
#endif // SHARE_VM_CODE_CODECACHE_HPP
< prev index next >