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); |
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, |