Mercurial > hg > truffle
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(), |