602 case relocInfo::opt_virtual_call_type:
603 if (!clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), this, clean_all)) {
604 return false;
605 }
606 break;
607
608 case relocInfo::static_call_type:
609 if (!clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), this, clean_all)) {
610 return false;
611 }
612 break;
613
614 default:
615 break;
616 }
617 }
618
619 return true;
620 }
621
622 // Iterating over all nmethods, e.g. with the help of CodeCache::nmethods_do(fun) was found
623 // to not be inherently safe. There is a chance that fields are seen which are not properly
624 // initialized. This happens despite the fact that nmethods_do() asserts the CodeCache_lock
625 // to be held.
626 // To bundle knowledge about necessary checks in one place, this function was introduced.
627 // It is not claimed that these checks are sufficient, but they were found to be necessary.
628 bool CompiledMethod::nmethod_access_is_safe(nmethod* nm) {
629 Method* method = (nm == NULL) ? NULL : nm->method(); // nm->method() may be uninitialized, i.e. != NULL, but invalid
630 return (nm != NULL) && (method != NULL) && (method->signature() != NULL) &&
631 !nm->is_zombie() && !nm->is_not_installed() &&
632 os::is_readable_pointer(method) &&
633 os::is_readable_pointer(method->constants()) &&
634 os::is_readable_pointer(method->signature());
635 }
636
637 class HasEvolDependency : public MetadataClosure {
638 bool _has_evol_dependency;
639 public:
640 HasEvolDependency() : _has_evol_dependency(false) {}
641 void do_metadata(Metadata* md) {
642 if (md->is_method()) {
643 Method* method = (Method*)md;
644 if (method->is_old()) {
645 _has_evol_dependency = true;
646 }
647 }
648 }
649 bool has_evol_dependency() const { return _has_evol_dependency; }
650 };
651
652 bool CompiledMethod::has_evol_metadata() {
653 // Check the metadata in relocIter and CompiledIC and also deoptimize
654 // any nmethod that has reference to old methods.
655 HasEvolDependency check_evol;
656 metadata_do(&check_evol);
|
602 case relocInfo::opt_virtual_call_type:
603 if (!clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), this, clean_all)) {
604 return false;
605 }
606 break;
607
608 case relocInfo::static_call_type:
609 if (!clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), this, clean_all)) {
610 return false;
611 }
612 break;
613
614 default:
615 break;
616 }
617 }
618
619 return true;
620 }
621
622 class HasEvolDependency : public MetadataClosure {
623 bool _has_evol_dependency;
624 public:
625 HasEvolDependency() : _has_evol_dependency(false) {}
626 void do_metadata(Metadata* md) {
627 if (md->is_method()) {
628 Method* method = (Method*)md;
629 if (method->is_old()) {
630 _has_evol_dependency = true;
631 }
632 }
633 }
634 bool has_evol_dependency() const { return _has_evol_dependency; }
635 };
636
637 bool CompiledMethod::has_evol_metadata() {
638 // Check the metadata in relocIter and CompiledIC and also deoptimize
639 // any nmethod that has reference to old methods.
640 HasEvolDependency check_evol;
641 metadata_do(&check_evol);
|