Mercurial > hg > graal-compiler
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 |