< prev index next >

src/hotspot/share/code/compiledMethod.cpp


528 // nmethods are unloaded.  Return postponed=true in the parallel case for                                                            
529 // inline caches found that point to nmethods that are not yet visited during                                                        
530 // the do_unloading walk.                                                                                                            
531 void CompiledMethod::unload_nmethod_caches(bool unloading_occurred) {                                                                
532   ResourceMark rm;                                                                                                                   
533 
534   // Exception cache only needs to be called if unloading occurred                                                                   
535   if (unloading_occurred) {                                                                                                          
536     clean_exception_cache();                                                                                                         
537   }                                                                                                                                  
538 
539   cleanup_inline_caches_impl(unloading_occurred, false);                                                                             
540 
541   // All static stubs need to be cleaned.                                                                                            
542   clean_ic_stubs();                                                                                                                  
543 
544   // Check that the metadata embedded in the nmethod is alive                                                                        
545   DEBUG_ONLY(metadata_do(check_class));                                                                                              
546 }                                                                                                                                    
547 
548 // The IsUnloadingStruct represents a tuple comprising a result of                                                                   
549 // IsUnloadingBehaviour::is_unloading() for a given unloading cycle.                                                                 
550 struct IsUnloadingStruct {                                                                                                           
551   unsigned int _is_unloading:1;                                                                                                      
552   unsigned int _unloading_cycle:2;                                                                                                   
553 };                                                                                                                                   
554                                                                                                                                      
555 // The IsUnloadingUnion allows treating the tuple of the IsUnloadingStruct                                                           
556 // like a uint8_t, making it possible to read and write the tuple atomically.                                                        
557 union IsUnloadingUnion {                                                                                                             
558   IsUnloadingStruct _inflated;                                                                                                       
559   uint8_t _value;                                                                                                                    
560 };                                                                                                                                   
561 
562 bool CompiledMethod::is_unloading() {                                                                                                
563   IsUnloadingUnion state;                                                                                                            
564   state._value = RawAccess<MO_RELAXED>::load(&_is_unloading_state);                                                                  
565   if (state._inflated._is_unloading == 1) {                                                                                          
                                                                                                                                     
566     return true;                                                                                                                     
567   }                                                                                                                                  
568   if (state._inflated._unloading_cycle == CodeCache::unloading_cycle()) {                                                            
569     return state._inflated._is_unloading == 1;                                                                                       
570   }                                                                                                                                  
571 
572   // The IsUnloadingBehaviour is responsible for checking if there are any dead                                                      
573   // oops in the CompiledMethod, by calling oops_do on it.                                                                           
574   bool result = IsUnloadingBehaviour::current()->is_unloading(this);                                                                 
                                                                                                                                     
575 
576   state._inflated._unloading_cycle = CodeCache::unloading_cycle();                                                                   
577   state._inflated._is_unloading = result ? 1 : 0;                                                                                    
578 
579   RawAccess<MO_RELAXED>::store(&_is_unloading_state, state._value);                                                                  
580 
581   return result;                                                                                                                     
582 }                                                                                                                                    
583 
584 void CompiledMethod::clear_unloading_state() {                                                                                       
585   IsUnloadingUnion state;                                                                                                            
586   state._inflated._unloading_cycle = CodeCache::unloading_cycle();                                                                   
587   state._inflated._is_unloading = 0;                                                                                                 
588   RawAccess<MO_RELAXED>::store(&_is_unloading_state, state._value);                                                                  
589 }                                                                                                                                    
590 
591 // Called to clean up after class unloading for live nmethods and from the sweeper                                                   
592 // for all methods.                                                                                                                  
593 void CompiledMethod::cleanup_inline_caches_impl(bool unloading_occurred, bool clean_all) {                                           
594   assert(CompiledICLocker::is_safe(this), "mt unsafe call");                                                                         
595   ResourceMark rm;                                                                                                                   
596 
597   // Find all calls in an nmethod and clear the ones that point to non-entrant,                                                      
598   // zombie and unloaded nmethods.                                                                                                   
599   RelocIterator iter(this, oops_reloc_begin());                                                                                      
600   while(iter.next()) {                                                                                                               
601 
602     switch (iter.type()) {                                                                                                           
603 
604     case relocInfo::virtual_call_type:                                                                                               
605       if (unloading_occurred) {                                                                                                      
606         // If class unloading occurred we first clear ICs where the cached metadata                                                  
607         // is referring to an unloaded klass or method.                                                                              

528 // nmethods are unloaded.  Return postponed=true in the parallel case for
529 // inline caches found that point to nmethods that are not yet visited during
530 // the do_unloading walk.
531 void CompiledMethod::unload_nmethod_caches(bool unloading_occurred) {
532   ResourceMark rm;
533 
534   // Exception cache only needs to be called if unloading occurred
535   if (unloading_occurred) {
536     clean_exception_cache();
537   }
538 
539   cleanup_inline_caches_impl(unloading_occurred, false);
540 
541   // All static stubs need to be cleaned.
542   clean_ic_stubs();
543 
544   // Check that the metadata embedded in the nmethod is alive
545   DEBUG_ONLY(metadata_do(check_class));
546 }
547 
548 // The _is_unloading_state encodes a tuple comprising the unloading cycle
549 // and the result of IsUnloadingBehaviour::is_unloading() fpr that cycle.
550 // This is the bit layout of the _is_unloading_state byte: 00000CCU
551 // CC refers to the cycle, which has 2 bits, and U refers to the result of
552 // IsUnloadingBehaviour::is_unloading() for that unloading cycle.








553 
554 bool CompiledMethod::is_unloading() {
555   uint8_t state = RawAccess<MO_RELAXED>::load(&_is_unloading_state);
556   bool state_is_unloading = (state & (uint8_t)1u) == 1;
557   uint8_t state_unloading_cycle = (state & (uint8_t)0x7u) >> 1;
558   if (state_is_unloading) {
559     return true;
560   }
561   if (state_unloading_cycle == CodeCache::unloading_cycle()) {
562     return false;
563   }
564 
565   // The IsUnloadingBehaviour is responsible for checking if there are any dead
566   // oops in the CompiledMethod, by calling oops_do on it.
567   state_unloading_cycle = CodeCache::unloading_cycle();
568   state_is_unloading = IsUnloadingBehaviour::current()->is_unloading(this);
569 
570   state = (state_unloading_cycle << 1) | (state_is_unloading ? 1 : 0);

571 
572   RawAccess<MO_RELAXED>::store(&_is_unloading_state, state);
573 
574   return state_is_unloading;
575 }
576 
577 void CompiledMethod::clear_unloading_state() {
578   uint8_t state = CodeCache::unloading_cycle() << 1;
579   RawAccess<MO_RELAXED>::store(&_is_unloading_state, state);


580 }
581 
582 // Called to clean up after class unloading for live nmethods and from the sweeper
583 // for all methods.
584 void CompiledMethod::cleanup_inline_caches_impl(bool unloading_occurred, bool clean_all) {
585   assert(CompiledICLocker::is_safe(this), "mt unsafe call");
586   ResourceMark rm;
587 
588   // Find all calls in an nmethod and clear the ones that point to non-entrant,
589   // zombie and unloaded nmethods.
590   RelocIterator iter(this, oops_reloc_begin());
591   while(iter.next()) {
592 
593     switch (iter.type()) {
594 
595     case relocInfo::virtual_call_type:
596       if (unloading_occurred) {
597         // If class unloading occurred we first clear ICs where the cached metadata
598         // is referring to an unloaded klass or method.
< prev index next >