src/hotspot/share/code/nmethod.cpp
changeset 52847 27ebaa5566ea
parent 52800 8613f3fdbdae
child 52857 7e268f863ff0
equal deleted inserted replaced
52846:6ed72482de52 52847:27ebaa5566ea
  1573   bool state_is_unloading = IsUnloadingState::is_unloading(state);
  1573   bool state_is_unloading = IsUnloadingState::is_unloading(state);
  1574   uint8_t state_unloading_cycle = IsUnloadingState::unloading_cycle(state);
  1574   uint8_t state_unloading_cycle = IsUnloadingState::unloading_cycle(state);
  1575   if (state_is_unloading) {
  1575   if (state_is_unloading) {
  1576     return true;
  1576     return true;
  1577   }
  1577   }
  1578   if (state_unloading_cycle == CodeCache::unloading_cycle()) {
  1578   uint8_t current_cycle = CodeCache::unloading_cycle();
       
  1579   if (state_unloading_cycle == current_cycle) {
  1579     return false;
  1580     return false;
  1580   }
  1581   }
  1581 
  1582 
  1582   // The IsUnloadingBehaviour is responsible for checking if there are any dead
  1583   // The IsUnloadingBehaviour is responsible for checking if there are any dead
  1583   // oops in the CompiledMethod, by calling oops_do on it.
  1584   // oops in the CompiledMethod, by calling oops_do on it.
  1584   state_unloading_cycle = CodeCache::unloading_cycle();
  1585   state_unloading_cycle = current_cycle;
  1585   state_is_unloading = IsUnloadingBehaviour::current()->is_unloading(this);
  1586 
       
  1587   if (is_zombie()) {
       
  1588     // Zombies without calculated unloading epoch are never unloading due to GC.
       
  1589 
       
  1590     // There are no races where a previously observed is_unloading() nmethod
       
  1591     // suddenly becomes not is_unloading() due to here being observed as zombie.
       
  1592 
       
  1593     // With STW unloading, all is_alive() && is_unloading() nmethods are unlinked
       
  1594     // and unloaded in the safepoint. That makes races where an nmethod is first
       
  1595     // observed as is_alive() && is_unloading() and subsequently observed as
       
  1596     // is_zombie() impossible.
       
  1597 
       
  1598     // With concurrent unloading, all references to is_unloading() nmethods are
       
  1599     // first unlinked (e.g. IC caches and dependency contexts). Then a global
       
  1600     // handshake operation is performed with all JavaThreads before finally
       
  1601     // unloading the nmethods. The sweeper never converts is_alive() && is_unloading()
       
  1602     // nmethods to zombies; it waits for them to become is_unloaded(). So before
       
  1603     // the global handshake, it is impossible for is_unloading() nmethods to
       
  1604     // racingly become is_zombie(). And is_unloading() is calculated for all is_alive()
       
  1605     // nmethods before taking that global handshake, meaning that it will never
       
  1606     // be recalculated after the handshake.
       
  1607 
       
  1608     // After that global handshake, is_unloading() nmethods are only observable
       
  1609     // to the iterators, and they will never trigger recomputation of the cached
       
  1610     // is_unloading_state, and hence may not suffer from such races.
       
  1611 
       
  1612     state_is_unloading = false;
       
  1613   } else {
       
  1614     state_is_unloading = IsUnloadingBehaviour::current()->is_unloading(this);
       
  1615   }
  1586 
  1616 
  1587   state = IsUnloadingState::create(state_is_unloading, state_unloading_cycle);
  1617   state = IsUnloadingState::create(state_is_unloading, state_unloading_cycle);
  1588 
  1618 
  1589   RawAccess<MO_RELAXED>::store(&_is_unloading_state, state);
  1619   RawAccess<MO_RELAXED>::store(&_is_unloading_state, state);
  1590 
  1620