comparison src/share/vm/code/nmethod.cpp @ 989:148e5441d916

6863023: need non-perm oops in code cache for JSR 292 Summary: Make a special root-list for those few nmethods which might contain non-perm oops. Reviewed-by: twisti, kvn, never, jmasa, ysr
author jrose
date Tue, 15 Sep 2009 21:53:47 -0700
parents 72088be4b386
children 54b3b351d6f9
comparison
equal deleted inserted replaced
987:00977607da34 989:148e5441d916
579 { 579 {
580 { 580 {
581 debug_only(No_Safepoint_Verifier nsv;) 581 debug_only(No_Safepoint_Verifier nsv;)
582 assert_locked_or_safepoint(CodeCache_lock); 582 assert_locked_or_safepoint(CodeCache_lock);
583 583
584 NOT_PRODUCT(_has_debug_info = false; ) 584 NOT_PRODUCT(_has_debug_info = false);
585 _oops_do_mark_link = NULL;
585 _method = method; 586 _method = method;
586 _entry_bci = InvocationEntryBci; 587 _entry_bci = InvocationEntryBci;
587 _link = NULL; 588 _osr_link = NULL;
589 _scavenge_root_link = NULL;
590 _scavenge_root_state = 0;
588 _compiler = NULL; 591 _compiler = NULL;
589 // We have no exception handler or deopt handler make the 592 // We have no exception handler or deopt handler make the
590 // values something that will never match a pc like the nmethod vtable entry 593 // values something that will never match a pc like the nmethod vtable entry
591 _exception_offset = 0; 594 _exception_offset = 0;
592 _deoptimize_offset = 0; 595 _deoptimize_offset = 0;
616 619
617 _lock_count = 0; 620 _lock_count = 0;
618 _stack_traversal_mark = 0; 621 _stack_traversal_mark = 0;
619 622
620 code_buffer->copy_oops_to(this); 623 code_buffer->copy_oops_to(this);
621 debug_only(check_store();) 624 debug_only(verify_scavenge_root_oops());
622 CodeCache::commit(this); 625 CodeCache::commit(this);
623 VTune::create_nmethod(this); 626 VTune::create_nmethod(this);
624 } 627 }
625 628
626 if (PrintNativeNMethods || PrintDebugInfo || PrintRelocations || PrintDependencies) { 629 if (PrintNativeNMethods || PrintDebugInfo || PrintRelocations || PrintDependencies) {
666 { 669 {
667 { 670 {
668 debug_only(No_Safepoint_Verifier nsv;) 671 debug_only(No_Safepoint_Verifier nsv;)
669 assert_locked_or_safepoint(CodeCache_lock); 672 assert_locked_or_safepoint(CodeCache_lock);
670 673
671 NOT_PRODUCT(_has_debug_info = false; ) 674 NOT_PRODUCT(_has_debug_info = false);
675 _oops_do_mark_link = NULL;
672 _method = method; 676 _method = method;
673 _entry_bci = InvocationEntryBci; 677 _entry_bci = InvocationEntryBci;
674 _link = NULL; 678 _osr_link = NULL;
679 _scavenge_root_link = NULL;
680 _scavenge_root_state = 0;
675 _compiler = NULL; 681 _compiler = NULL;
676 // We have no exception handler or deopt handler make the 682 // We have no exception handler or deopt handler make the
677 // values something that will never match a pc like the nmethod vtable entry 683 // values something that will never match a pc like the nmethod vtable entry
678 _exception_offset = 0; 684 _exception_offset = 0;
679 _deoptimize_offset = 0; 685 _deoptimize_offset = 0;
701 707
702 _lock_count = 0; 708 _lock_count = 0;
703 _stack_traversal_mark = 0; 709 _stack_traversal_mark = 0;
704 710
705 code_buffer->copy_oops_to(this); 711 code_buffer->copy_oops_to(this);
706 debug_only(check_store();) 712 debug_only(verify_scavenge_root_oops());
707 CodeCache::commit(this); 713 CodeCache::commit(this);
708 VTune::create_nmethod(this); 714 VTune::create_nmethod(this);
709 } 715 }
710 716
711 if (PrintNMethods || PrintDebugInfo || PrintRelocations || PrintDependencies) { 717 if (PrintNMethods || PrintDebugInfo || PrintRelocations || PrintDependencies) {
768 assert(debug_info->oop_recorder() == code_buffer->oop_recorder(), "shared OR"); 774 assert(debug_info->oop_recorder() == code_buffer->oop_recorder(), "shared OR");
769 { 775 {
770 debug_only(No_Safepoint_Verifier nsv;) 776 debug_only(No_Safepoint_Verifier nsv;)
771 assert_locked_or_safepoint(CodeCache_lock); 777 assert_locked_or_safepoint(CodeCache_lock);
772 778
773 NOT_PRODUCT(_has_debug_info = false; ) 779 NOT_PRODUCT(_has_debug_info = false);
780 _oops_do_mark_link = NULL;
774 _method = method; 781 _method = method;
775 _compile_id = compile_id; 782 _compile_id = compile_id;
776 _comp_level = comp_level; 783 _comp_level = comp_level;
777 _entry_bci = entry_bci; 784 _entry_bci = entry_bci;
778 _link = NULL; 785 _osr_link = NULL;
786 _scavenge_root_link = NULL;
787 _scavenge_root_state = 0;
779 _compiler = compiler; 788 _compiler = compiler;
780 _orig_pc_offset = orig_pc_offset; 789 _orig_pc_offset = orig_pc_offset;
781 #ifdef HAVE_DTRACE_H 790 #ifdef HAVE_DTRACE_H
782 _trap_offset = 0; 791 _trap_offset = 0;
783 #endif // def HAVE_DTRACE_H 792 #endif // def HAVE_DTRACE_H
811 820
812 // Copy contents of ScopeDescRecorder to nmethod 821 // Copy contents of ScopeDescRecorder to nmethod
813 code_buffer->copy_oops_to(this); 822 code_buffer->copy_oops_to(this);
814 debug_info->copy_to(this); 823 debug_info->copy_to(this);
815 dependencies->copy_to(this); 824 dependencies->copy_to(this);
816 debug_only(check_store();) 825 if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
826 CodeCache::add_scavenge_root_nmethod(this);
827 }
828 debug_only(verify_scavenge_root_oops());
817 829
818 CodeCache::commit(this); 830 CodeCache::commit(this);
819 831
820 VTune::create_nmethod(this); 832 VTune::create_nmethod(this);
821 833
900 // Print out more verbose output usually for a newly created nmethod. 912 // Print out more verbose output usually for a newly created nmethod.
901 void nmethod::print_on(outputStream* st, const char* title) const { 913 void nmethod::print_on(outputStream* st, const char* title) const {
902 if (st != NULL) { 914 if (st != NULL) {
903 ttyLocker ttyl; 915 ttyLocker ttyl;
904 // Print a little tag line that looks like +PrintCompilation output: 916 // Print a little tag line that looks like +PrintCompilation output:
905 st->print("%3d%c %s", 917 int tlen = (int) strlen(title);
918 bool do_nl = false;
919 if (tlen > 0 && title[tlen-1] == '\n') { tlen--; do_nl = true; }
920 st->print("%3d%c %.*s",
906 compile_id(), 921 compile_id(),
907 is_osr_method() ? '%' : 922 is_osr_method() ? '%' :
908 method() != NULL && 923 method() != NULL &&
909 is_native_method() ? 'n' : ' ', 924 is_native_method() ? 'n' : ' ',
910 title); 925 tlen, title);
911 #ifdef TIERED 926 #ifdef TIERED
912 st->print(" (%d) ", comp_level()); 927 st->print(" (%d) ", comp_level());
913 #endif // TIERED 928 #endif // TIERED
914 if (WizardMode) st->print(" (" INTPTR_FORMAT ")", this); 929 if (WizardMode) st->print(" (" INTPTR_FORMAT ")", this);
915 if (method() != NULL) { 930 if (Universe::heap()->is_gc_active() && method() != NULL) {
916 method()->print_short_name(st); 931 st->print("(method)");
932 } else if (method() != NULL) {
933 method()->print_short_name(st);
917 if (is_osr_method()) 934 if (is_osr_method())
918 st->print(" @ %d", osr_entry_bci()); 935 st->print(" @ %d", osr_entry_bci());
919 if (method()->code_size() > 0) 936 if (method()->code_size() > 0)
920 st->print(" (%d bytes)", method()->code_size()); 937 st->print(" (%d bytes)", method()->code_size());
921 } 938 }
939
940 if (do_nl) st->cr();
922 } 941 }
923 } 942 }
924 943
925 944
926 void nmethod::print_nmethod(bool printmethod) { 945 void nmethod::print_nmethod(bool printmethod) {
1031 } 1050 }
1032 } 1051 }
1033 } 1052 }
1034 } 1053 }
1035 1054
1055 // This is a private interface with the sweeper.
1036 void nmethod::mark_as_seen_on_stack() { 1056 void nmethod::mark_as_seen_on_stack() {
1037 assert(is_not_entrant(), "must be a non-entrant method"); 1057 assert(is_not_entrant(), "must be a non-entrant method");
1038 set_stack_traversal_mark(NMethodSweeper::traversal_count()); 1058 set_stack_traversal_mark(NMethodSweeper::traversal_count());
1039 } 1059 }
1040 1060
1075 if (TraceClassUnloading && WizardMode) { 1095 if (TraceClassUnloading && WizardMode) {
1076 tty->print_cr("[Class unloading: Making nmethod " INTPTR_FORMAT 1096 tty->print_cr("[Class unloading: Making nmethod " INTPTR_FORMAT
1077 " unloadable], methodOop(" INTPTR_FORMAT 1097 " unloadable], methodOop(" INTPTR_FORMAT
1078 "), cause(" INTPTR_FORMAT ")", 1098 "), cause(" INTPTR_FORMAT ")",
1079 this, (address)_method, (address)cause); 1099 this, (address)_method, (address)cause);
1080 cause->klass()->print(); 1100 if (!Universe::heap()->is_gc_active())
1101 cause->klass()->print();
1081 } 1102 }
1082 // If _method is already NULL the methodOop is about to be unloaded, 1103 // If _method is already NULL the methodOop is about to be unloaded,
1083 // so we don't have to break the cycle. Note that it is possible to 1104 // so we don't have to break the cycle. Note that it is possible to
1084 // have the methodOop live here, in case we unload the nmethod because 1105 // have the methodOop live here, in case we unload the nmethod because
1085 // it is pointing to some oop (other than the methodOop) being unloaded. 1106 // it is pointing to some oop (other than the methodOop) being unloaded.
1103 flags.state = unloaded; 1124 flags.state = unloaded;
1104 1125
1105 // The methodOop is gone at this point 1126 // The methodOop is gone at this point
1106 assert(_method == NULL, "Tautology"); 1127 assert(_method == NULL, "Tautology");
1107 1128
1108 set_link(NULL); 1129 set_osr_link(NULL);
1130 //set_scavenge_root_link(NULL); // done by prune_scavenge_root_nmethods
1109 NMethodSweeper::notify(this); 1131 NMethodSweeper::notify(this);
1110 } 1132 }
1111 1133
1112 void nmethod::invalidate_osr_method() { 1134 void nmethod::invalidate_osr_method() {
1113 assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); 1135 assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod");
1287 set_exception_cache(NULL); 1309 set_exception_cache(NULL);
1288 while(ec != NULL) { 1310 while(ec != NULL) {
1289 ExceptionCache* next = ec->next(); 1311 ExceptionCache* next = ec->next();
1290 delete ec; 1312 delete ec;
1291 ec = next; 1313 ec = next;
1314 }
1315
1316 if (on_scavenge_root_list()) {
1317 CodeCache::drop_scavenge_root_nmethod(this);
1292 } 1318 }
1293 1319
1294 ((CodeBlob*)(this))->flush(); 1320 ((CodeBlob*)(this))->flush();
1295 1321
1296 CodeCache::free(this); 1322 CodeCache::free(this);
1348 // The oop should be kept alive 1374 // The oop should be kept alive
1349 keep_alive->do_oop(root); 1375 keep_alive->do_oop(root);
1350 return false; 1376 return false;
1351 } 1377 }
1352 } 1378 }
1353 assert(unloading_occurred, "Inconsistency in unloading"); 1379 // If ScavengeRootsInCode is true, an nmethod might be unloaded
1380 // simply because one of its constant oops has gone dead.
1381 // No actual classes need to be unloaded in order for this to occur.
1382 assert(unloading_occurred || ScavengeRootsInCode, "Inconsistency in unloading");
1354 make_unloaded(is_alive, obj); 1383 make_unloaded(is_alive, obj);
1355 return true; 1384 return true;
1356 } 1385 }
1357 1386
1358 // ------------------------------------------------------------------ 1387 // ------------------------------------------------------------------
1556 } 1585 }
1557 } 1586 }
1558 } 1587 }
1559 1588
1560 // Scopes 1589 // Scopes
1590 // This includes oop constants not inlined in the code stream.
1561 for (oop* p = oops_begin(); p < oops_end(); p++) { 1591 for (oop* p = oops_begin(); p < oops_end(); p++) {
1562 if (*p == Universe::non_oop_word()) continue; // skip non-oops 1592 if (*p == Universe::non_oop_word()) continue; // skip non-oops
1563 f->do_oop(p); 1593 f->do_oop(p);
1564 } 1594 }
1595 }
1596
1597 #define NMETHOD_SENTINEL ((nmethod*)badAddress)
1598
1599 nmethod* volatile nmethod::_oops_do_mark_nmethods;
1600
1601 // An nmethod is "marked" if its _mark_link is set non-null.
1602 // Even if it is the end of the linked list, it will have a non-null link value,
1603 // as long as it is on the list.
1604 // This code must be MP safe, because it is used from parallel GC passes.
1605 bool nmethod::test_set_oops_do_mark() {
1606 assert(nmethod::oops_do_marking_is_active(), "oops_do_marking_prologue must be called");
1607 nmethod* observed_mark_link = _oops_do_mark_link;
1608 if (observed_mark_link == NULL) {
1609 // Claim this nmethod for this thread to mark.
1610 observed_mark_link = (nmethod*)
1611 Atomic::cmpxchg_ptr(NMETHOD_SENTINEL, &_oops_do_mark_link, NULL);
1612 if (observed_mark_link == NULL) {
1613
1614 // Atomically append this nmethod (now claimed) to the head of the list:
1615 nmethod* observed_mark_nmethods = _oops_do_mark_nmethods;
1616 for (;;) {
1617 nmethod* required_mark_nmethods = observed_mark_nmethods;
1618 _oops_do_mark_link = required_mark_nmethods;
1619 observed_mark_nmethods = (nmethod*)
1620 Atomic::cmpxchg_ptr(this, &_oops_do_mark_nmethods, required_mark_nmethods);
1621 if (observed_mark_nmethods == required_mark_nmethods)
1622 break;
1623 }
1624 // Mark was clear when we first saw this guy.
1625 NOT_PRODUCT(if (TraceScavenge) print_on(tty, "oops_do, mark\n"));
1626 return false;
1627 }
1628 }
1629 // On fall through, another racing thread marked this nmethod before we did.
1630 return true;
1631 }
1632
1633 void nmethod::oops_do_marking_prologue() {
1634 NOT_PRODUCT(if (TraceScavenge) tty->print_cr("[oops_do_marking_prologue"));
1635 assert(_oops_do_mark_nmethods == NULL, "must not call oops_do_marking_prologue twice in a row");
1636 // We use cmpxchg_ptr instead of regular assignment here because the user
1637 // may fork a bunch of threads, and we need them all to see the same state.
1638 void* observed = Atomic::cmpxchg_ptr(NMETHOD_SENTINEL, &_oops_do_mark_nmethods, NULL);
1639 guarantee(observed == NULL, "no races in this sequential code");
1640 }
1641
1642 void nmethod::oops_do_marking_epilogue() {
1643 assert(_oops_do_mark_nmethods != NULL, "must not call oops_do_marking_epilogue twice in a row");
1644 nmethod* cur = _oops_do_mark_nmethods;
1645 while (cur != NMETHOD_SENTINEL) {
1646 assert(cur != NULL, "not NULL-terminated");
1647 nmethod* next = cur->_oops_do_mark_link;
1648 cur->_oops_do_mark_link = NULL;
1649 NOT_PRODUCT(if (TraceScavenge) cur->print_on(tty, "oops_do, unmark\n"));
1650 cur = next;
1651 }
1652 void* required = _oops_do_mark_nmethods;
1653 void* observed = Atomic::cmpxchg_ptr(NULL, &_oops_do_mark_nmethods, required);
1654 guarantee(observed == required, "no races in this sequential code");
1655 NOT_PRODUCT(if (TraceScavenge) tty->print_cr("oops_do_marking_epilogue]"));
1656 }
1657
1658 class DetectScavengeRoot: public OopClosure {
1659 bool _detected_scavenge_root;
1660 public:
1661 DetectScavengeRoot() : _detected_scavenge_root(false)
1662 { NOT_PRODUCT(_print_nm = NULL); }
1663 bool detected_scavenge_root() { return _detected_scavenge_root; }
1664 virtual void do_oop(oop* p) {
1665 if ((*p) != NULL && (*p)->is_scavengable()) {
1666 NOT_PRODUCT(maybe_print(p));
1667 _detected_scavenge_root = true;
1668 }
1669 }
1670 virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
1671
1672 #ifndef PRODUCT
1673 nmethod* _print_nm;
1674 void maybe_print(oop* p) {
1675 if (_print_nm == NULL) return;
1676 if (!_detected_scavenge_root) _print_nm->print_on(tty, "new scavenge root");
1677 tty->print_cr(""PTR_FORMAT"[offset=%d] detected non-perm oop "PTR_FORMAT" (found at "PTR_FORMAT")",
1678 _print_nm, (int)((intptr_t)p - (intptr_t)_print_nm),
1679 (intptr_t)(*p), (intptr_t)p);
1680 (*p)->print();
1681 }
1682 #endif //PRODUCT
1683 };
1684
1685 bool nmethod::detect_scavenge_root_oops() {
1686 DetectScavengeRoot detect_scavenge_root;
1687 NOT_PRODUCT(if (TraceScavenge) detect_scavenge_root._print_nm = this);
1688 oops_do(&detect_scavenge_root);
1689 return detect_scavenge_root.detected_scavenge_root();
1565 } 1690 }
1566 1691
1567 // Method that knows how to preserve outgoing arguments at call. This method must be 1692 // Method that knows how to preserve outgoing arguments at call. This method must be
1568 // called with a frame corresponding to a Java invoke 1693 // called with a frame corresponding to a Java invoke
1569 void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { 1694 void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) {
1876 2001
1877 2002
1878 // ----------------------------------------------------------------------------- 2003 // -----------------------------------------------------------------------------
1879 // Verification 2004 // Verification
1880 2005
2006 class VerifyOopsClosure: public OopClosure {
2007 nmethod* _nm;
2008 bool _ok;
2009 public:
2010 VerifyOopsClosure(nmethod* nm) : _nm(nm), _ok(true) { }
2011 bool ok() { return _ok; }
2012 virtual void do_oop(oop* p) {
2013 if ((*p) == NULL || (*p)->is_oop()) return;
2014 if (_ok) {
2015 _nm->print_nmethod(true);
2016 _ok = false;
2017 }
2018 tty->print_cr("*** non-oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)",
2019 (intptr_t)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm));
2020 }
2021 virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
2022 };
2023
1881 void nmethod::verify() { 2024 void nmethod::verify() {
1882 2025
1883 // Hmm. OSR methods can be deopted but not marked as zombie or not_entrant 2026 // Hmm. OSR methods can be deopted but not marked as zombie or not_entrant
1884 // seems odd. 2027 // seems odd.
1885 2028
1908 for (PcDesc* p = scopes_pcs_begin(); p < scopes_pcs_end(); p++) { 2051 for (PcDesc* p = scopes_pcs_begin(); p < scopes_pcs_end(); p++) {
1909 if (! p->verify(this)) { 2052 if (! p->verify(this)) {
1910 tty->print_cr("\t\tin nmethod at " INTPTR_FORMAT " (pcs)", this); 2053 tty->print_cr("\t\tin nmethod at " INTPTR_FORMAT " (pcs)", this);
1911 } 2054 }
1912 } 2055 }
2056
2057 VerifyOopsClosure voc(this);
2058 oops_do(&voc);
2059 assert(voc.ok(), "embedded oops must be OK");
2060 verify_scavenge_root_oops();
1913 2061
1914 verify_scopes(); 2062 verify_scopes();
1915 } 2063 }
1916 2064
1917 2065
1972 2120
1973 // ----------------------------------------------------------------------------- 2121 // -----------------------------------------------------------------------------
1974 // Non-product code 2122 // Non-product code
1975 #ifndef PRODUCT 2123 #ifndef PRODUCT
1976 2124
1977 void nmethod::check_store() { 2125 class DebugScavengeRoot: public OopClosure {
1978 // Make sure all oops in the compiled code are tenured 2126 nmethod* _nm;
1979 2127 bool _ok;
1980 RelocIterator iter(this); 2128 public:
1981 while (iter.next()) { 2129 DebugScavengeRoot(nmethod* nm) : _nm(nm), _ok(true) { }
1982 if (iter.type() == relocInfo::oop_type) { 2130 bool ok() { return _ok; }
1983 oop_Relocation* reloc = iter.oop_reloc(); 2131 virtual void do_oop(oop* p) {
1984 oop obj = reloc->oop_value(); 2132 if ((*p) == NULL || !(*p)->is_scavengable()) return;
1985 if (obj != NULL && !obj->is_perm()) { 2133 if (_ok) {
1986 fatal("must be permanent oop in compiled code"); 2134 _nm->print_nmethod(true);
1987 } 2135 _ok = false;
1988 } 2136 }
1989 } 2137 tty->print_cr("*** non-perm oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)",
2138 (intptr_t)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm));
2139 (*p)->print();
2140 }
2141 virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }
2142 };
2143
2144 void nmethod::verify_scavenge_root_oops() {
2145 if (!on_scavenge_root_list()) {
2146 // Actually look inside, to verify the claim that it's clean.
2147 DebugScavengeRoot debug_scavenge_root(this);
2148 oops_do(&debug_scavenge_root);
2149 if (!debug_scavenge_root.ok())
2150 fatal("found an unadvertised bad non-perm oop in the code cache");
2151 }
2152 assert(scavenge_root_not_marked(), "");
1990 } 2153 }
1991 2154
1992 #endif // PRODUCT 2155 #endif // PRODUCT
1993 2156
1994 // Printing operations 2157 // Printing operations
2017 if (level()) tty->print("l%d ", level()); 2180 if (level()) tty->print("l%d ", level());
2018 if (is_in_use()) tty->print("in_use "); 2181 if (is_in_use()) tty->print("in_use ");
2019 if (is_not_entrant()) tty->print("not_entrant "); 2182 if (is_not_entrant()) tty->print("not_entrant ");
2020 if (is_zombie()) tty->print("zombie "); 2183 if (is_zombie()) tty->print("zombie ");
2021 if (is_unloaded()) tty->print("unloaded "); 2184 if (is_unloaded()) tty->print("unloaded ");
2185 if (on_scavenge_root_list()) tty->print("scavenge_root ");
2022 tty->print_cr("}:"); 2186 tty->print_cr("}:");
2023 } 2187 }
2024 if (size () > 0) tty->print_cr(" total in heap [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", 2188 if (size () > 0) tty->print_cr(" total in heap [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
2025 (address)this, 2189 (address)this,
2026 (address)this + size(), 2190 (address)this + size(),