src/hotspot/share/code/nmethod.cpp
changeset 52659 8b26bd8b1832
parent 52411 35ebea32a23c
child 52661 4f45c682eab0
equal deleted inserted replaced
52658:2d18e5ed0f8d 52659:8b26bd8b1832
   563   int frame_size,
   563   int frame_size,
   564   ByteSize basic_lock_owner_sp_offset,
   564   ByteSize basic_lock_owner_sp_offset,
   565   ByteSize basic_lock_sp_offset,
   565   ByteSize basic_lock_sp_offset,
   566   OopMapSet* oop_maps )
   566   OopMapSet* oop_maps )
   567   : CompiledMethod(method, "native nmethod", type, nmethod_size, sizeof(nmethod), code_buffer, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false),
   567   : CompiledMethod(method, "native nmethod", type, nmethod_size, sizeof(nmethod), code_buffer, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false),
       
   568   _is_unloading_state(0),
   568   _native_receiver_sp_offset(basic_lock_owner_sp_offset),
   569   _native_receiver_sp_offset(basic_lock_owner_sp_offset),
   569   _native_basic_lock_sp_offset(basic_lock_sp_offset)
   570   _native_basic_lock_sp_offset(basic_lock_sp_offset)
   570 {
   571 {
   571   {
   572   {
   572     int scopes_data_offset = 0;
   573     int scopes_data_offset = 0;
   607     _deopt_mh_handler_begin = (address) this + deoptimize_mh_offset;
   608     _deopt_mh_handler_begin = (address) this + deoptimize_mh_offset;
   608 
   609 
   609     code_buffer->copy_code_and_locs_to(this);
   610     code_buffer->copy_code_and_locs_to(this);
   610     code_buffer->copy_values_to(this);
   611     code_buffer->copy_values_to(this);
   611 
   612 
       
   613     clear_unloading_state();
   612     if (ScavengeRootsInCode) {
   614     if (ScavengeRootsInCode) {
   613       Universe::heap()->register_nmethod(this);
   615       Universe::heap()->register_nmethod(this);
   614     }
   616     }
   615     debug_only(Universe::heap()->verify_nmethod(this));
   617     debug_only(Universe::heap()->verify_nmethod(this));
   616     CodeCache::commit(this);
   618     CodeCache::commit(this);
   670   , jweak installed_code,
   672   , jweak installed_code,
   671   jweak speculation_log
   673   jweak speculation_log
   672 #endif
   674 #endif
   673   )
   675   )
   674   : CompiledMethod(method, "nmethod", type, nmethod_size, sizeof(nmethod), code_buffer, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false),
   676   : CompiledMethod(method, "nmethod", type, nmethod_size, sizeof(nmethod), code_buffer, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false),
       
   677   _is_unloading_state(0),
   675   _native_receiver_sp_offset(in_ByteSize(-1)),
   678   _native_receiver_sp_offset(in_ByteSize(-1)),
   676   _native_basic_lock_sp_offset(in_ByteSize(-1))
   679   _native_basic_lock_sp_offset(in_ByteSize(-1))
   677 {
   680 {
   678   assert(debug_info->oop_recorder() == code_buffer->oop_recorder(), "shared OR");
   681   assert(debug_info->oop_recorder() == code_buffer->oop_recorder(), "shared OR");
   679   {
   682   {
  1501     f(md);
  1504     f(md);
  1502   }
  1505   }
  1503 
  1506 
  1504   // Visit metadata not embedded in the other places.
  1507   // Visit metadata not embedded in the other places.
  1505   if (_method != NULL) f(_method);
  1508   if (_method != NULL) f(_method);
       
  1509 }
       
  1510 
       
  1511 // The _is_unloading_state encodes a tuple comprising the unloading cycle
       
  1512 // and the result of IsUnloadingBehaviour::is_unloading() fpr that cycle.
       
  1513 // This is the bit layout of the _is_unloading_state byte: 00000CCU
       
  1514 // CC refers to the cycle, which has 2 bits, and U refers to the result of
       
  1515 // IsUnloadingBehaviour::is_unloading() for that unloading cycle.
       
  1516 
       
  1517 class IsUnloadingState: public AllStatic {
       
  1518   static const uint8_t _is_unloading_mask = 1;
       
  1519   static const uint8_t _is_unloading_shift = 0;
       
  1520   static const uint8_t _unloading_cycle_mask = 6;
       
  1521   static const uint8_t _unloading_cycle_shift = 1;
       
  1522 
       
  1523   static uint8_t set_is_unloading(uint8_t state, bool value) {
       
  1524     state &= ~_is_unloading_mask;
       
  1525     if (value) {
       
  1526       state |= 1 << _is_unloading_shift;
       
  1527     }
       
  1528     assert(is_unloading(state) == value, "unexpected unloading cycle overflow");
       
  1529     return state;
       
  1530   }
       
  1531 
       
  1532   static uint8_t set_unloading_cycle(uint8_t state, uint8_t value) {
       
  1533     state &= ~_unloading_cycle_mask;
       
  1534     state |= value << _unloading_cycle_shift;
       
  1535     assert(unloading_cycle(state) == value, "unexpected unloading cycle overflow");
       
  1536     return state;
       
  1537   }
       
  1538 
       
  1539 public:
       
  1540   static bool is_unloading(uint8_t state) { return (state & _is_unloading_mask) >> _is_unloading_shift == 1; }
       
  1541   static uint8_t unloading_cycle(uint8_t state) { return (state & _unloading_cycle_mask) >> _unloading_cycle_shift; }
       
  1542 
       
  1543   static uint8_t create(bool is_unloading, uint8_t unloading_cycle) {
       
  1544     uint8_t state = 0;
       
  1545     state = set_is_unloading(state, is_unloading);
       
  1546     state = set_unloading_cycle(state, unloading_cycle);
       
  1547     return state;
       
  1548   }
       
  1549 };
       
  1550 
       
  1551 bool nmethod::is_unloading() {
       
  1552   uint8_t state = RawAccess<MO_RELAXED>::load(&_is_unloading_state);
       
  1553   bool state_is_unloading = IsUnloadingState::is_unloading(state);
       
  1554   uint8_t state_unloading_cycle = IsUnloadingState::unloading_cycle(state);
       
  1555   if (state_is_unloading) {
       
  1556     return true;
       
  1557   }
       
  1558   if (state_unloading_cycle == CodeCache::unloading_cycle()) {
       
  1559     return false;
       
  1560   }
       
  1561 
       
  1562   // The IsUnloadingBehaviour is responsible for checking if there are any dead
       
  1563   // oops in the CompiledMethod, by calling oops_do on it.
       
  1564   state_unloading_cycle = CodeCache::unloading_cycle();
       
  1565   state_is_unloading = IsUnloadingBehaviour::current()->is_unloading(this);
       
  1566 
       
  1567   state = IsUnloadingState::create(state_is_unloading, state_unloading_cycle);
       
  1568 
       
  1569   RawAccess<MO_RELAXED>::store(&_is_unloading_state, state);
       
  1570 
       
  1571   return state_is_unloading;
       
  1572 }
       
  1573 
       
  1574 void nmethod::clear_unloading_state() {
       
  1575   uint8_t state = IsUnloadingState::create(false, CodeCache::unloading_cycle());
       
  1576   RawAccess<MO_RELAXED>::store(&_is_unloading_state, state);
  1506 }
  1577 }
  1507 
  1578 
  1508 
  1579 
  1509 // This is called at the end of the strong tracing/marking phase of a
  1580 // This is called at the end of the strong tracing/marking phase of a
  1510 // GC to unload an nmethod if it contains otherwise unreachable
  1581 // GC to unload an nmethod if it contains otherwise unreachable