src/hotspot/share/code/codeCache.hpp
changeset 52661 4f45c682eab0
parent 52453 6e99148dbf33
child 52781 436097b038a1
equal deleted inserted replaced
52660:9cb53c505acd 52661:4f45c682eab0
   332 };
   332 };
   333 
   333 
   334 
   334 
   335 // Iterator to iterate over nmethods in the CodeCache.
   335 // Iterator to iterate over nmethods in the CodeCache.
   336 template <class T, class Filter> class CodeBlobIterator : public StackObj {
   336 template <class T, class Filter> class CodeBlobIterator : public StackObj {
       
   337  public:
       
   338   enum LivenessFilter { all_blobs, only_alive, only_alive_and_not_unloading };
       
   339 
   337  private:
   340  private:
   338   CodeBlob* _code_blob;   // Current CodeBlob
   341   CodeBlob* _code_blob;   // Current CodeBlob
   339   GrowableArrayIterator<CodeHeap*> _heap;
   342   GrowableArrayIterator<CodeHeap*> _heap;
   340   GrowableArrayIterator<CodeHeap*> _end;
   343   GrowableArrayIterator<CodeHeap*> _end;
       
   344   bool _only_alive;
       
   345   bool _only_not_unloading;
   341 
   346 
   342  public:
   347  public:
   343   CodeBlobIterator(T* nm = NULL) {
   348   CodeBlobIterator(LivenessFilter filter, T* nm = NULL)
       
   349     : _only_alive(filter == only_alive || filter == only_alive_and_not_unloading),
       
   350       _only_not_unloading(filter == only_alive_and_not_unloading)
       
   351   {
   344     if (Filter::heaps() == NULL) {
   352     if (Filter::heaps() == NULL) {
   345       return;
   353       return;
   346     }
   354     }
   347     _heap = Filter::heaps()->begin();
   355     _heap = Filter::heaps()->begin();
   348     _end = Filter::heaps()->end();
   356     _end = Filter::heaps()->end();
   358 
   366 
   359   // Advance iterator to next blob
   367   // Advance iterator to next blob
   360   bool next() {
   368   bool next() {
   361     assert_locked_or_safepoint(CodeCache_lock);
   369     assert_locked_or_safepoint(CodeCache_lock);
   362 
   370 
   363     bool result = next_blob();
   371     for (;;) {
   364     while (!result && _heap != _end) {
   372       // Walk through heaps as required
   365       // Advance to next code heap of segmented code cache
   373       if (!next_blob()) {
   366       if (++_heap == _end) {
   374         if (_heap == _end) {
   367         break;
   375           return false;
       
   376         }
       
   377         ++_heap;
       
   378         continue;
   368       }
   379       }
   369       result = next_blob();
   380 
   370     }
   381       // Filter is_alive as required
   371 
   382       if (_only_alive && !_code_blob->is_alive()) {
   372     return result;
   383         continue;
   373   }
   384       }
   374 
   385 
   375   // Advance iterator to next alive blob
   386       // Filter is_unloading as required
   376   bool next_alive() {
   387       if (_only_not_unloading) {
   377     bool result = next();
   388         CompiledMethod* cm = _code_blob->as_compiled_method_or_null();
   378     while(result && !_code_blob->is_alive()) {
   389         if (cm != NULL && cm->is_unloading()) {
   379       result = next();
   390           continue;
   380     }
   391         }
   381     return result;
   392       }
   382   }
   393 
   383 
   394       return true;
   384   bool end()        const   { return _code_blob == NULL; }
   395     }
   385   T* method() const   { return (T*)_code_blob; }
   396   }
       
   397 
       
   398   bool end()  const { return _code_blob == NULL; }
       
   399   T* method() const { return (T*)_code_blob; }
   386 
   400 
   387 private:
   401 private:
   388 
   402 
   389   // Advance iterator to the next blob in the current code heap
   403   // Advance iterator to the next blob in the current code heap
   390   bool next_blob() {
   404   bool next_blob() {
   420 struct NMethodFilter {
   434 struct NMethodFilter {
   421   static bool apply(CodeBlob* cb) { return cb->is_nmethod(); }
   435   static bool apply(CodeBlob* cb) { return cb->is_nmethod(); }
   422   static const GrowableArray<CodeHeap*>* heaps() { return CodeCache::nmethod_heaps(); }
   436   static const GrowableArray<CodeHeap*>* heaps() { return CodeCache::nmethod_heaps(); }
   423 };
   437 };
   424 
   438 
   425 
       
   426 typedef CodeBlobIterator<CompiledMethod, CompiledMethodFilter> CompiledMethodIterator;
   439 typedef CodeBlobIterator<CompiledMethod, CompiledMethodFilter> CompiledMethodIterator;
   427 typedef CodeBlobIterator<nmethod, NMethodFilter> NMethodIterator;
   440 typedef CodeBlobIterator<nmethod, NMethodFilter> NMethodIterator;
   428 
   441 
   429 #endif // SHARE_VM_CODE_CODECACHE_HPP
   442 #endif // SHARE_VM_CODE_CODECACHE_HPP