< prev index next >

src/hotspot/share/runtime/sweeper.cpp


681 
682   MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);                                                                 
683   nm->flush();                                                                                                                       
684 }                                                                                                                                    
685 
686 NMethodSweeper::MethodStateChange NMethodSweeper::process_compiled_method(CompiledMethod* cm) {                                      
687   assert(cm != NULL, "sanity");                                                                                                      
688   assert(!CodeCache_lock->owned_by_self(), "just checking");                                                                         
689 
690   MethodStateChange result = None;                                                                                                   
691   // Make sure this nmethod doesn't get unloaded during the scan,                                                                    
692   // since safepoints may happen during acquired below locks.                                                                        
693   CompiledMethodMarker nmm(cm);                                                                                                      
694   SWEEP(cm);                                                                                                                         
695 
696   // Skip methods that are currently referenced by the VM                                                                            
697   if (cm->is_locked_by_vm()) {                                                                                                       
698     // But still remember to clean-up inline caches for alive nmethods                                                               
699     if (cm->is_alive() && !cm->is_unloading()) {                                                                                     
700       // Clean inline caches that point to zombie/non-entrant/unloaded nmethods                                                      
701       CompiledICLocker ml(cm);                                                                                                       
702       cm->cleanup_inline_caches(false);                                                                                              
703       SWEEP(cm);                                                                                                                     
704     }                                                                                                                                
705     return result;                                                                                                                   
706   }                                                                                                                                  
707 
708   if (cm->is_zombie()) {                                                                                                             
709     // All inline caches that referred to this nmethod were cleaned in the                                                           
710     // previous sweeper cycle. Now flush the nmethod from the code cache.                                                            
711     assert(!cm->is_locked_by_vm(), "must not flush locked Compiled Methods");                                                        
712     release_compiled_method(cm);                                                                                                     
713     assert(result == None, "sanity");                                                                                                
714     result = Flushed;                                                                                                                
715   } else if (cm->is_not_entrant()) {                                                                                                 
716     // If there are no current activations of this method on the                                                                     
717     // stack we can safely convert it to a zombie method                                                                             
718     OrderAccess::loadload(); // _stack_traversal_mark and _state                                                                     
719     if (cm->can_convert_to_zombie()) {                                                                                               
720       // Clear ICStubs to prevent back patching stubs of zombie or flushed                                                           

681 
682   MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
683   nm->flush();
684 }
685 
686 NMethodSweeper::MethodStateChange NMethodSweeper::process_compiled_method(CompiledMethod* cm) {
687   assert(cm != NULL, "sanity");
688   assert(!CodeCache_lock->owned_by_self(), "just checking");
689 
690   MethodStateChange result = None;
691   // Make sure this nmethod doesn't get unloaded during the scan,
692   // since safepoints may happen during acquired below locks.
693   CompiledMethodMarker nmm(cm);
694   SWEEP(cm);
695 
696   // Skip methods that are currently referenced by the VM
697   if (cm->is_locked_by_vm()) {
698     // But still remember to clean-up inline caches for alive nmethods
699     if (cm->is_alive() && !cm->is_unloading()) {
700       // Clean inline caches that point to zombie/non-entrant/unloaded nmethods

701       cm->cleanup_inline_caches(false);
702       SWEEP(cm);
703     }
704     return result;
705   }
706 
707   if (cm->is_zombie()) {
708     // All inline caches that referred to this nmethod were cleaned in the
709     // previous sweeper cycle. Now flush the nmethod from the code cache.
710     assert(!cm->is_locked_by_vm(), "must not flush locked Compiled Methods");
711     release_compiled_method(cm);
712     assert(result == None, "sanity");
713     result = Flushed;
714   } else if (cm->is_not_entrant()) {
715     // If there are no current activations of this method on the
716     // stack we can safely convert it to a zombie method
717     OrderAccess::loadload(); // _stack_traversal_mark and _state
718     if (cm->can_convert_to_zombie()) {
719       // Clear ICStubs to prevent back patching stubs of zombie or flushed

727       cm->make_zombie();                                                                                                             
728       SWEEP(cm);                                                                                                                     
729       // The nmethod may have been locked by JVMTI after being made zombie (see                                                      
730       // JvmtiDeferredEvent::compiled_method_unload_event()). If so, we cannot                                                       
731       // flush the osr nmethod directly but have to wait for a later sweeper cycle.                                                  
732       if (cm->is_osr_method() && !cm->is_locked_by_vm()) {                                                                           
733         // No inline caches will ever point to osr methods, so we can just remove it.                                                
734         // Make sure that we unregistered the nmethod with the heap and flushed all                                                  
735         // dependencies before removing the nmethod (done in make_zombie()).                                                         
736         assert(cm->is_zombie(), "nmethod must be unregistered");                                                                     
737         release_compiled_method(cm);                                                                                                 
738         assert(result == None, "sanity");                                                                                            
739         result = Flushed;                                                                                                            
740       } else {                                                                                                                       
741         assert(result == None, "sanity");                                                                                            
742         result = MadeZombie;                                                                                                         
743         assert(cm->is_zombie(), "nmethod must be zombie");                                                                           
744       }                                                                                                                              
745     } else {                                                                                                                         
746       // Still alive, clean up its inline caches                                                                                     
747       CompiledICLocker ml(cm);                                                                                                       
748       cm->cleanup_inline_caches(false);                                                                                              
749       SWEEP(cm);                                                                                                                     
750     }                                                                                                                                
751   } else if (cm->is_unloaded()) {                                                                                                    
752     // Code is unloaded, so there are no activations on the stack.                                                                   
753     // Convert the nmethod to zombie or flush it directly in the OSR case.                                                           
754     {                                                                                                                                
755       // Clean ICs of unloaded nmethods as well because they may reference other                                                     
756       // unloaded nmethods that may be flushed earlier in the sweeper cycle.                                                         
757       CompiledICLocker ml(cm);                                                                                                       
758       cm->cleanup_inline_caches(false);                                                                                              
759     }                                                                                                                                
760     if (cm->is_osr_method()) {                                                                                                       
761       SWEEP(cm);                                                                                                                     
762       // No inline caches will ever point to osr methods, so we can just remove it                                                   
763       release_compiled_method(cm);                                                                                                   
764       assert(result == None, "sanity");                                                                                              
765       result = Flushed;                                                                                                              
766     } else {                                                                                                                         
767       // Code cache state change is tracked in make_zombie()                                                                         
768       cm->make_zombie();                                                                                                             
769       SWEEP(cm);                                                                                                                     
770       assert(result == None, "sanity");                                                                                              
771       result = MadeZombie;                                                                                                           
772     }                                                                                                                                
773   } else {                                                                                                                           
774     if (cm->is_nmethod()) {                                                                                                          
775       possibly_flush((nmethod*)cm);                                                                                                  
776     }                                                                                                                                
777     // Clean inline caches that point to zombie/non-entrant/unloaded nmethods                                                        
778     CompiledICLocker ml(cm);                                                                                                         
779     cm->cleanup_inline_caches(false);                                                                                                
780     SWEEP(cm);                                                                                                                       
781   }                                                                                                                                  
782   return result;                                                                                                                     
783 }                                                                                                                                    
784 
785 
786 void NMethodSweeper::possibly_flush(nmethod* nm) {                                                                                   
787   if (UseCodeCacheFlushing) {                                                                                                        
788     if (!nm->is_locked_by_vm() && !nm->is_native_method() && !nm->is_not_installed() && !nm->is_unloading()) {                       
789       bool make_not_entrant = false;                                                                                                 
790 
791       // Do not make native methods not-entrant                                                                                      
792       nm->dec_hotness_counter();                                                                                                     
793       // Get the initial value of the hotness counter. This value depends on the                                                     
794       // ReservedCodeCacheSize                                                                                                       
795       int reset_val = hotness_counter_reset_val();                                                                                   
796       int time_since_reset = reset_val - nm->hotness_counter();                                                                      
797       int code_blob_type = CodeCache::get_code_blob_type(nm);                                                                        

726       cm->make_zombie();
727       SWEEP(cm);
728       // The nmethod may have been locked by JVMTI after being made zombie (see
729       // JvmtiDeferredEvent::compiled_method_unload_event()). If so, we cannot
730       // flush the osr nmethod directly but have to wait for a later sweeper cycle.
731       if (cm->is_osr_method() && !cm->is_locked_by_vm()) {
732         // No inline caches will ever point to osr methods, so we can just remove it.
733         // Make sure that we unregistered the nmethod with the heap and flushed all
734         // dependencies before removing the nmethod (done in make_zombie()).
735         assert(cm->is_zombie(), "nmethod must be unregistered");
736         release_compiled_method(cm);
737         assert(result == None, "sanity");
738         result = Flushed;
739       } else {
740         assert(result == None, "sanity");
741         result = MadeZombie;
742         assert(cm->is_zombie(), "nmethod must be zombie");
743       }
744     } else {
745       // Still alive, clean up its inline caches

746       cm->cleanup_inline_caches(false);
747       SWEEP(cm);
748     }
749   } else if (cm->is_unloaded()) {
750     // Code is unloaded, so there are no activations on the stack.
751     // Convert the nmethod to zombie or flush it directly in the OSR case.
752 
753     // Clean ICs of unloaded nmethods as well because they may reference other
754     // unloaded nmethods that may be flushed earlier in the sweeper cycle.
755     cm->cleanup_inline_caches(false);


756     if (cm->is_osr_method()) {
757       SWEEP(cm);
758       // No inline caches will ever point to osr methods, so we can just remove it
759       release_compiled_method(cm);
760       assert(result == None, "sanity");
761       result = Flushed;
762     } else {
763       // Code cache state change is tracked in make_zombie()
764       cm->make_zombie();
765       SWEEP(cm);
766       assert(result == None, "sanity");
767       result = MadeZombie;
768     }
769   } else {
770     if (cm->is_nmethod()) {
771       possibly_flush((nmethod*)cm);
772     }
773     // Clean inline caches that point to zombie/non-entrant/unloaded nmethods

774     cm->cleanup_inline_caches(false);
775     SWEEP(cm);
776   }
777   return result;
778 }
779 
780 
781 void NMethodSweeper::possibly_flush(nmethod* nm) {
782   if (UseCodeCacheFlushing) {
783     if (!nm->is_locked_by_vm() && !nm->is_native_method() && !nm->is_not_installed() && !nm->is_unloading()) {
784       bool make_not_entrant = false;
785 
786       // Do not make native methods not-entrant
787       nm->dec_hotness_counter();
788       // Get the initial value of the hotness counter. This value depends on the
789       // ReservedCodeCacheSize
790       int reset_val = hotness_counter_reset_val();
791       int time_since_reset = reset_val - nm->hotness_counter();
792       int code_blob_type = CodeCache::get_code_blob_type(nm);
< prev index next >