3608 |
3599 |
3609 |
3600 |
3610 // RedefineClasses() support for previous versions: |
3601 // RedefineClasses() support for previous versions: |
3611 |
3602 |
3612 // Purge previous versions |
3603 // Purge previous versions |
3613 static void purge_previous_versions_internal(InstanceKlass* ik, int emcp_method_count) { |
3604 void InstanceKlass::purge_previous_versions(InstanceKlass* ik) { |
3614 if (ik->previous_versions() != NULL) { |
3605 if (ik->previous_versions() != NULL) { |
3615 // This klass has previous versions so see what we can cleanup |
3606 // This klass has previous versions so see what we can cleanup |
3616 // while it is safe to do so. |
3607 // while it is safe to do so. |
3617 |
3608 |
3618 int deleted_count = 0; // leave debugging breadcrumbs |
3609 int deleted_count = 0; // leave debugging breadcrumbs |
3619 int live_count = 0; |
3610 int live_count = 0; |
3620 ClassLoaderData* loader_data = ik->class_loader_data() == NULL ? |
3611 ClassLoaderData* loader_data = ik->class_loader_data(); |
3621 ClassLoaderData::the_null_class_loader_data() : |
3612 assert(loader_data != NULL, "should never be null"); |
3622 ik->class_loader_data(); |
|
3623 |
3613 |
3624 // RC_TRACE macro has an embedded ResourceMark |
3614 // RC_TRACE macro has an embedded ResourceMark |
3625 RC_TRACE(0x00000200, ("purge: %s: previous version length=%d", |
3615 RC_TRACE(0x00000200, ("purge: %s: previous versions", ik->external_name())); |
3626 ik->external_name(), ik->previous_versions()->length())); |
3616 |
3627 |
3617 // previous versions are linked together through the InstanceKlass |
3628 for (int i = ik->previous_versions()->length() - 1; i >= 0; i--) { |
3618 InstanceKlass* pv_node = ik->previous_versions(); |
3629 // check the previous versions array |
3619 InstanceKlass* last = ik; |
3630 PreviousVersionNode * pv_node = ik->previous_versions()->at(i); |
3620 int version = 0; |
3631 ConstantPool* cp_ref = pv_node->prev_constant_pool(); |
3621 |
3632 assert(cp_ref != NULL, "cp ref was unexpectedly cleared"); |
3622 // check the previous versions list |
3633 |
3623 for (; pv_node != NULL; ) { |
3634 ConstantPool* pvcp = cp_ref; |
3624 |
|
3625 ConstantPool* pvcp = pv_node->constants(); |
|
3626 assert(pvcp != NULL, "cp ref was unexpectedly cleared"); |
|
3627 |
|
3628 |
3635 if (!pvcp->on_stack()) { |
3629 if (!pvcp->on_stack()) { |
3636 // If the constant pool isn't on stack, none of the methods |
3630 // If the constant pool isn't on stack, none of the methods |
3637 // are executing. Delete all the methods, the constant pool and |
3631 // are executing. Unlink this previous_version. |
3638 // and this previous version node. |
3632 // The previous version InstanceKlass is on the ClassLoaderData deallocate list |
3639 GrowableArray<Method*>* method_refs = pv_node->prev_EMCP_methods(); |
3633 // so will be deallocated during the next phase of class unloading. |
3640 if (method_refs != NULL) { |
3634 pv_node = pv_node->previous_versions(); |
3641 for (int j = method_refs->length() - 1; j >= 0; j--) { |
3635 last->link_previous_versions(pv_node); |
3642 Method* method = method_refs->at(j); |
|
3643 assert(method != NULL, "method ref was unexpectedly cleared"); |
|
3644 method_refs->remove_at(j); |
|
3645 // method will be freed with associated class. |
|
3646 } |
|
3647 } |
|
3648 // Remove the constant pool |
|
3649 delete pv_node; |
|
3650 // Since we are traversing the array backwards, we don't have to |
|
3651 // do anything special with the index. |
|
3652 ik->previous_versions()->remove_at(i); |
|
3653 deleted_count++; |
3636 deleted_count++; |
|
3637 version++; |
3654 continue; |
3638 continue; |
3655 } else { |
3639 } else { |
3656 RC_TRACE(0x00000200, ("purge: previous version @%d is alive", i)); |
3640 RC_TRACE(0x00000200, ("purge: previous version " INTPTR_FORMAT " is alive", |
|
3641 pv_node)); |
3657 assert(pvcp->pool_holder() != NULL, "Constant pool with no holder"); |
3642 assert(pvcp->pool_holder() != NULL, "Constant pool with no holder"); |
3658 guarantee (!loader_data->is_unloading(), "unloaded classes can't be on the stack"); |
3643 guarantee (!loader_data->is_unloading(), "unloaded classes can't be on the stack"); |
3659 live_count++; |
3644 live_count++; |
3660 } |
3645 } |
3661 |
3646 |
3662 // At least one method is live in this previous version, clean out |
3647 // At least one method is live in this previous version so clean its MethodData. |
3663 // the others or mark them as obsolete. |
3648 // Reset dead EMCP methods not to get breakpoints. |
3664 GrowableArray<Method*>* method_refs = pv_node->prev_EMCP_methods(); |
3649 // All methods are deallocated when all of the methods for this class are no |
|
3650 // longer running. |
|
3651 Array<Method*>* method_refs = pv_node->methods(); |
3665 if (method_refs != NULL) { |
3652 if (method_refs != NULL) { |
3666 RC_TRACE(0x00000200, ("purge: previous methods length=%d", |
3653 RC_TRACE(0x00000200, ("purge: previous methods length=%d", |
3667 method_refs->length())); |
3654 method_refs->length())); |
3668 for (int j = method_refs->length() - 1; j >= 0; j--) { |
3655 for (int j = 0; j < method_refs->length(); j++) { |
3669 Method* method = method_refs->at(j); |
3656 Method* method = method_refs->at(j); |
3670 assert(method != NULL, "method ref was unexpectedly cleared"); |
3657 |
3671 |
|
3672 // Remove the emcp method if it's not executing |
|
3673 // If it's been made obsolete by a redefinition of a non-emcp |
|
3674 // method, mark it as obsolete but leave it to clean up later. |
|
3675 if (!method->on_stack()) { |
3658 if (!method->on_stack()) { |
3676 method_refs->remove_at(j); |
3659 // no breakpoints for non-running methods |
3677 } else if (emcp_method_count == 0) { |
3660 if (method->is_running_emcp()) { |
3678 method->set_is_obsolete(); |
3661 method->set_running_emcp(false); |
|
3662 } |
3679 } else { |
3663 } else { |
|
3664 assert (method->is_obsolete() || method->is_running_emcp(), |
|
3665 "emcp method cannot run after emcp bit is cleared"); |
3680 // RC_TRACE macro has an embedded ResourceMark |
3666 // RC_TRACE macro has an embedded ResourceMark |
3681 RC_TRACE(0x00000200, |
3667 RC_TRACE(0x00000200, |
3682 ("purge: %s(%s): prev method @%d in version @%d is alive", |
3668 ("purge: %s(%s): prev method @%d in version @%d is alive", |
3683 method->name()->as_C_string(), |
3669 method->name()->as_C_string(), |
3684 method->signature()->as_C_string(), j, i)); |
3670 method->signature()->as_C_string(), j, version)); |
3685 if (method->method_data() != NULL) { |
3671 if (method->method_data() != NULL) { |
3686 // Clean out any weak method links |
3672 // Clean out any weak method links for running methods |
|
3673 // (also should include not EMCP methods) |
3687 method->method_data()->clean_weak_method_links(); |
3674 method->method_data()->clean_weak_method_links(); |
3688 } |
3675 } |
3689 } |
3676 } |
3690 } |
3677 } |
3691 } |
3678 } |
3692 } |
3679 // next previous version |
3693 assert(ik->previous_versions()->length() == live_count, "sanity check"); |
3680 last = pv_node; |
|
3681 pv_node = pv_node->previous_versions(); |
|
3682 version++; |
|
3683 } |
3694 RC_TRACE(0x00000200, |
3684 RC_TRACE(0x00000200, |
3695 ("purge: previous version stats: live=%d, deleted=%d", live_count, |
3685 ("purge: previous version stats: live=%d, deleted=%d", live_count, |
3696 deleted_count)); |
3686 deleted_count)); |
3697 } |
3687 } |
3698 |
3688 |
|
3689 // Clean MethodData of this class's methods so they don't refer to |
|
3690 // old methods that are no longer running. |
3699 Array<Method*>* methods = ik->methods(); |
3691 Array<Method*>* methods = ik->methods(); |
3700 int num_methods = methods->length(); |
3692 int num_methods = methods->length(); |
3701 for (int index2 = 0; index2 < num_methods; ++index2) { |
3693 for (int index2 = 0; index2 < num_methods; ++index2) { |
3702 if (methods->at(index2)->method_data() != NULL) { |
3694 if (methods->at(index2)->method_data() != NULL) { |
3703 methods->at(index2)->method_data()->clean_weak_method_links(); |
3695 methods->at(index2)->method_data()->clean_weak_method_links(); |
3704 } |
3696 } |
3705 } |
3697 } |
3706 } |
3698 } |
3707 |
3699 |
3708 // External interface for use during class unloading. |
3700 void InstanceKlass::mark_newly_obsolete_methods(Array<Method*>* old_methods, |
3709 void InstanceKlass::purge_previous_versions(InstanceKlass* ik) { |
3701 int emcp_method_count) { |
3710 // Call with >0 emcp methods since they are not currently being redefined. |
|
3711 purge_previous_versions_internal(ik, 1); |
|
3712 } |
|
3713 |
|
3714 |
|
3715 // Potentially add an information node that contains pointers to the |
|
3716 // interesting parts of the previous version of the_class. |
|
3717 // This is also where we clean out any unused references. |
|
3718 // Note that while we delete nodes from the _previous_versions |
|
3719 // array, we never delete the array itself until the klass is |
|
3720 // unloaded. The has_been_redefined() query depends on that fact. |
|
3721 // |
|
3722 void InstanceKlass::add_previous_version(instanceKlassHandle ikh, |
|
3723 BitMap* emcp_methods, int emcp_method_count) { |
|
3724 assert(Thread::current()->is_VM_thread(), |
|
3725 "only VMThread can add previous versions"); |
|
3726 |
|
3727 if (_previous_versions == NULL) { |
|
3728 // This is the first previous version so make some space. |
|
3729 // Start with 2 elements under the assumption that the class |
|
3730 // won't be redefined much. |
|
3731 _previous_versions = new (ResourceObj::C_HEAP, mtClass) |
|
3732 GrowableArray<PreviousVersionNode *>(2, true); |
|
3733 } |
|
3734 |
|
3735 ConstantPool* cp_ref = ikh->constants(); |
|
3736 |
|
3737 // RC_TRACE macro has an embedded ResourceMark |
|
3738 RC_TRACE(0x00000400, ("adding previous version ref for %s @%d, EMCP_cnt=%d " |
|
3739 "on_stack=%d", |
|
3740 ikh->external_name(), _previous_versions->length(), emcp_method_count, |
|
3741 cp_ref->on_stack())); |
|
3742 |
|
3743 // If the constant pool for this previous version of the class |
|
3744 // is not marked as being on the stack, then none of the methods |
|
3745 // in this previous version of the class are on the stack so |
|
3746 // we don't need to create a new PreviousVersionNode. However, |
|
3747 // we still need to examine older previous versions below. |
|
3748 Array<Method*>* old_methods = ikh->methods(); |
|
3749 |
|
3750 if (cp_ref->on_stack()) { |
|
3751 PreviousVersionNode * pv_node = NULL; |
|
3752 if (emcp_method_count == 0) { |
|
3753 // non-shared ConstantPool gets a reference |
|
3754 pv_node = new PreviousVersionNode(cp_ref, NULL); |
|
3755 RC_TRACE(0x00000400, |
|
3756 ("add: all methods are obsolete; flushing any EMCP refs")); |
|
3757 } else { |
|
3758 int local_count = 0; |
|
3759 GrowableArray<Method*>* method_refs = new (ResourceObj::C_HEAP, mtClass) |
|
3760 GrowableArray<Method*>(emcp_method_count, true); |
|
3761 for (int i = 0; i < old_methods->length(); i++) { |
|
3762 if (emcp_methods->at(i)) { |
|
3763 // this old method is EMCP. Save it only if it's on the stack |
|
3764 Method* old_method = old_methods->at(i); |
|
3765 if (old_method->on_stack()) { |
|
3766 method_refs->append(old_method); |
|
3767 } |
|
3768 if (++local_count >= emcp_method_count) { |
|
3769 // no more EMCP methods so bail out now |
|
3770 break; |
|
3771 } |
|
3772 } |
|
3773 } |
|
3774 // non-shared ConstantPool gets a reference |
|
3775 pv_node = new PreviousVersionNode(cp_ref, method_refs); |
|
3776 } |
|
3777 // append new previous version. |
|
3778 _previous_versions->append(pv_node); |
|
3779 } |
|
3780 |
|
3781 // Since the caller is the VMThread and we are at a safepoint, this |
|
3782 // is a good time to clear out unused references. |
|
3783 |
|
3784 RC_TRACE(0x00000400, ("add: previous version length=%d", |
|
3785 _previous_versions->length())); |
|
3786 |
|
3787 // Purge previous versions not executing on the stack |
|
3788 purge_previous_versions_internal(this, emcp_method_count); |
|
3789 |
|
3790 int obsolete_method_count = old_methods->length() - emcp_method_count; |
3702 int obsolete_method_count = old_methods->length() - emcp_method_count; |
3791 |
3703 |
3792 if (emcp_method_count != 0 && obsolete_method_count != 0 && |
3704 if (emcp_method_count != 0 && obsolete_method_count != 0 && |
3793 _previous_versions->length() > 0) { |
3705 _previous_versions != NULL) { |
3794 // We have a mix of obsolete and EMCP methods so we have to |
3706 // We have a mix of obsolete and EMCP methods so we have to |
3795 // clear out any matching EMCP method entries the hard way. |
3707 // clear out any matching EMCP method entries the hard way. |
3796 int local_count = 0; |
3708 int local_count = 0; |
3797 for (int i = 0; i < old_methods->length(); i++) { |
3709 for (int i = 0; i < old_methods->length(); i++) { |
3798 if (!emcp_methods->at(i)) { |
3710 Method* old_method = old_methods->at(i); |
|
3711 if (old_method->is_obsolete()) { |
3799 // only obsolete methods are interesting |
3712 // only obsolete methods are interesting |
3800 Method* old_method = old_methods->at(i); |
|
3801 Symbol* m_name = old_method->name(); |
3713 Symbol* m_name = old_method->name(); |
3802 Symbol* m_signature = old_method->signature(); |
3714 Symbol* m_signature = old_method->signature(); |
3803 |
3715 |
3804 // we might not have added the last entry |
3716 // previous versions are linked together through the InstanceKlass |
3805 for (int j = _previous_versions->length() - 1; j >= 0; j--) { |
3717 int j = 0; |
3806 // check the previous versions array for non executing obsolete methods |
3718 for (InstanceKlass* prev_version = _previous_versions; |
3807 PreviousVersionNode * pv_node = _previous_versions->at(j); |
3719 prev_version != NULL; |
3808 |
3720 prev_version = prev_version->previous_versions(), j++) { |
3809 GrowableArray<Method*>* method_refs = pv_node->prev_EMCP_methods(); |
3721 |
3810 if (method_refs == NULL) { |
3722 Array<Method*>* method_refs = prev_version->methods(); |
3811 // We have run into a PreviousVersion generation where |
3723 for (int k = 0; k < method_refs->length(); k++) { |
3812 // all methods were made obsolete during that generation's |
|
3813 // RedefineClasses() operation. At the time of that |
|
3814 // operation, all EMCP methods were flushed so we don't |
|
3815 // have to go back any further. |
|
3816 // |
|
3817 // A NULL method_refs is different than an empty method_refs. |
|
3818 // We cannot infer any optimizations about older generations |
|
3819 // from an empty method_refs for the current generation. |
|
3820 break; |
|
3821 } |
|
3822 |
|
3823 for (int k = method_refs->length() - 1; k >= 0; k--) { |
|
3824 Method* method = method_refs->at(k); |
3724 Method* method = method_refs->at(k); |
3825 |
3725 |
3826 if (!method->is_obsolete() && |
3726 if (!method->is_obsolete() && |
3827 method->name() == m_name && |
3727 method->name() == m_name && |
3828 method->signature() == m_signature) { |
3728 method->signature() == m_signature) { |
3829 // The current RedefineClasses() call has made all EMCP |
3729 // The current RedefineClasses() call has made all EMCP |
3830 // versions of this method obsolete so mark it as obsolete |
3730 // versions of this method obsolete so mark it as obsolete |
3831 // and remove the reference. |
|
3832 RC_TRACE(0x00000400, |
3731 RC_TRACE(0x00000400, |
3833 ("add: %s(%s): flush obsolete method @%d in version @%d", |
3732 ("add: %s(%s): flush obsolete method @%d in version @%d", |
3834 m_name->as_C_string(), m_signature->as_C_string(), k, j)); |
3733 m_name->as_C_string(), m_signature->as_C_string(), k, j)); |
3835 |
3734 |
3836 method->set_is_obsolete(); |
3735 method->set_is_obsolete(); |
3837 // Leave obsolete methods on the previous version list to |
|
3838 // clean up later. |
|
3839 break; |
3736 break; |
3840 } |
3737 } |
3841 } |
3738 } |
3842 |
3739 |
3843 // The previous loop may not find a matching EMCP method, but |
3740 // The previous loop may not find a matching EMCP method, but |
3844 // that doesn't mean that we can optimize and not go any |
3741 // that doesn't mean that we can optimize and not go any |
3845 // further back in the PreviousVersion generations. The EMCP |
3742 // further back in the PreviousVersion generations. The EMCP |
3846 // method for this generation could have already been deleted, |
3743 // method for this generation could have already been made obsolete, |
3847 // but there still may be an older EMCP method that has not |
3744 // but there still may be an older EMCP method that has not |
3848 // been deleted. |
3745 // been made obsolete. |
3849 } |
3746 } |
3850 |
3747 |
3851 if (++local_count >= obsolete_method_count) { |
3748 if (++local_count >= obsolete_method_count) { |
3852 // no more obsolete methods so bail out now |
3749 // no more obsolete methods so bail out now |
3853 break; |
3750 break; |
3854 } |
3751 } |
3855 } |
3752 } |
3856 } |
3753 } |
3857 } |
3754 } |
|
3755 } |
|
3756 |
|
3757 // Save the scratch_class as the previous version if any of the methods are running. |
|
3758 // The previous_versions are used to set breakpoints in EMCP methods and they are |
|
3759 // also used to clean MethodData links to redefined methods that are no longer running. |
|
3760 void InstanceKlass::add_previous_version(instanceKlassHandle scratch_class, |
|
3761 int emcp_method_count) { |
|
3762 assert(Thread::current()->is_VM_thread(), |
|
3763 "only VMThread can add previous versions"); |
|
3764 |
|
3765 // RC_TRACE macro has an embedded ResourceMark |
|
3766 RC_TRACE(0x00000400, ("adding previous version ref for %s, EMCP_cnt=%d", |
|
3767 scratch_class->external_name(), emcp_method_count)); |
|
3768 |
|
3769 // Clean out old previous versions |
|
3770 purge_previous_versions(this); |
|
3771 |
|
3772 // Mark newly obsolete methods in remaining previous versions. An EMCP method from |
|
3773 // a previous redefinition may be made obsolete by this redefinition. |
|
3774 Array<Method*>* old_methods = scratch_class->methods(); |
|
3775 mark_newly_obsolete_methods(old_methods, emcp_method_count); |
|
3776 |
|
3777 // If the constant pool for this previous version of the class |
|
3778 // is not marked as being on the stack, then none of the methods |
|
3779 // in this previous version of the class are on the stack so |
|
3780 // we don't need to add this as a previous version. |
|
3781 ConstantPool* cp_ref = scratch_class->constants(); |
|
3782 if (!cp_ref->on_stack()) { |
|
3783 RC_TRACE(0x00000400, ("add: scratch class not added; no methods are running")); |
|
3784 return; |
|
3785 } |
|
3786 |
|
3787 if (emcp_method_count != 0) { |
|
3788 // At least one method is still running, check for EMCP methods |
|
3789 for (int i = 0; i < old_methods->length(); i++) { |
|
3790 Method* old_method = old_methods->at(i); |
|
3791 if (!old_method->is_obsolete() && old_method->on_stack()) { |
|
3792 // if EMCP method (not obsolete) is on the stack, mark as EMCP so that |
|
3793 // we can add breakpoints for it. |
|
3794 |
|
3795 // We set the method->on_stack bit during safepoints for class redefinition and |
|
3796 // class unloading and use this bit to set the is_running_emcp bit. |
|
3797 // After the safepoint, the on_stack bit is cleared and the running emcp |
|
3798 // method may exit. If so, we would set a breakpoint in a method that |
|
3799 // is never reached, but this won't be noticeable to the programmer. |
|
3800 old_method->set_running_emcp(true); |
|
3801 RC_TRACE(0x00000400, ("add: EMCP method %s is on_stack " INTPTR_FORMAT, |
|
3802 old_method->name_and_sig_as_C_string(), old_method)); |
|
3803 } else if (!old_method->is_obsolete()) { |
|
3804 RC_TRACE(0x00000400, ("add: EMCP method %s is NOT on_stack " INTPTR_FORMAT, |
|
3805 old_method->name_and_sig_as_C_string(), old_method)); |
|
3806 } |
|
3807 } |
|
3808 } |
|
3809 |
|
3810 // Add previous version if any methods are still running. |
|
3811 RC_TRACE(0x00000400, ("add: scratch class added; one of its methods is on_stack")); |
|
3812 assert(scratch_class->previous_versions() == NULL, "shouldn't have a previous version"); |
|
3813 scratch_class->link_previous_versions(previous_versions()); |
|
3814 link_previous_versions(scratch_class()); |
3858 } // end add_previous_version() |
3815 } // end add_previous_version() |
3859 |
|
3860 |
|
3861 // Determine if InstanceKlass has a previous version. |
|
3862 bool InstanceKlass::has_previous_version() const { |
|
3863 return (_previous_versions != NULL && _previous_versions->length() > 0); |
|
3864 } // end has_previous_version() |
|
3865 |
|
3866 |
|
3867 InstanceKlass* InstanceKlass::get_klass_version(int version) { |
|
3868 if (constants()->version() == version) { |
|
3869 return this; |
|
3870 } |
|
3871 PreviousVersionWalker pvw(Thread::current(), (InstanceKlass*)this); |
|
3872 for (PreviousVersionNode * pv_node = pvw.next_previous_version(); |
|
3873 pv_node != NULL; pv_node = pvw.next_previous_version()) { |
|
3874 ConstantPool* prev_cp = pv_node->prev_constant_pool(); |
|
3875 if (prev_cp->version() == version) { |
|
3876 return prev_cp->pool_holder(); |
|
3877 } |
|
3878 } |
|
3879 return NULL; // None found |
|
3880 } |
|
3881 |
|
3882 |
3816 |
3883 Method* InstanceKlass::method_with_idnum(int idnum) { |
3817 Method* InstanceKlass::method_with_idnum(int idnum) { |
3884 Method* m = NULL; |
3818 Method* m = NULL; |
3885 if (idnum < methods()->length()) { |
3819 if (idnum < methods()->length()) { |
3886 m = methods()->at(idnum); |
3820 m = methods()->at(idnum); |