< prev index next >

src/hotspot/share/code/nmethod.cpp

Print this page




1133   if (m == NULL)  return;
1134   MethodData* mdo = m->method_data();
1135   if (mdo == NULL)  return;
1136   // There is a benign race here.  See comments in methodData.hpp.
1137   mdo->inc_decompile_count();
1138 }
1139 
1140 bool nmethod::try_transition(int new_state_int) {
1141   signed char new_state = new_state_int;
1142 #ifdef DEBUG
1143   if (new_state != unloaded) {
1144     assert_lock_strong(CompiledMethod_lock);
1145   }
1146 #endif
1147   for (;;) {
1148     signed char old_state = Atomic::load(&_state);
1149     if (old_state >= new_state) {
1150       // Ensure monotonicity of transitions.
1151       return false;
1152     }
1153     if (Atomic::cmpxchg(new_state, &_state, old_state) == old_state) {
1154       return true;
1155     }
1156   }
1157 }
1158 
1159 void nmethod::make_unloaded() {
1160   post_compiled_method_unload();
1161 
1162   // This nmethod is being unloaded, make sure that dependencies
1163   // recorded in instanceKlasses get flushed.
1164   // Since this work is being done during a GC, defer deleting dependencies from the
1165   // InstanceKlass.
1166   assert(Universe::heap()->is_gc_active() || Thread::current()->is_ConcurrentGC_thread(),
1167          "should only be called during gc");
1168   flush_dependencies(/*delete_immediately*/false);
1169 
1170   // Break cycle between nmethod & method
1171   LogTarget(Trace, class, unload, nmethod) lt;
1172   if (lt.is_enabled()) {
1173     LogStream ls(lt);


1832   LogTarget(Trace, gc, nmethod) lt;
1833   if (lt.is_enabled()) {
1834     LogStream ls(lt);
1835     CompileTask::print(&ls, this, state, true /* short_form */);
1836   }
1837 }
1838 
1839 bool nmethod::oops_do_try_claim() {
1840   if (oops_do_try_claim_weak_request()) {
1841     nmethod* result = oops_do_try_add_to_list_as_weak_done();
1842     assert(result == NULL, "adding to global list as weak done must always succeed.");
1843     return true;
1844   }
1845   return false;
1846 }
1847 
1848 bool nmethod::oops_do_try_claim_weak_request() {
1849   assert(SafepointSynchronize::is_at_safepoint(), "only at safepoint");
1850 
1851   if ((_oops_do_mark_link == NULL) &&
1852       (Atomic::replace_if_null(mark_link(this, claim_weak_request_tag), &_oops_do_mark_link))) {
1853     oops_do_log_change("oops_do, mark weak request");
1854     return true;
1855   }
1856   return false;
1857 }
1858 
1859 void nmethod::oops_do_set_strong_done(nmethod* old_head) {
1860   _oops_do_mark_link = mark_link(old_head, claim_strong_done_tag);
1861 }
1862 
1863 nmethod::oops_do_mark_link* nmethod::oops_do_try_claim_strong_done() {
1864   assert(SafepointSynchronize::is_at_safepoint(), "only at safepoint");
1865 
1866   oops_do_mark_link* old_next = Atomic::cmpxchg(mark_link(this, claim_strong_done_tag), &_oops_do_mark_link, mark_link(NULL, claim_weak_request_tag));
1867   if (old_next == NULL) {
1868     oops_do_log_change("oops_do, mark strong done");
1869   }
1870   return old_next;
1871 }
1872 
1873 nmethod::oops_do_mark_link* nmethod::oops_do_try_add_strong_request(nmethod::oops_do_mark_link* next) {
1874   assert(SafepointSynchronize::is_at_safepoint(), "only at safepoint");
1875   assert(next == mark_link(this, claim_weak_request_tag), "Should be claimed as weak");
1876 
1877   oops_do_mark_link* old_next = Atomic::cmpxchg(mark_link(this, claim_strong_request_tag), &_oops_do_mark_link, next);
1878   if (old_next == next) {
1879     oops_do_log_change("oops_do, mark strong request");
1880   }
1881   return old_next;
1882 }
1883 
1884 bool nmethod::oops_do_try_claim_weak_done_as_strong_done(nmethod::oops_do_mark_link* next) {
1885   assert(SafepointSynchronize::is_at_safepoint(), "only at safepoint");
1886   assert(extract_state(next) == claim_weak_done_tag, "Should be claimed as weak done");
1887 
1888   oops_do_mark_link* old_next = Atomic::cmpxchg(mark_link(extract_nmethod(next), claim_strong_done_tag), &_oops_do_mark_link, next);
1889   if (old_next == next) {
1890     oops_do_log_change("oops_do, mark weak done -> mark strong done");
1891     return true;
1892   }
1893   return false;
1894 }
1895 
1896 nmethod* nmethod::oops_do_try_add_to_list_as_weak_done() {
1897   assert(SafepointSynchronize::is_at_safepoint(), "only at safepoint");
1898 
1899   assert(extract_state(_oops_do_mark_link) == claim_weak_request_tag ||
1900          extract_state(_oops_do_mark_link) == claim_strong_request_tag,
1901          "must be but is nmethod " PTR_FORMAT " %u", p2i(extract_nmethod(_oops_do_mark_link)), extract_state(_oops_do_mark_link));
1902 
1903   nmethod* old_head = Atomic::xchg(&_oops_do_mark_nmethods, this);
1904   // Self-loop if needed.
1905   if (old_head == NULL) {
1906     old_head = this;
1907   }
1908   // Try to install end of list and weak done tag.
1909   if (Atomic::cmpxchg(mark_link(old_head, claim_weak_done_tag), &_oops_do_mark_link, mark_link(this, claim_weak_request_tag)) == mark_link(this, claim_weak_request_tag)) {
1910     oops_do_log_change("oops_do, mark weak done");
1911     return NULL;
1912   } else {
1913     return old_head;
1914   }
1915 }
1916 
1917 void nmethod::oops_do_add_to_list_as_strong_done() {
1918   assert(SafepointSynchronize::is_at_safepoint(), "only at safepoint");
1919 
1920   nmethod* old_head = Atomic::xchg(&_oops_do_mark_nmethods, this);
1921   // Self-loop if needed.
1922   if (old_head == NULL) {
1923     old_head = this;
1924   }
1925   assert(_oops_do_mark_link == mark_link(this, claim_strong_done_tag), "must be but is nmethod " PTR_FORMAT " state %u",
1926          p2i(extract_nmethod(_oops_do_mark_link)), extract_state(_oops_do_mark_link));
1927 
1928   oops_do_set_strong_done(old_head);
1929 }




1133   if (m == NULL)  return;
1134   MethodData* mdo = m->method_data();
1135   if (mdo == NULL)  return;
1136   // There is a benign race here.  See comments in methodData.hpp.
1137   mdo->inc_decompile_count();
1138 }
1139 
1140 bool nmethod::try_transition(int new_state_int) {
1141   signed char new_state = new_state_int;
1142 #ifdef DEBUG
1143   if (new_state != unloaded) {
1144     assert_lock_strong(CompiledMethod_lock);
1145   }
1146 #endif
1147   for (;;) {
1148     signed char old_state = Atomic::load(&_state);
1149     if (old_state >= new_state) {
1150       // Ensure monotonicity of transitions.
1151       return false;
1152     }
1153     if (Atomic::cmpxchg(&_state, old_state, new_state) == old_state) {
1154       return true;
1155     }
1156   }
1157 }
1158 
1159 void nmethod::make_unloaded() {
1160   post_compiled_method_unload();
1161 
1162   // This nmethod is being unloaded, make sure that dependencies
1163   // recorded in instanceKlasses get flushed.
1164   // Since this work is being done during a GC, defer deleting dependencies from the
1165   // InstanceKlass.
1166   assert(Universe::heap()->is_gc_active() || Thread::current()->is_ConcurrentGC_thread(),
1167          "should only be called during gc");
1168   flush_dependencies(/*delete_immediately*/false);
1169 
1170   // Break cycle between nmethod & method
1171   LogTarget(Trace, class, unload, nmethod) lt;
1172   if (lt.is_enabled()) {
1173     LogStream ls(lt);


1832   LogTarget(Trace, gc, nmethod) lt;
1833   if (lt.is_enabled()) {
1834     LogStream ls(lt);
1835     CompileTask::print(&ls, this, state, true /* short_form */);
1836   }
1837 }
1838 
1839 bool nmethod::oops_do_try_claim() {
1840   if (oops_do_try_claim_weak_request()) {
1841     nmethod* result = oops_do_try_add_to_list_as_weak_done();
1842     assert(result == NULL, "adding to global list as weak done must always succeed.");
1843     return true;
1844   }
1845   return false;
1846 }
1847 
1848 bool nmethod::oops_do_try_claim_weak_request() {
1849   assert(SafepointSynchronize::is_at_safepoint(), "only at safepoint");
1850 
1851   if ((_oops_do_mark_link == NULL) &&
1852       (Atomic::replace_if_null(&_oops_do_mark_link, mark_link(this, claim_weak_request_tag)))) {
1853     oops_do_log_change("oops_do, mark weak request");
1854     return true;
1855   }
1856   return false;
1857 }
1858 
1859 void nmethod::oops_do_set_strong_done(nmethod* old_head) {
1860   _oops_do_mark_link = mark_link(old_head, claim_strong_done_tag);
1861 }
1862 
1863 nmethod::oops_do_mark_link* nmethod::oops_do_try_claim_strong_done() {
1864   assert(SafepointSynchronize::is_at_safepoint(), "only at safepoint");
1865 
1866   oops_do_mark_link* old_next = Atomic::cmpxchg(&_oops_do_mark_link, mark_link(NULL, claim_weak_request_tag), mark_link(this, claim_strong_done_tag));
1867   if (old_next == NULL) {
1868     oops_do_log_change("oops_do, mark strong done");
1869   }
1870   return old_next;
1871 }
1872 
1873 nmethod::oops_do_mark_link* nmethod::oops_do_try_add_strong_request(nmethod::oops_do_mark_link* next) {
1874   assert(SafepointSynchronize::is_at_safepoint(), "only at safepoint");
1875   assert(next == mark_link(this, claim_weak_request_tag), "Should be claimed as weak");
1876 
1877   oops_do_mark_link* old_next = Atomic::cmpxchg(&_oops_do_mark_link, next, mark_link(this, claim_strong_request_tag));
1878   if (old_next == next) {
1879     oops_do_log_change("oops_do, mark strong request");
1880   }
1881   return old_next;
1882 }
1883 
1884 bool nmethod::oops_do_try_claim_weak_done_as_strong_done(nmethod::oops_do_mark_link* next) {
1885   assert(SafepointSynchronize::is_at_safepoint(), "only at safepoint");
1886   assert(extract_state(next) == claim_weak_done_tag, "Should be claimed as weak done");
1887 
1888   oops_do_mark_link* old_next = Atomic::cmpxchg(&_oops_do_mark_link, next, mark_link(extract_nmethod(next), claim_strong_done_tag));
1889   if (old_next == next) {
1890     oops_do_log_change("oops_do, mark weak done -> mark strong done");
1891     return true;
1892   }
1893   return false;
1894 }
1895 
1896 nmethod* nmethod::oops_do_try_add_to_list_as_weak_done() {
1897   assert(SafepointSynchronize::is_at_safepoint(), "only at safepoint");
1898 
1899   assert(extract_state(_oops_do_mark_link) == claim_weak_request_tag ||
1900          extract_state(_oops_do_mark_link) == claim_strong_request_tag,
1901          "must be but is nmethod " PTR_FORMAT " %u", p2i(extract_nmethod(_oops_do_mark_link)), extract_state(_oops_do_mark_link));
1902 
1903   nmethod* old_head = Atomic::xchg(&_oops_do_mark_nmethods, this);
1904   // Self-loop if needed.
1905   if (old_head == NULL) {
1906     old_head = this;
1907   }
1908   // Try to install end of list and weak done tag.
1909   if (Atomic::cmpxchg(&_oops_do_mark_link, mark_link(this, claim_weak_request_tag), mark_link(old_head, claim_weak_done_tag)) == mark_link(this, claim_weak_request_tag)) {
1910     oops_do_log_change("oops_do, mark weak done");
1911     return NULL;
1912   } else {
1913     return old_head;
1914   }
1915 }
1916 
1917 void nmethod::oops_do_add_to_list_as_strong_done() {
1918   assert(SafepointSynchronize::is_at_safepoint(), "only at safepoint");
1919 
1920   nmethod* old_head = Atomic::xchg(&_oops_do_mark_nmethods, this);
1921   // Self-loop if needed.
1922   if (old_head == NULL) {
1923     old_head = this;
1924   }
1925   assert(_oops_do_mark_link == mark_link(this, claim_strong_done_tag), "must be but is nmethod " PTR_FORMAT " state %u",
1926          p2i(extract_nmethod(_oops_do_mark_link)), extract_state(_oops_do_mark_link));
1927 
1928   oops_do_set_strong_done(old_head);
1929 }


< prev index next >