comparison src/share/vm/interpreter/bytecodeInterpreter.cpp @ 14395:48d3d0eb193b

8017317: PPC64 (part 7): cppInterpreter: implement support for biased locking Reviewed-by: kvn, dholmes
author goetz
date Wed, 26 Jun 2013 16:06:38 +0200
parents 603ca7e51354
children 583211d4b16b
comparison
equal deleted inserted replaced
14394:58be756e7595 14395:48d3d0eb193b
34 #include "memory/resourceArea.hpp" 34 #include "memory/resourceArea.hpp"
35 #include "oops/methodCounters.hpp" 35 #include "oops/methodCounters.hpp"
36 #include "oops/objArrayKlass.hpp" 36 #include "oops/objArrayKlass.hpp"
37 #include "oops/oop.inline.hpp" 37 #include "oops/oop.inline.hpp"
38 #include "prims/jvmtiExport.hpp" 38 #include "prims/jvmtiExport.hpp"
39 #include "runtime/biasedLocking.hpp"
39 #include "runtime/frame.inline.hpp" 40 #include "runtime/frame.inline.hpp"
40 #include "runtime/handles.inline.hpp" 41 #include "runtime/handles.inline.hpp"
41 #include "runtime/interfaceSupport.hpp" 42 #include "runtime/interfaceSupport.hpp"
42 #include "runtime/sharedRuntime.hpp" 43 #include "runtime/sharedRuntime.hpp"
43 #include "runtime/threadCritical.hpp" 44 #include "runtime/threadCritical.hpp"
677 #endif // HACK 678 #endif // HACK
678 679
679 680
680 // lock method if synchronized 681 // lock method if synchronized
681 if (METHOD->is_synchronized()) { 682 if (METHOD->is_synchronized()) {
682 // oop rcvr = locals[0].j.r; 683 // oop rcvr = locals[0].j.r;
683 oop rcvr; 684 oop rcvr;
684 if (METHOD->is_static()) { 685 if (METHOD->is_static()) {
685 rcvr = METHOD->constants()->pool_holder()->java_mirror(); 686 rcvr = METHOD->constants()->pool_holder()->java_mirror();
686 } else { 687 } else {
687 rcvr = LOCALS_OBJECT(0); 688 rcvr = LOCALS_OBJECT(0);
688 VERIFY_OOP(rcvr); 689 VERIFY_OOP(rcvr);
689 } 690 }
690 // The initial monitor is ours for the taking 691 // The initial monitor is ours for the taking
691 BasicObjectLock* mon = &istate->monitor_base()[-1]; 692 // Monitor not filled in frame manager any longer as this caused race condition with biased locking.
692 oop monobj = mon->obj(); 693 BasicObjectLock* mon = &istate->monitor_base()[-1];
693 assert(mon->obj() == rcvr, "method monitor mis-initialized"); 694 mon->set_obj(rcvr);
694 695 bool success = false;
695 bool success = UseBiasedLocking; 696 uintptr_t epoch_mask_in_place = (uintptr_t)markOopDesc::epoch_mask_in_place;
696 if (UseBiasedLocking) { 697 markOop mark = rcvr->mark();
697 markOop mark = rcvr->mark(); 698 intptr_t hash = (intptr_t) markOopDesc::no_hash;
698 if (mark->has_bias_pattern()) { 699 // Implies UseBiasedLocking.
699 // The bias pattern is present in the object's header. Need to check 700 if (mark->has_bias_pattern()) {
700 // whether the bias owner and the epoch are both still current. 701 uintptr_t thread_ident;
701 intptr_t xx = ((intptr_t) THREAD) ^ (intptr_t) mark; 702 uintptr_t anticipated_bias_locking_value;
702 xx = (intptr_t) rcvr->klass()->prototype_header() ^ xx; 703 thread_ident = (uintptr_t)istate->thread();
703 intptr_t yy = (xx & ~((int) markOopDesc::age_mask_in_place)); 704 anticipated_bias_locking_value =
704 if (yy != 0 ) { 705 (((uintptr_t)rcvr->klass()->prototype_header() | thread_ident) ^ (uintptr_t)mark) &
705 // At this point we know that the header has the bias pattern and 706 ~((uintptr_t) markOopDesc::age_mask_in_place);
706 // that we are not the bias owner in the current epoch. We need to 707
707 // figure out more details about the state of the header in order to 708 if (anticipated_bias_locking_value == 0) {
708 // know what operations can be legally performed on the object's 709 // Already biased towards this thread, nothing to do.
709 // header. 710 if (PrintBiasedLockingStatistics) {
710 711 (* BiasedLocking::biased_lock_entry_count_addr())++;
711 // If the low three bits in the xor result aren't clear, that means 712 }
712 // the prototype header is no longer biased and we have to revoke 713 success = true;
713 // the bias on this object. 714 } else if ((anticipated_bias_locking_value & markOopDesc::biased_lock_mask_in_place) != 0) {
714 715 // Try to revoke bias.
715 if (yy & markOopDesc::biased_lock_mask_in_place == 0 ) { 716 markOop header = rcvr->klass()->prototype_header();
716 // Biasing is still enabled for this data type. See whether the 717 if (hash != markOopDesc::no_hash) {
717 // epoch of the current bias is still valid, meaning that the epoch 718 header = header->copy_set_hash(hash);
718 // bits of the mark word are equal to the epoch bits of the 719 }
719 // prototype header. (Note that the prototype header's epoch bits 720 if (Atomic::cmpxchg_ptr(header, rcvr->mark_addr(), mark) == mark) {
720 // only change at a safepoint.) If not, attempt to rebias the object 721 if (PrintBiasedLockingStatistics)
721 // toward the current thread. Note that we must be absolutely sure 722 (*BiasedLocking::revoked_lock_entry_count_addr())++;
722 // that the current epoch is invalid in order to do this because 723 }
723 // otherwise the manipulations it performs on the mark word are 724 } else if ((anticipated_bias_locking_value & epoch_mask_in_place) != 0) {
724 // illegal. 725 // Try to rebias.
725 if (yy & markOopDesc::epoch_mask_in_place == 0) { 726 markOop new_header = (markOop) ( (intptr_t) rcvr->klass()->prototype_header() | thread_ident);
726 // The epoch of the current bias is still valid but we know nothing 727 if (hash != markOopDesc::no_hash) {
727 // about the owner; it might be set or it might be clear. Try to 728 new_header = new_header->copy_set_hash(hash);
728 // acquire the bias of the object using an atomic operation. If this 729 }
729 // fails we will go in to the runtime to revoke the object's bias. 730 if (Atomic::cmpxchg_ptr((void*)new_header, rcvr->mark_addr(), mark) == mark) {
730 // Note that we first construct the presumed unbiased header so we 731 if (PrintBiasedLockingStatistics) {
731 // don't accidentally blow away another thread's valid bias. 732 (* BiasedLocking::rebiased_lock_entry_count_addr())++;
732 intptr_t unbiased = (intptr_t) mark & (markOopDesc::biased_lock_mask_in_place |
733 markOopDesc::age_mask_in_place |
734 markOopDesc::epoch_mask_in_place);
735 if (Atomic::cmpxchg_ptr((intptr_t)THREAD | unbiased, (intptr_t*) rcvr->mark_addr(), unbiased) != unbiased) {
736 CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception);
737 }
738 } else {
739 try_rebias:
740 // At this point we know the epoch has expired, meaning that the
741 // current "bias owner", if any, is actually invalid. Under these
742 // circumstances _only_, we are allowed to use the current header's
743 // value as the comparison value when doing the cas to acquire the
744 // bias in the current epoch. In other words, we allow transfer of
745 // the bias from one thread to another directly in this situation.
746 xx = (intptr_t) rcvr->klass()->prototype_header() | (intptr_t) THREAD;
747 if (Atomic::cmpxchg_ptr((intptr_t)THREAD | (intptr_t) rcvr->klass()->prototype_header(),
748 (intptr_t*) rcvr->mark_addr(),
749 (intptr_t) mark) != (intptr_t) mark) {
750 CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception);
751 }
752 }
753 } else {
754 try_revoke_bias:
755 // The prototype mark in the klass doesn't have the bias bit set any
756 // more, indicating that objects of this data type are not supposed
757 // to be biased any more. We are going to try to reset the mark of
758 // this object to the prototype value and fall through to the
759 // CAS-based locking scheme. Note that if our CAS fails, it means
760 // that another thread raced us for the privilege of revoking the
761 // bias of this particular object, so it's okay to continue in the
762 // normal locking code.
763 //
764 xx = (intptr_t) rcvr->klass()->prototype_header() | (intptr_t) THREAD;
765 if (Atomic::cmpxchg_ptr(rcvr->klass()->prototype_header(),
766 (intptr_t*) rcvr->mark_addr(),
767 mark) == mark) {
768 // (*counters->revoked_lock_entry_count_addr())++;
769 success = false;
770 }
771 }
772 } 733 }
773 } else { 734 } else {
774 cas_label: 735 CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception);
775 success = false; 736 }
776 } 737 success = true;
777 } 738 } else {
778 if (!success) { 739 // Try to bias towards thread in case object is anonymously biased.
779 markOop displaced = rcvr->mark()->set_unlocked(); 740 markOop header = (markOop) ((uintptr_t) mark &
780 mon->lock()->set_displaced_header(displaced); 741 ((uintptr_t)markOopDesc::biased_lock_mask_in_place |
781 if (Atomic::cmpxchg_ptr(mon, rcvr->mark_addr(), displaced) != displaced) { 742 (uintptr_t)markOopDesc::age_mask_in_place | epoch_mask_in_place));
782 // Is it simple recursive case? 743 if (hash != markOopDesc::no_hash) {
783 if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) { 744 header = header->copy_set_hash(hash);
784 mon->lock()->set_displaced_header(NULL); 745 }
785 } else { 746 markOop new_header = (markOop) ((uintptr_t) header | thread_ident);
786 CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception); 747 // Debugging hint.
748 DEBUG_ONLY(mon->lock()->set_displaced_header((markOop) (uintptr_t) 0xdeaddead);)
749 if (Atomic::cmpxchg_ptr((void*)new_header, rcvr->mark_addr(), header) == header) {
750 if (PrintBiasedLockingStatistics) {
751 (* BiasedLocking::anonymously_biased_lock_entry_count_addr())++;
787 } 752 }
788 } 753 } else {
789 } 754 CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception);
755 }
756 success = true;
757 }
758 }
759
760 // Traditional lightweight locking.
761 if (!success) {
762 markOop displaced = rcvr->mark()->set_unlocked();
763 mon->lock()->set_displaced_header(displaced);
764 bool call_vm = UseHeavyMonitors;
765 if (call_vm || Atomic::cmpxchg_ptr(mon, rcvr->mark_addr(), displaced) != displaced) {
766 // Is it simple recursive case?
767 if (!call_vm && THREAD->is_lock_owned((address) displaced->clear_lock_bits())) {
768 mon->lock()->set_displaced_header(NULL);
769 } else {
770 CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception);
771 }
772 }
773 }
790 } 774 }
791 THREAD->clr_do_not_unlock(); 775 THREAD->clr_do_not_unlock();
792 776
793 // Notify jvmti 777 // Notify jvmti
794 #ifdef VM_JVMTI 778 #ifdef VM_JVMTI
879 // derefing's lockee ought to provoke implicit null check 863 // derefing's lockee ought to provoke implicit null check
880 // find a free monitor 864 // find a free monitor
881 BasicObjectLock* entry = (BasicObjectLock*) istate->stack_base(); 865 BasicObjectLock* entry = (BasicObjectLock*) istate->stack_base();
882 assert(entry->obj() == NULL, "Frame manager didn't allocate the monitor"); 866 assert(entry->obj() == NULL, "Frame manager didn't allocate the monitor");
883 entry->set_obj(lockee); 867 entry->set_obj(lockee);
884 868 bool success = false;
885 markOop displaced = lockee->mark()->set_unlocked(); 869 uintptr_t epoch_mask_in_place = (uintptr_t)markOopDesc::epoch_mask_in_place;
886 entry->lock()->set_displaced_header(displaced); 870
887 if (Atomic::cmpxchg_ptr(entry, lockee->mark_addr(), displaced) != displaced) { 871 markOop mark = lockee->mark();
888 // Is it simple recursive case? 872 intptr_t hash = (intptr_t) markOopDesc::no_hash;
889 if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) { 873 // implies UseBiasedLocking
890 entry->lock()->set_displaced_header(NULL); 874 if (mark->has_bias_pattern()) {
875 uintptr_t thread_ident;
876 uintptr_t anticipated_bias_locking_value;
877 thread_ident = (uintptr_t)istate->thread();
878 anticipated_bias_locking_value =
879 (((uintptr_t)lockee->klass()->prototype_header() | thread_ident) ^ (uintptr_t)mark) &
880 ~((uintptr_t) markOopDesc::age_mask_in_place);
881
882 if (anticipated_bias_locking_value == 0) {
883 // already biased towards this thread, nothing to do
884 if (PrintBiasedLockingStatistics) {
885 (* BiasedLocking::biased_lock_entry_count_addr())++;
886 }
887 success = true;
888 } else if ((anticipated_bias_locking_value & markOopDesc::biased_lock_mask_in_place) != 0) {
889 // try revoke bias
890 markOop header = lockee->klass()->prototype_header();
891 if (hash != markOopDesc::no_hash) {
892 header = header->copy_set_hash(hash);
893 }
894 if (Atomic::cmpxchg_ptr(header, lockee->mark_addr(), mark) == mark) {
895 if (PrintBiasedLockingStatistics) {
896 (*BiasedLocking::revoked_lock_entry_count_addr())++;
897 }
898 }
899 } else if ((anticipated_bias_locking_value & epoch_mask_in_place) !=0) {
900 // try rebias
901 markOop new_header = (markOop) ( (intptr_t) lockee->klass()->prototype_header() | thread_ident);
902 if (hash != markOopDesc::no_hash) {
903 new_header = new_header->copy_set_hash(hash);
904 }
905 if (Atomic::cmpxchg_ptr((void*)new_header, lockee->mark_addr(), mark) == mark) {
906 if (PrintBiasedLockingStatistics) {
907 (* BiasedLocking::rebiased_lock_entry_count_addr())++;
908 }
909 } else {
910 CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
911 }
912 success = true;
891 } else { 913 } else {
892 CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception); 914 // try to bias towards thread in case object is anonymously biased
915 markOop header = (markOop) ((uintptr_t) mark & ((uintptr_t)markOopDesc::biased_lock_mask_in_place |
916 (uintptr_t)markOopDesc::age_mask_in_place | epoch_mask_in_place));
917 if (hash != markOopDesc::no_hash) {
918 header = header->copy_set_hash(hash);
919 }
920 markOop new_header = (markOop) ((uintptr_t) header | thread_ident);
921 // debugging hint
922 DEBUG_ONLY(entry->lock()->set_displaced_header((markOop) (uintptr_t) 0xdeaddead);)
923 if (Atomic::cmpxchg_ptr((void*)new_header, lockee->mark_addr(), header) == header) {
924 if (PrintBiasedLockingStatistics) {
925 (* BiasedLocking::anonymously_biased_lock_entry_count_addr())++;
926 }
927 } else {
928 CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
929 }
930 success = true;
931 }
932 }
933
934 // traditional lightweight locking
935 if (!success) {
936 markOop displaced = lockee->mark()->set_unlocked();
937 entry->lock()->set_displaced_header(displaced);
938 bool call_vm = UseHeavyMonitors;
939 if (call_vm || Atomic::cmpxchg_ptr(entry, lockee->mark_addr(), displaced) != displaced) {
940 // Is it simple recursive case?
941 if (!call_vm && THREAD->is_lock_owned((address) displaced->clear_lock_bits())) {
942 entry->lock()->set_displaced_header(NULL);
943 } else {
944 CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
945 }
893 } 946 }
894 } 947 }
895 UPDATE_PC_AND_TOS(1, -1); 948 UPDATE_PC_AND_TOS(1, -1);
896 goto run; 949 goto run;
897 } 950 }
1698 else if (most_recent->obj() == lockee) break; 1751 else if (most_recent->obj() == lockee) break;
1699 most_recent++; 1752 most_recent++;
1700 } 1753 }
1701 if (entry != NULL) { 1754 if (entry != NULL) {
1702 entry->set_obj(lockee); 1755 entry->set_obj(lockee);
1703 markOop displaced = lockee->mark()->set_unlocked(); 1756 int success = false;
1704 entry->lock()->set_displaced_header(displaced); 1757 uintptr_t epoch_mask_in_place = (uintptr_t)markOopDesc::epoch_mask_in_place;
1705 if (Atomic::cmpxchg_ptr(entry, lockee->mark_addr(), displaced) != displaced) { 1758
1706 // Is it simple recursive case? 1759 markOop mark = lockee->mark();
1707 if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) { 1760 intptr_t hash = (intptr_t) markOopDesc::no_hash;
1708 entry->lock()->set_displaced_header(NULL); 1761 // implies UseBiasedLocking
1709 } else { 1762 if (mark->has_bias_pattern()) {
1710 CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception); 1763 uintptr_t thread_ident;
1764 uintptr_t anticipated_bias_locking_value;
1765 thread_ident = (uintptr_t)istate->thread();
1766 anticipated_bias_locking_value =
1767 (((uintptr_t)lockee->klass()->prototype_header() | thread_ident) ^ (uintptr_t)mark) &
1768 ~((uintptr_t) markOopDesc::age_mask_in_place);
1769
1770 if (anticipated_bias_locking_value == 0) {
1771 // already biased towards this thread, nothing to do
1772 if (PrintBiasedLockingStatistics) {
1773 (* BiasedLocking::biased_lock_entry_count_addr())++;
1774 }
1775 success = true;
1776 }
1777 else if ((anticipated_bias_locking_value & markOopDesc::biased_lock_mask_in_place) != 0) {
1778 // try revoke bias
1779 markOop header = lockee->klass()->prototype_header();
1780 if (hash != markOopDesc::no_hash) {
1781 header = header->copy_set_hash(hash);
1782 }
1783 if (Atomic::cmpxchg_ptr(header, lockee->mark_addr(), mark) == mark) {
1784 if (PrintBiasedLockingStatistics)
1785 (*BiasedLocking::revoked_lock_entry_count_addr())++;
1786 }
1787 }
1788 else if ((anticipated_bias_locking_value & epoch_mask_in_place) !=0) {
1789 // try rebias
1790 markOop new_header = (markOop) ( (intptr_t) lockee->klass()->prototype_header() | thread_ident);
1791 if (hash != markOopDesc::no_hash) {
1792 new_header = new_header->copy_set_hash(hash);
1793 }
1794 if (Atomic::cmpxchg_ptr((void*)new_header, lockee->mark_addr(), mark) == mark) {
1795 if (PrintBiasedLockingStatistics)
1796 (* BiasedLocking::rebiased_lock_entry_count_addr())++;
1797 }
1798 else {
1799 CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
1800 }
1801 success = true;
1802 }
1803 else {
1804 // try to bias towards thread in case object is anonymously biased
1805 markOop header = (markOop) ((uintptr_t) mark & ((uintptr_t)markOopDesc::biased_lock_mask_in_place |
1806 (uintptr_t)markOopDesc::age_mask_in_place |
1807 epoch_mask_in_place));
1808 if (hash != markOopDesc::no_hash) {
1809 header = header->copy_set_hash(hash);
1810 }
1811 markOop new_header = (markOop) ((uintptr_t) header | thread_ident);
1812 // debugging hint
1813 DEBUG_ONLY(entry->lock()->set_displaced_header((markOop) (uintptr_t) 0xdeaddead);)
1814 if (Atomic::cmpxchg_ptr((void*)new_header, lockee->mark_addr(), header) == header) {
1815 if (PrintBiasedLockingStatistics)
1816 (* BiasedLocking::anonymously_biased_lock_entry_count_addr())++;
1817 }
1818 else {
1819 CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
1820 }
1821 success = true;
1822 }
1823 }
1824
1825 // traditional lightweight locking
1826 if (!success) {
1827 markOop displaced = lockee->mark()->set_unlocked();
1828 entry->lock()->set_displaced_header(displaced);
1829 bool call_vm = UseHeavyMonitors;
1830 if (call_vm || Atomic::cmpxchg_ptr(entry, lockee->mark_addr(), displaced) != displaced) {
1831 // Is it simple recursive case?
1832 if (!call_vm && THREAD->is_lock_owned((address) displaced->clear_lock_bits())) {
1833 entry->lock()->set_displaced_header(NULL);
1834 } else {
1835 CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
1836 }
1711 } 1837 }
1712 } 1838 }
1713 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); 1839 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
1714 } else { 1840 } else {
1715 istate->set_msg(more_monitors); 1841 istate->set_msg(more_monitors);
1727 while (most_recent != limit ) { 1853 while (most_recent != limit ) {
1728 if ((most_recent)->obj() == lockee) { 1854 if ((most_recent)->obj() == lockee) {
1729 BasicLock* lock = most_recent->lock(); 1855 BasicLock* lock = most_recent->lock();
1730 markOop header = lock->displaced_header(); 1856 markOop header = lock->displaced_header();
1731 most_recent->set_obj(NULL); 1857 most_recent->set_obj(NULL);
1732 // If it isn't recursive we either must swap old header or call the runtime 1858 if (!lockee->mark()->has_bias_pattern()) {
1733 if (header != NULL) { 1859 bool call_vm = UseHeavyMonitors;
1734 if (Atomic::cmpxchg_ptr(header, lockee->mark_addr(), lock) != lock) { 1860 // If it isn't recursive we either must swap old header or call the runtime
1735 // restore object for the slow case 1861 if (header != NULL || call_vm) {
1736 most_recent->set_obj(lockee); 1862 if (call_vm || Atomic::cmpxchg_ptr(header, lockee->mark_addr(), lock) != lock) {
1737 CALL_VM(InterpreterRuntime::monitorexit(THREAD, most_recent), handle_exception); 1863 // restore object for the slow case
1864 most_recent->set_obj(lockee);
1865 CALL_VM(InterpreterRuntime::monitorexit(THREAD, most_recent), handle_exception);
1866 }
1738 } 1867 }
1739 } 1868 }
1740 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); 1869 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
1741 } 1870 }
1742 most_recent++; 1871 most_recent++;
2676 oop lockee = end->obj(); 2805 oop lockee = end->obj();
2677 if (lockee != NULL) { 2806 if (lockee != NULL) {
2678 BasicLock* lock = end->lock(); 2807 BasicLock* lock = end->lock();
2679 markOop header = lock->displaced_header(); 2808 markOop header = lock->displaced_header();
2680 end->set_obj(NULL); 2809 end->set_obj(NULL);
2681 // If it isn't recursive we either must swap old header or call the runtime 2810
2682 if (header != NULL) { 2811 if (!lockee->mark()->has_bias_pattern()) {
2683 if (Atomic::cmpxchg_ptr(header, lockee->mark_addr(), lock) != lock) { 2812 // If it isn't recursive we either must swap old header or call the runtime
2684 // restore object for the slow case 2813 if (header != NULL) {
2685 end->set_obj(lockee); 2814 if (Atomic::cmpxchg_ptr(header, lockee->mark_addr(), lock) != lock) {
2686 { 2815 // restore object for the slow case
2687 // Prevent any HandleMarkCleaner from freeing our live handles 2816 end->set_obj(lockee);
2688 HandleMark __hm(THREAD); 2817 {
2689 CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, end)); 2818 // Prevent any HandleMarkCleaner from freeing our live handles
2819 HandleMark __hm(THREAD);
2820 CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, end));
2821 }
2690 } 2822 }
2691 } 2823 }
2692 } 2824 }
2693 // One error is plenty 2825 // One error is plenty
2694 if (illegal_state_oop() == NULL && !suppress_error) { 2826 if (illegal_state_oop() == NULL && !suppress_error) {
2733 if (!suppress_error) { 2865 if (!suppress_error) {
2734 VM_JAVA_ERROR_NO_JUMP(vmSymbols::java_lang_NullPointerException(), ""); 2866 VM_JAVA_ERROR_NO_JUMP(vmSymbols::java_lang_NullPointerException(), "");
2735 illegal_state_oop = THREAD->pending_exception(); 2867 illegal_state_oop = THREAD->pending_exception();
2736 THREAD->clear_pending_exception(); 2868 THREAD->clear_pending_exception();
2737 } 2869 }
2870 } else if (UseHeavyMonitors) {
2871 {
2872 // Prevent any HandleMarkCleaner from freeing our live handles.
2873 HandleMark __hm(THREAD);
2874 CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, base));
2875 }
2876 if (THREAD->has_pending_exception()) {
2877 if (!suppress_error) illegal_state_oop = THREAD->pending_exception();
2878 THREAD->clear_pending_exception();
2879 }
2738 } else { 2880 } else {
2739 BasicLock* lock = base->lock(); 2881 BasicLock* lock = base->lock();
2740 markOop header = lock->displaced_header(); 2882 markOop header = lock->displaced_header();
2741 base->set_obj(NULL); 2883 base->set_obj(NULL);
2742 // If it isn't recursive we either must swap old header or call the runtime 2884
2743 if (header != NULL) { 2885 if (!rcvr->mark()->has_bias_pattern()) {
2744 if (Atomic::cmpxchg_ptr(header, rcvr->mark_addr(), lock) != lock) { 2886 base->set_obj(NULL);
2745 // restore object for the slow case 2887 // If it isn't recursive we either must swap old header or call the runtime
2746 base->set_obj(rcvr); 2888 if (header != NULL) {
2747 { 2889 if (Atomic::cmpxchg_ptr(header, rcvr->mark_addr(), lock) != lock) {
2748 // Prevent any HandleMarkCleaner from freeing our live handles 2890 // restore object for the slow case
2749 HandleMark __hm(THREAD); 2891 base->set_obj(rcvr);
2750 CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, base)); 2892 {
2751 } 2893 // Prevent any HandleMarkCleaner from freeing our live handles
2752 if (THREAD->has_pending_exception()) { 2894 HandleMark __hm(THREAD);
2753 if (!suppress_error) illegal_state_oop = THREAD->pending_exception(); 2895 CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, base));
2754 THREAD->clear_pending_exception(); 2896 }
2897 if (THREAD->has_pending_exception()) {
2898 if (!suppress_error) illegal_state_oop = THREAD->pending_exception();
2899 THREAD->clear_pending_exception();
2900 }
2755 } 2901 }
2756 } 2902 }
2757 } 2903 }
2758 } 2904 }
2759 } 2905 }
2760 } 2906 }
2761 } 2907 }
2908 // Clear the do_not_unlock flag now.
2909 THREAD->clr_do_not_unlock();
2762 2910
2763 // 2911 //
2764 // Notify jvmti/jvmdi 2912 // Notify jvmti/jvmdi
2765 // 2913 //
2766 // NOTE: we do not notify a method_exit if we have a pending exception, 2914 // NOTE: we do not notify a method_exit if we have a pending exception,
3128 #endif // !ZERO 3276 #endif // !ZERO
3129 tty->print_cr("self_link: " INTPTR_FORMAT, (uintptr_t) this->_self_link); 3277 tty->print_cr("self_link: " INTPTR_FORMAT, (uintptr_t) this->_self_link);
3130 } 3278 }
3131 3279
3132 extern "C" { 3280 extern "C" {
3133 void PI(uintptr_t arg) { 3281 void PI(uintptr_t arg) {
3134 ((BytecodeInterpreter*)arg)->print(); 3282 ((BytecodeInterpreter*)arg)->print();
3135 } 3283 }
3136 } 3284 }
3137 #endif // PRODUCT 3285 #endif // PRODUCT
3138 3286
3139 #endif // JVMTI 3287 #endif // JVMTI
3140 #endif // CC_INTERP 3288 #endif // CC_INTERP