src/hotspot/share/code/nmethod.cpp
changeset 58777 18c246ad2ff9
parent 58377 975f2d30f6b3
child 59056 15936b142f86
equal deleted inserted replaced
58776:ea153023d832 58777:18c246ad2ff9
  1824     if (*p == Universe::non_oop_word())  continue;  // skip non-oops
  1824     if (*p == Universe::non_oop_word())  continue;  // skip non-oops
  1825     f->do_oop(p);
  1825     f->do_oop(p);
  1826   }
  1826   }
  1827 }
  1827 }
  1828 
  1828 
  1829 #define NMETHOD_SENTINEL ((nmethod*)badAddress)
       
  1830 
       
  1831 nmethod* volatile nmethod::_oops_do_mark_nmethods;
  1829 nmethod* volatile nmethod::_oops_do_mark_nmethods;
  1832 
  1830 
  1833 // An nmethod is "marked" if its _mark_link is set non-null.
  1831 void nmethod::oops_do_log_change(const char* state) {
  1834 // Even if it is the end of the linked list, it will have a non-null link value,
  1832   LogTarget(Trace, gc, nmethod) lt;
  1835 // as long as it is on the list.
  1833   if (lt.is_enabled()) {
  1836 // This code must be MP safe, because it is used from parallel GC passes.
  1834     LogStream ls(lt);
  1837 bool nmethod::test_set_oops_do_mark() {
  1835     CompileTask::print(&ls, this, state, true /* short_form */);
  1838   assert(nmethod::oops_do_marking_is_active(), "oops_do_marking_prologue must be called");
  1836   }
  1839   if (_oops_do_mark_link == NULL) {
  1837 }
  1840     // Claim this nmethod for this thread to mark.
  1838 
  1841     if (Atomic::replace_if_null(NMETHOD_SENTINEL, &_oops_do_mark_link)) {
  1839 bool nmethod::oops_do_try_claim() {
  1842       // Atomically append this nmethod (now claimed) to the head of the list:
  1840   if (oops_do_try_claim_weak_request()) {
  1843       nmethod* observed_mark_nmethods = _oops_do_mark_nmethods;
  1841     nmethod* result = oops_do_try_add_to_list_as_weak_done();
  1844       for (;;) {
  1842     assert(result == NULL, "adding to global list as weak done must always succeed.");
  1845         nmethod* required_mark_nmethods = observed_mark_nmethods;
  1843     return true;
  1846         _oops_do_mark_link = required_mark_nmethods;
  1844   }
  1847         observed_mark_nmethods =
  1845   return false;
  1848           Atomic::cmpxchg(this, &_oops_do_mark_nmethods, required_mark_nmethods);
  1846 }
  1849         if (observed_mark_nmethods == required_mark_nmethods)
  1847 
  1850           break;
  1848 bool nmethod::oops_do_try_claim_weak_request() {
  1851       }
  1849   assert(SafepointSynchronize::is_at_safepoint(), "only at safepoint");
  1852       // Mark was clear when we first saw this guy.
  1850 
  1853       LogTarget(Trace, gc, nmethod) lt;
  1851   if ((_oops_do_mark_link == NULL) &&
  1854       if (lt.is_enabled()) {
  1852       (Atomic::replace_if_null(mark_link(this, claim_weak_request_tag), &_oops_do_mark_link))) {
  1855         LogStream ls(lt);
  1853     oops_do_log_change("oops_do, mark weak request");
  1856         CompileTask::print(&ls, this, "oops_do, mark", /*short_form:*/ true);
  1854     return true;
  1857       }
  1855   }
  1858       return false;
  1856   return false;
  1859     }
  1857 }
  1860   }
  1858 
  1861   // On fall through, another racing thread marked this nmethod before we did.
  1859 void nmethod::oops_do_set_strong_done(nmethod* old_head) {
  1862   return true;
  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(this, &_oops_do_mark_nmethods);
       
  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(this, &_oops_do_mark_nmethods);
       
  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 }
       
  1930 
       
  1931 void nmethod::oops_do_process_weak(OopsDoProcessor* p) {
       
  1932   if (!oops_do_try_claim_weak_request()) {
       
  1933     // Failed to claim for weak processing.
       
  1934     oops_do_log_change("oops_do, mark weak request fail");
       
  1935     return;
       
  1936   }
       
  1937 
       
  1938   p->do_regular_processing(this);
       
  1939 
       
  1940   nmethod* old_head = oops_do_try_add_to_list_as_weak_done();
       
  1941   if (old_head == NULL) {
       
  1942     return;
       
  1943   }
       
  1944   oops_do_log_change("oops_do, mark weak done fail");
       
  1945   // Adding to global list failed, another thread added a strong request.
       
  1946   assert(extract_state(_oops_do_mark_link) == claim_strong_request_tag,
       
  1947          "must be but is %u", extract_state(_oops_do_mark_link));
       
  1948 
       
  1949   oops_do_log_change("oops_do, mark weak request -> mark strong done");
       
  1950 
       
  1951   oops_do_set_strong_done(old_head);
       
  1952   // Do missing strong processing.
       
  1953   p->do_remaining_strong_processing(this);
       
  1954 }
       
  1955 
       
  1956 void nmethod::oops_do_process_strong(OopsDoProcessor* p) {
       
  1957   oops_do_mark_link* next_raw = oops_do_try_claim_strong_done();
       
  1958   if (next_raw == NULL) {
       
  1959     p->do_regular_processing(this);
       
  1960     oops_do_add_to_list_as_strong_done();
       
  1961     return;
       
  1962   }
       
  1963   // Claim failed. Figure out why and handle it.
       
  1964   if (oops_do_has_weak_request(next_raw)) {
       
  1965     oops_do_mark_link* old = next_raw;
       
  1966     // Claim failed because being weak processed (state == "weak request").
       
  1967     // Try to request deferred strong processing.
       
  1968     next_raw = oops_do_try_add_strong_request(old);
       
  1969     if (next_raw == old) {
       
  1970       // Successfully requested deferred strong processing.
       
  1971       return;
       
  1972     }
       
  1973     // Failed because of a concurrent transition. No longer in "weak request" state.
       
  1974   }
       
  1975   if (oops_do_has_any_strong_state(next_raw)) {
       
  1976     // Already claimed for strong processing or requested for such.
       
  1977     return;
       
  1978   }
       
  1979   if (oops_do_try_claim_weak_done_as_strong_done(next_raw)) {
       
  1980     // Successfully claimed "weak done" as "strong done". Do the missing marking.
       
  1981     p->do_remaining_strong_processing(this);
       
  1982     return;
       
  1983   }
       
  1984   // Claim failed, some other thread got it.
  1863 }
  1985 }
  1864 
  1986 
  1865 void nmethod::oops_do_marking_prologue() {
  1987 void nmethod::oops_do_marking_prologue() {
       
  1988   assert_at_safepoint();
       
  1989 
  1866   log_trace(gc, nmethod)("oops_do_marking_prologue");
  1990   log_trace(gc, nmethod)("oops_do_marking_prologue");
  1867   assert(_oops_do_mark_nmethods == NULL, "must not call oops_do_marking_prologue twice in a row");
  1991   assert(_oops_do_mark_nmethods == NULL, "must be empty");
  1868   // We use cmpxchg instead of regular assignment here because the user
       
  1869   // may fork a bunch of threads, and we need them all to see the same state.
       
  1870   nmethod* observed = Atomic::cmpxchg(NMETHOD_SENTINEL, &_oops_do_mark_nmethods, (nmethod*)NULL);
       
  1871   guarantee(observed == NULL, "no races in this sequential code");
       
  1872 }
  1992 }
  1873 
  1993 
  1874 void nmethod::oops_do_marking_epilogue() {
  1994 void nmethod::oops_do_marking_epilogue() {
  1875   assert(_oops_do_mark_nmethods != NULL, "must not call oops_do_marking_epilogue twice in a row");
  1995   assert_at_safepoint();
  1876   nmethod* cur = _oops_do_mark_nmethods;
  1996 
  1877   while (cur != NMETHOD_SENTINEL) {
  1997   nmethod* next = _oops_do_mark_nmethods;
  1878     assert(cur != NULL, "not NULL-terminated");
  1998   _oops_do_mark_nmethods = NULL;
  1879     nmethod* next = cur->_oops_do_mark_link;
  1999   if (next == NULL) {
       
  2000     return;
       
  2001   }
       
  2002   nmethod* cur;
       
  2003   do {
       
  2004     cur = next;
       
  2005     next = extract_nmethod(cur->_oops_do_mark_link);
  1880     cur->_oops_do_mark_link = NULL;
  2006     cur->_oops_do_mark_link = NULL;
  1881     DEBUG_ONLY(cur->verify_oop_relocations());
  2007     DEBUG_ONLY(cur->verify_oop_relocations());
  1882 
  2008 
  1883     LogTarget(Trace, gc, nmethod) lt;
  2009     LogTarget(Trace, gc, nmethod) lt;
  1884     if (lt.is_enabled()) {
  2010     if (lt.is_enabled()) {
  1885       LogStream ls(lt);
  2011       LogStream ls(lt);
  1886       CompileTask::print(&ls, cur, "oops_do, unmark", /*short_form:*/ true);
  2012       CompileTask::print(&ls, cur, "oops_do, unmark", /*short_form:*/ true);
  1887     }
  2013     }
  1888     cur = next;
  2014     // End if self-loop has been detected.
  1889   }
  2015   } while (cur != next);
  1890   nmethod* required = _oops_do_mark_nmethods;
       
  1891   nmethod* observed = Atomic::cmpxchg((nmethod*)NULL, &_oops_do_mark_nmethods, required);
       
  1892   guarantee(observed == required, "no races in this sequential code");
       
  1893   log_trace(gc, nmethod)("oops_do_marking_epilogue");
  2016   log_trace(gc, nmethod)("oops_do_marking_epilogue");
  1894 }
  2017 }
  1895 
  2018 
  1896 inline bool includes(void* p, void* from, void* to) {
  2019 inline bool includes(void* p, void* from, void* to) {
  1897   return from <= p && p < to;
  2020   return from <= p && p < to;
  2260   VerifyOopsClosure voc(this);
  2383   VerifyOopsClosure voc(this);
  2261   oops_do(&voc);
  2384   oops_do(&voc);
  2262   assert(voc.ok(), "embedded oops must be OK");
  2385   assert(voc.ok(), "embedded oops must be OK");
  2263   Universe::heap()->verify_nmethod(this);
  2386   Universe::heap()->verify_nmethod(this);
  2264 
  2387 
       
  2388   assert(_oops_do_mark_link == NULL, "_oops_do_mark_link for %s should be NULL but is " PTR_FORMAT,
       
  2389          nm->method()->external_name(), p2i(_oops_do_mark_link));
  2265   verify_scopes();
  2390   verify_scopes();
  2266 
  2391 
  2267   CompiledICLocker nm_verify(this);
  2392   CompiledICLocker nm_verify(this);
  2268   VerifyMetadataClosure vmc;
  2393   VerifyMetadataClosure vmc;
  2269   metadata_do(&vmc);
  2394   metadata_do(&vmc);