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.
|