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 |