287 set_array_name(NULL); |
287 set_array_name(NULL); |
288 set_inner_classes(NULL); |
288 set_inner_classes(NULL); |
289 set_static_oop_field_count(0); |
289 set_static_oop_field_count(0); |
290 set_nonstatic_field_size(0); |
290 set_nonstatic_field_size(0); |
291 set_is_marked_dependent(false); |
291 set_is_marked_dependent(false); |
|
292 set_has_unloaded_dependent(false); |
292 set_init_state(InstanceKlass::allocated); |
293 set_init_state(InstanceKlass::allocated); |
293 set_init_thread(NULL); |
294 set_init_thread(NULL); |
294 set_reference_type(rt); |
295 set_reference_type(rt); |
295 set_oop_map_cache(NULL); |
296 set_oop_map_cache(NULL); |
296 set_jni_ids(NULL); |
297 set_jni_ids(NULL); |
1817 id = jmeths[idnum+1]; // Look up the id (may be NULL) |
1818 id = jmeths[idnum+1]; // Look up the id (may be NULL) |
1818 } |
1819 } |
1819 return id; |
1820 return id; |
1820 } |
1821 } |
1821 |
1822 |
|
1823 int nmethodBucket::decrement() { |
|
1824 return Atomic::add(-1, (volatile int *)&_count); |
|
1825 } |
1822 |
1826 |
1823 // |
1827 // |
1824 // Walk the list of dependent nmethods searching for nmethods which |
1828 // Walk the list of dependent nmethods searching for nmethods which |
1825 // are dependent on the changes that were passed in and mark them for |
1829 // are dependent on the changes that were passed in and mark them for |
1826 // deoptimization. Returns the number of nmethods found. |
1830 // deoptimization. Returns the number of nmethods found. |
1831 nmethodBucket* b = _dependencies; |
1835 nmethodBucket* b = _dependencies; |
1832 while (b != NULL) { |
1836 while (b != NULL) { |
1833 nmethod* nm = b->get_nmethod(); |
1837 nmethod* nm = b->get_nmethod(); |
1834 // since dependencies aren't removed until an nmethod becomes a zombie, |
1838 // since dependencies aren't removed until an nmethod becomes a zombie, |
1835 // the dependency list may contain nmethods which aren't alive. |
1839 // the dependency list may contain nmethods which aren't alive. |
1836 if (nm->is_alive() && !nm->is_marked_for_deoptimization() && nm->check_dependency_on(changes)) { |
1840 if (b->count() > 0 && nm->is_alive() && !nm->is_marked_for_deoptimization() && nm->check_dependency_on(changes)) { |
1837 if (TraceDependencies) { |
1841 if (TraceDependencies) { |
1838 ResourceMark rm; |
1842 ResourceMark rm; |
1839 tty->print_cr("Marked for deoptimization"); |
1843 tty->print_cr("Marked for deoptimization"); |
1840 tty->print_cr(" context = %s", this->external_name()); |
1844 tty->print_cr(" context = %s", this->external_name()); |
1841 changes.print(); |
1845 changes.print(); |
1848 b = b->next(); |
1852 b = b->next(); |
1849 } |
1853 } |
1850 return found; |
1854 return found; |
1851 } |
1855 } |
1852 |
1856 |
|
1857 void InstanceKlass::clean_dependent_nmethods() { |
|
1858 assert_locked_or_safepoint(CodeCache_lock); |
|
1859 |
|
1860 if (has_unloaded_dependent()) { |
|
1861 nmethodBucket* b = _dependencies; |
|
1862 nmethodBucket* last = NULL; |
|
1863 while (b != NULL) { |
|
1864 assert(b->count() >= 0, err_msg("bucket count: %d", b->count())); |
|
1865 |
|
1866 nmethodBucket* next = b->next(); |
|
1867 |
|
1868 if (b->count() == 0) { |
|
1869 if (last == NULL) { |
|
1870 _dependencies = next; |
|
1871 } else { |
|
1872 last->set_next(next); |
|
1873 } |
|
1874 delete b; |
|
1875 // last stays the same. |
|
1876 } else { |
|
1877 last = b; |
|
1878 } |
|
1879 |
|
1880 b = next; |
|
1881 } |
|
1882 set_has_unloaded_dependent(false); |
|
1883 } |
|
1884 #ifdef ASSERT |
|
1885 else { |
|
1886 // Verification |
|
1887 for (nmethodBucket* b = _dependencies; b != NULL; b = b->next()) { |
|
1888 assert(b->count() >= 0, err_msg("bucket count: %d", b->count())); |
|
1889 assert(b->count() != 0, "empty buckets need to be cleaned"); |
|
1890 } |
|
1891 } |
|
1892 #endif |
|
1893 } |
1853 |
1894 |
1854 // |
1895 // |
1855 // Add an nmethodBucket to the list of dependencies for this nmethod. |
1896 // Add an nmethodBucket to the list of dependencies for this nmethod. |
1856 // It's possible that an nmethod has multiple dependencies on this klass |
1897 // It's possible that an nmethod has multiple dependencies on this klass |
1857 // so a count is kept for each bucket to guarantee that creation and |
1898 // so a count is kept for each bucket to guarantee that creation and |
1882 assert_locked_or_safepoint(CodeCache_lock); |
1923 assert_locked_or_safepoint(CodeCache_lock); |
1883 nmethodBucket* b = _dependencies; |
1924 nmethodBucket* b = _dependencies; |
1884 nmethodBucket* last = NULL; |
1925 nmethodBucket* last = NULL; |
1885 while (b != NULL) { |
1926 while (b != NULL) { |
1886 if (nm == b->get_nmethod()) { |
1927 if (nm == b->get_nmethod()) { |
1887 if (b->decrement() == 0) { |
1928 int val = b->decrement(); |
1888 if (last == NULL) { |
1929 guarantee(val >= 0, err_msg("Underflow: %d", val)); |
1889 _dependencies = b->next(); |
1930 if (val == 0) { |
1890 } else { |
1931 set_has_unloaded_dependent(true); |
1891 last->set_next(b->next()); |
|
1892 } |
|
1893 delete b; |
|
1894 } |
1932 } |
1895 return; |
1933 return; |
1896 } |
1934 } |
1897 last = b; |
1935 last = b; |
1898 b = b->next(); |
1936 b = b->next(); |
1927 |
1965 |
1928 bool InstanceKlass::is_dependent_nmethod(nmethod* nm) { |
1966 bool InstanceKlass::is_dependent_nmethod(nmethod* nm) { |
1929 nmethodBucket* b = _dependencies; |
1967 nmethodBucket* b = _dependencies; |
1930 while (b != NULL) { |
1968 while (b != NULL) { |
1931 if (nm == b->get_nmethod()) { |
1969 if (nm == b->get_nmethod()) { |
|
1970 #ifdef ASSERT |
|
1971 int count = b->count(); |
|
1972 assert(count >= 0, "Just check if we ever get here 1"); |
|
1973 assert(count > 0, "Just check if we ever get here 2"); |
|
1974 #endif |
1932 return true; |
1975 return true; |
1933 } |
1976 } |
1934 b = b->next(); |
1977 b = b->next(); |
1935 } |
1978 } |
1936 return false; |
1979 return false; |
2225 } |
2268 } |
2226 |
2269 |
2227 #endif // INCLUDE_ALL_GCS |
2270 #endif // INCLUDE_ALL_GCS |
2228 |
2271 |
2229 void InstanceKlass::clean_implementors_list(BoolObjectClosure* is_alive) { |
2272 void InstanceKlass::clean_implementors_list(BoolObjectClosure* is_alive) { |
2230 assert(is_loader_alive(is_alive), "this klass should be live"); |
2273 assert(class_loader_data()->is_alive(is_alive), "this klass should be live"); |
2231 if (is_interface()) { |
2274 if (is_interface()) { |
2232 if (ClassUnloading) { |
2275 if (ClassUnloading) { |
2233 Klass* impl = implementor(); |
2276 Klass* impl = implementor(); |
2234 if (impl != NULL) { |
2277 if (impl != NULL) { |
2235 if (!impl->is_loader_alive(is_alive)) { |
2278 if (!impl->is_loader_alive(is_alive)) { |