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 }
|