1890 // Add an nmethodBucket to the list of dependencies for this nmethod. 1891 // It's possible that an nmethod has multiple dependencies on this klass 1892 // so a count is kept for each bucket to guarantee that creation and 1893 // deletion of dependencies is consistent. Returns new head of the list. 1894 // 1895 nmethodBucket* nmethodBucket::add_dependent_nmethod(nmethodBucket* deps, nmethod* nm) { 1896 assert_locked_or_safepoint(CodeCache_lock); 1897 for (nmethodBucket* b = deps; b != NULL; b = b->next()) { 1898 if (nm == b->get_nmethod()) { 1899 b->increment(); 1900 return deps; 1901 } 1902 } 1903 return new nmethodBucket(nm, deps); 1904 } 1905 1906 // 1907 // Decrement count of the nmethod in the dependency list and remove 1908 // the bucket completely when the count goes to 0. This method must 1909 // find a corresponding bucket otherwise there's a bug in the 1910 // recording of dependencies. Returns true if the bucket is ready for reclamation. 1911 // 1912 bool nmethodBucket::remove_dependent_nmethod(nmethodBucket* deps, nmethod* nm) { 1913 assert_locked_or_safepoint(CodeCache_lock); 1914 1915 for (nmethodBucket* b = deps; b != NULL; b = b->next()) { 1916 if (nm == b->get_nmethod()) { 1917 int val = b->decrement(); 1918 guarantee(val >= 0, "Underflow: %d", val); 1919 return (val == 0); 1920 } 1921 } 1922 #ifdef ASSERT 1923 tty->print_raw_cr("### can't find dependent nmethod"); 1924 nm->print(); 1925 #endif // ASSERT 1926 ShouldNotReachHere(); 1927 return false; 1928 } 1929 1930 // 1931 // Reclaim all unused buckets. Returns new head of the list. 1932 // 1933 nmethodBucket* nmethodBucket::clean_dependent_nmethods(nmethodBucket* deps) { 1934 nmethodBucket* first = deps; 1935 nmethodBucket* last = NULL; 1936 nmethodBucket* b = first; 1937 1938 while (b != NULL) { 1939 assert(b->count() >= 0, "bucket count: %d", b->count()); 1940 nmethodBucket* next = b->next(); 1941 if (b->count() == 0) { 1942 if (last == NULL) { 1943 first = next; 1944 } else { 1945 last->set_next(next); 1946 } 1947 delete b; 1948 // last stays the same. 1949 } else { 1996 if (has_unloaded_dependent()) { 1997 _dependencies = nmethodBucket::clean_dependent_nmethods(_dependencies); 1998 set_has_unloaded_dependent(false); 1999 } 2000 #ifdef ASSERT 2001 else { 2002 // Verification 2003 for (nmethodBucket* b = _dependencies; b != NULL; b = b->next()) { 2004 assert(b->count() >= 0, "bucket count: %d", b->count()); 2005 assert(b->count() != 0, "empty buckets need to be cleaned"); 2006 } 2007 } 2008 #endif 2009 } 2010 2011 void InstanceKlass::add_dependent_nmethod(nmethod* nm) { 2012 assert_locked_or_safepoint(CodeCache_lock); 2013 _dependencies = nmethodBucket::add_dependent_nmethod(_dependencies, nm); 2014 } 2015 2016 void InstanceKlass::remove_dependent_nmethod(nmethod* nm) { 2017 assert_locked_or_safepoint(CodeCache_lock); 2018 2019 if (nmethodBucket::remove_dependent_nmethod(_dependencies, nm)) { 2020 set_has_unloaded_dependent(true); 2021 } 2022 } 2023 2024 #ifndef PRODUCT 2025 void InstanceKlass::print_dependent_nmethods(bool verbose) { 2026 nmethodBucket::print_dependent_nmethods(_dependencies, verbose); 2027 } 2028 2029 bool InstanceKlass::is_dependent_nmethod(nmethod* nm) { 2030 return nmethodBucket::is_dependent_nmethod(_dependencies, nm); 2031 } 2032 #endif //PRODUCT 2033 2034 void InstanceKlass::clean_implementors_list(BoolObjectClosure* is_alive) { 2035 assert(class_loader_data()->is_alive(is_alive), "this klass should be live"); 2036 if (is_interface()) { 2037 if (ClassUnloading) { 2038 Klass* impl = implementor(); 2039 if (impl != NULL) { 2040 if (!impl->is_loader_alive(is_alive)) { 2041 // remove this guy 2042 Klass** klass = adr_implementor(); 2043 assert(klass != NULL, "null klass"); 2044 if (klass != NULL) { 2045 *klass = NULL; 2046 } 2047 } 2048 } 2049 } 2050 } 2051 } 2052 2053 void InstanceKlass::clean_method_data(BoolObjectClosure* is_alive) { 3529 } 3530 3531 3532 Method* InstanceKlass::method_with_orig_idnum(int idnum, int version) { 3533 InstanceKlass* holder = get_klass_version(version); 3534 if (holder == NULL) { 3535 return NULL; // The version of klass is gone, no method is found 3536 } 3537 Method* method = holder->method_with_orig_idnum(idnum); 3538 return method; 3539 } 3540 3541 3542 jint InstanceKlass::get_cached_class_file_len() { 3543 return VM_RedefineClasses::get_cached_class_file_len(_cached_class_file); 3544 } 3545 3546 unsigned char * InstanceKlass::get_cached_class_file_bytes() { 3547 return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file); 3548 } | 1890 // Add an nmethodBucket to the list of dependencies for this nmethod. 1891 // It's possible that an nmethod has multiple dependencies on this klass 1892 // so a count is kept for each bucket to guarantee that creation and 1893 // deletion of dependencies is consistent. Returns new head of the list. 1894 // 1895 nmethodBucket* nmethodBucket::add_dependent_nmethod(nmethodBucket* deps, nmethod* nm) { 1896 assert_locked_or_safepoint(CodeCache_lock); 1897 for (nmethodBucket* b = deps; b != NULL; b = b->next()) { 1898 if (nm == b->get_nmethod()) { 1899 b->increment(); 1900 return deps; 1901 } 1902 } 1903 return new nmethodBucket(nm, deps); 1904 } 1905 1906 // 1907 // Decrement count of the nmethod in the dependency list and remove 1908 // the bucket completely when the count goes to 0. This method must 1909 // find a corresponding bucket otherwise there's a bug in the 1910 // recording of dependencies. Returns true if the bucket was deleted, 1911 // or marked ready for reclaimation. 1912 bool nmethodBucket::remove_dependent_nmethod(nmethodBucket** deps, nmethod* nm, bool delete_immediately) { 1913 assert_locked_or_safepoint(CodeCache_lock); 1914 1915 nmethodBucket* first = *deps; 1916 nmethodBucket* last = NULL; 1917 1918 for (nmethodBucket* b = first; b != NULL; b = b->next()) { 1919 if (nm == b->get_nmethod()) { 1920 int val = b->decrement(); 1921 guarantee(val >= 0, "Underflow: %d", val); 1922 if (val == 0) { 1923 if (delete_immediately) { 1924 if (last == NULL) { 1925 *deps = b->next(); 1926 } else { 1927 last->set_next(b->next()); 1928 } 1929 delete b; 1930 } 1931 } 1932 return true; 1933 } 1934 last = b; 1935 } 1936 1937 #ifdef ASSERT 1938 tty->print_raw_cr("### can't find dependent nmethod"); 1939 nm->print(); 1940 #endif // ASSERT 1941 ShouldNotReachHere(); 1942 return false; 1943 } 1944 1945 // Convenience overload, for callers that don't want to delete the nmethodBucket entry. 1946 bool nmethodBucket::remove_dependent_nmethod(nmethodBucket* deps, nmethod* nm) { 1947 nmethodBucket** deps_addr = &deps; 1948 return remove_dependent_nmethod(deps_addr, nm, false /* Don't delete */); 1949 } 1950 1951 // 1952 // Reclaim all unused buckets. Returns new head of the list. 1953 // 1954 nmethodBucket* nmethodBucket::clean_dependent_nmethods(nmethodBucket* deps) { 1955 nmethodBucket* first = deps; 1956 nmethodBucket* last = NULL; 1957 nmethodBucket* b = first; 1958 1959 while (b != NULL) { 1960 assert(b->count() >= 0, "bucket count: %d", b->count()); 1961 nmethodBucket* next = b->next(); 1962 if (b->count() == 0) { 1963 if (last == NULL) { 1964 first = next; 1965 } else { 1966 last->set_next(next); 1967 } 1968 delete b; 1969 // last stays the same. 1970 } else { 2017 if (has_unloaded_dependent()) { 2018 _dependencies = nmethodBucket::clean_dependent_nmethods(_dependencies); 2019 set_has_unloaded_dependent(false); 2020 } 2021 #ifdef ASSERT 2022 else { 2023 // Verification 2024 for (nmethodBucket* b = _dependencies; b != NULL; b = b->next()) { 2025 assert(b->count() >= 0, "bucket count: %d", b->count()); 2026 assert(b->count() != 0, "empty buckets need to be cleaned"); 2027 } 2028 } 2029 #endif 2030 } 2031 2032 void InstanceKlass::add_dependent_nmethod(nmethod* nm) { 2033 assert_locked_or_safepoint(CodeCache_lock); 2034 _dependencies = nmethodBucket::add_dependent_nmethod(_dependencies, nm); 2035 } 2036 2037 void InstanceKlass::remove_dependent_nmethod(nmethod* nm, bool delete_immediately) { 2038 assert_locked_or_safepoint(CodeCache_lock); 2039 2040 if (nmethodBucket::remove_dependent_nmethod(&_dependencies, nm, delete_immediately)) { 2041 set_has_unloaded_dependent(true); 2042 } 2043 } 2044 2045 #ifndef PRODUCT 2046 void InstanceKlass::print_dependent_nmethods(bool verbose) { 2047 nmethodBucket::print_dependent_nmethods(_dependencies, verbose); 2048 } 2049 2050 bool InstanceKlass::is_dependent_nmethod(nmethod* nm) { 2051 return nmethodBucket::is_dependent_nmethod(_dependencies, nm); 2052 } 2053 #endif //PRODUCT 2054 2055 void InstanceKlass::clean_weak_instanceklass_links(BoolObjectClosure* is_alive) { 2056 clean_implementors_list(is_alive); 2057 clean_method_data(is_alive); 2058 2059 clean_dependent_nmethods(); 2060 } 2061 2062 void InstanceKlass::clean_implementors_list(BoolObjectClosure* is_alive) { 2063 assert(class_loader_data()->is_alive(is_alive), "this klass should be live"); 2064 if (is_interface()) { 2065 if (ClassUnloading) { 2066 Klass* impl = implementor(); 2067 if (impl != NULL) { 2068 if (!impl->is_loader_alive(is_alive)) { 2069 // remove this guy 2070 Klass** klass = adr_implementor(); 2071 assert(klass != NULL, "null klass"); 2072 if (klass != NULL) { 2073 *klass = NULL; 2074 } 2075 } 2076 } 2077 } 2078 } 2079 } 2080 2081 void InstanceKlass::clean_method_data(BoolObjectClosure* is_alive) { 3557 } 3558 3559 3560 Method* InstanceKlass::method_with_orig_idnum(int idnum, int version) { 3561 InstanceKlass* holder = get_klass_version(version); 3562 if (holder == NULL) { 3563 return NULL; // The version of klass is gone, no method is found 3564 } 3565 Method* method = holder->method_with_orig_idnum(idnum); 3566 return method; 3567 } 3568 3569 3570 jint InstanceKlass::get_cached_class_file_len() { 3571 return VM_RedefineClasses::get_cached_class_file_len(_cached_class_file); 3572 } 3573 3574 unsigned char * InstanceKlass::get_cached_class_file_bytes() { 3575 return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file); 3576 } 3577 3578 3579 /////////////// Unit tests /////////////// 3580 3581 #ifndef PRODUCT 3582 3583 class TestNmethodBucketContext { 3584 public: 3585 nmethod* _nmethodLast; 3586 nmethod* _nmethodMiddle; 3587 nmethod* _nmethodFirst; 3588 3589 nmethodBucket* _bucketLast; 3590 nmethodBucket* _bucketMiddle; 3591 nmethodBucket* _bucketFirst; 3592 3593 nmethodBucket* _bucketList; 3594 3595 TestNmethodBucketContext() { 3596 CodeCache_lock->lock_without_safepoint_check(); 3597 3598 _nmethodLast = reinterpret_cast<nmethod*>(0x8 * 0); 3599 _nmethodMiddle = reinterpret_cast<nmethod*>(0x8 * 1); 3600 _nmethodFirst = reinterpret_cast<nmethod*>(0x8 * 2); 3601 3602 _bucketLast = new nmethodBucket(_nmethodLast, NULL); 3603 _bucketMiddle = new nmethodBucket(_nmethodMiddle, _bucketLast); 3604 _bucketFirst = new nmethodBucket(_nmethodFirst, _bucketMiddle); 3605 3606 _bucketList = _bucketFirst; 3607 } 3608 3609 ~TestNmethodBucketContext() { 3610 delete _bucketLast; 3611 delete _bucketMiddle; 3612 delete _bucketFirst; 3613 3614 CodeCache_lock->unlock(); 3615 } 3616 }; 3617 3618 class TestNmethodBucket { 3619 public: 3620 static void testRemoveDependentNmethodFirstDeleteImmediately() { 3621 TestNmethodBucketContext c; 3622 3623 nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodFirst, true /* delete */); 3624 3625 assert(c._bucketList == c._bucketMiddle, "check"); 3626 assert(c._bucketList->next() == c._bucketLast, "check"); 3627 assert(c._bucketList->next()->next() == NULL, "check"); 3628 3629 // Cleanup before context is deleted. 3630 c._bucketFirst = NULL; 3631 } 3632 3633 static void testRemoveDependentNmethodMiddleDeleteImmediately() { 3634 TestNmethodBucketContext c; 3635 3636 nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodMiddle, true /* delete */); 3637 3638 assert(c._bucketList == c._bucketFirst, "check"); 3639 assert(c._bucketList->next() == c._bucketLast, "check"); 3640 assert(c._bucketList->next()->next() == NULL, "check"); 3641 3642 // Cleanup before context is deleted. 3643 c._bucketMiddle = NULL; 3644 } 3645 3646 static void testRemoveDependentNmethodLastDeleteImmediately() { 3647 TestNmethodBucketContext c; 3648 3649 nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodLast, true /* delete */); 3650 3651 assert(c._bucketList == c._bucketFirst, "check"); 3652 assert(c._bucketList->next() == c._bucketMiddle, "check"); 3653 assert(c._bucketList->next()->next() == NULL, "check"); 3654 3655 // Cleanup before context is deleted. 3656 c._bucketLast = NULL; 3657 } 3658 3659 static void testRemoveDependentNmethodFirstDeleteDeferred() { 3660 TestNmethodBucketContext c; 3661 3662 nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodFirst, false /* delete */); 3663 3664 assert(c._bucketList == c._bucketFirst, "check"); 3665 assert(c._bucketList->next() == c._bucketMiddle, "check"); 3666 assert(c._bucketList->next()->next() == c._bucketLast, "check"); 3667 assert(c._bucketList->next()->next()->next() == NULL, "check"); 3668 3669 assert(c._bucketFirst->count() == 0, "check"); 3670 assert(c._bucketMiddle->count() == 1, "check"); 3671 assert(c._bucketLast->count() == 1, "check"); 3672 } 3673 3674 static void testRemoveDependentNmethodMiddleDeleteDeferred() { 3675 TestNmethodBucketContext c; 3676 3677 nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodMiddle, false /* delete */); 3678 3679 assert(c._bucketList == c._bucketFirst, "check"); 3680 assert(c._bucketList->next() == c._bucketMiddle, "check"); 3681 assert(c._bucketList->next()->next() == c._bucketLast, "check"); 3682 assert(c._bucketList->next()->next()->next() == NULL, "check"); 3683 3684 assert(c._bucketFirst->count() == 1, "check"); 3685 assert(c._bucketMiddle->count() == 0, "check"); 3686 assert(c._bucketLast->count() == 1, "check"); 3687 } 3688 3689 static void testRemoveDependentNmethodLastDeleteDeferred() { 3690 TestNmethodBucketContext c; 3691 3692 nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodLast, false /* delete */); 3693 3694 assert(c._bucketList == c._bucketFirst, "check"); 3695 assert(c._bucketList->next() == c._bucketMiddle, "check"); 3696 assert(c._bucketList->next()->next() == c._bucketLast, "check"); 3697 assert(c._bucketList->next()->next()->next() == NULL, "check"); 3698 3699 assert(c._bucketFirst->count() == 1, "check"); 3700 assert(c._bucketMiddle->count() == 1, "check"); 3701 assert(c._bucketLast->count() == 0, "check"); 3702 } 3703 3704 static void testRemoveDependentNmethodConvenienceFirst() { 3705 TestNmethodBucketContext c; 3706 3707 nmethodBucket::remove_dependent_nmethod(c._bucketList, c._nmethodFirst); 3708 3709 assert(c._bucketList == c._bucketFirst, "check"); 3710 assert(c._bucketList->next() == c._bucketMiddle, "check"); 3711 assert(c._bucketList->next()->next() == c._bucketLast, "check"); 3712 assert(c._bucketList->next()->next()->next() == NULL, "check"); 3713 3714 assert(c._bucketFirst->count() == 0, "check"); 3715 assert(c._bucketMiddle->count() == 1, "check"); 3716 assert(c._bucketLast->count() == 1, "check"); 3717 } 3718 3719 static void testRemoveDependentNmethodConvenienceMiddle() { 3720 TestNmethodBucketContext c; 3721 3722 nmethodBucket::remove_dependent_nmethod(c._bucketList, c._nmethodMiddle); 3723 3724 assert(c._bucketList == c._bucketFirst, "check"); 3725 assert(c._bucketList->next() == c._bucketMiddle, "check"); 3726 assert(c._bucketList->next()->next() == c._bucketLast, "check"); 3727 assert(c._bucketList->next()->next()->next() == NULL, "check"); 3728 3729 assert(c._bucketFirst->count() == 1, "check"); 3730 assert(c._bucketMiddle->count() == 0, "check"); 3731 assert(c._bucketLast->count() == 1, "check"); 3732 } 3733 3734 static void testRemoveDependentNmethodConvenienceLast() { 3735 TestNmethodBucketContext c; 3736 3737 nmethodBucket::remove_dependent_nmethod(c._bucketList, c._nmethodLast); 3738 3739 assert(c._bucketList == c._bucketFirst, "check"); 3740 assert(c._bucketList->next() == c._bucketMiddle, "check"); 3741 assert(c._bucketList->next()->next() == c._bucketLast, "check"); 3742 assert(c._bucketList->next()->next()->next() == NULL, "check"); 3743 3744 assert(c._bucketFirst->count() == 1, "check"); 3745 assert(c._bucketMiddle->count() == 1, "check"); 3746 assert(c._bucketLast->count() == 0, "check"); 3747 } 3748 3749 static void testRemoveDependentNmethod() { 3750 testRemoveDependentNmethodFirstDeleteImmediately(); 3751 testRemoveDependentNmethodMiddleDeleteImmediately(); 3752 testRemoveDependentNmethodLastDeleteImmediately(); 3753 3754 testRemoveDependentNmethodFirstDeleteDeferred(); 3755 testRemoveDependentNmethodMiddleDeleteDeferred(); 3756 testRemoveDependentNmethodLastDeleteDeferred(); 3757 3758 testRemoveDependentNmethodConvenienceFirst(); 3759 testRemoveDependentNmethodConvenienceMiddle(); 3760 testRemoveDependentNmethodConvenienceLast(); 3761 } 3762 3763 static void test() { 3764 testRemoveDependentNmethod(); 3765 } 3766 }; 3767 3768 void TestNmethodBucket_test() { 3769 TestNmethodBucket::test(); 3770 } 3771 3772 #endif |