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 class IsUnloadingState: public AllStatic {
555 static const uint8_t _is_unloading_mask = 1;
556 static const uint8_t _is_unloading_shift = 0;
557 static const uint8_t _unloading_cycle_mask = 6;
558 static const uint8_t _unloading_cycle_shift = 1;
559
560 static uint8_t set_is_unloading(uint8_t state, bool value) {
561 state &= ~_is_unloading_mask;
562 if (value) {
563 state |= 1 << _is_unloading_shift;
564 }
565 assert(is_unloading(state) == value, "unexpected unloading cycle overflow");
566 return state;
567 }
568
569 static uint8_t set_unloading_cycle(uint8_t state, uint8_t value) {
570 state &= ~_unloading_cycle_mask;
571 state |= value << _unloading_cycle_shift;
572 assert(unloading_cycle(state) == value, "unexpected unloading cycle overflow");
573 return state;
574 }
575
576 public:
577 static bool is_unloading(uint8_t state) { return (state & _is_unloading_mask) >> _is_unloading_shift == 1; }
578 static uint8_t unloading_cycle(uint8_t state) { return (state & _unloading_cycle_mask) >> _unloading_cycle_shift; }
579
580 static uint8_t create(bool is_unloading, uint8_t unloading_cycle) {
581 uint8_t state = 0;
582 state = set_is_unloading(state, is_unloading);
583 state = set_unloading_cycle(state, unloading_cycle);
584 return state;
585 }
586 };
587
588 bool CompiledMethod::is_unloading() {
589 uint8_t state = RawAccess<MO_RELAXED>::load(&_is_unloading_state);
590 bool state_is_unloading = IsUnloadingState::is_unloading(state);
591 uint8_t state_unloading_cycle = IsUnloadingState::unloading_cycle(state);
592 if (state_is_unloading) {
593 return true;
594 }
595 if (state_unloading_cycle == CodeCache::unloading_cycle()) {
596 return false;
597 }
598
599 // The IsUnloadingBehaviour is responsible for checking if there are any dead
600 // oops in the CompiledMethod, by calling oops_do on it.
601 state_unloading_cycle = CodeCache::unloading_cycle();
602 state_is_unloading = IsUnloadingBehaviour::current()->is_unloading(this);
603
604 state = IsUnloadingState::create(state_is_unloading, state_unloading_cycle);
605
606 RawAccess<MO_RELAXED>::store(&_is_unloading_state, state);
607
608 return state_is_unloading;
609 }
610
611 void CompiledMethod::clear_unloading_state() {
612 uint8_t state = IsUnloadingState::create(false, CodeCache::unloading_cycle());
613 RawAccess<MO_RELAXED>::store(&_is_unloading_state, state);
614 }
615
616 // Called to clean up after class unloading for live nmethods and from the sweeper
617 // for all methods.
618 void CompiledMethod::cleanup_inline_caches_impl(bool unloading_occurred, bool clean_all) {
619 assert(CompiledICLocker::is_safe(this), "mt unsafe call");
620 ResourceMark rm;
621
622 // Find all calls in an nmethod and clear the ones that point to non-entrant,
623 // zombie and unloaded nmethods.
624 RelocIterator iter(this, oops_reloc_begin());
625 while(iter.next()) {
626
627 switch (iter.type()) {
628
629 case relocInfo::virtual_call_type:
630 if (unloading_occurred) {
631 // If class unloading occurred we first clear ICs where the cached metadata
632 // is referring to an unloaded klass or method.
|