1 /*
2 * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
1698 __ cmpxchgptr(lock_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1699 __ jcc(Assembler::equal, count_mon);
1700
1701 // Test if the oopMark is an obvious stack pointer, i.e.,
1702 // 1) (mark & 3) == 0, and
1703 // 2) rsp <= mark < mark + os::pagesize()
1704 // These 3 tests can be done by evaluating the following
1705 // expression: ((mark - rsp) & (3 - os::vm_page_size())),
1706 // assuming both stack pointer and pagesize have their
1707 // least significant 2 bits clear.
1708 // NOTE: the oopMark is in swap_reg %rax, as the result of cmpxchg
1709
1710 __ subptr(swap_reg, rsp);
1711 __ andptr(swap_reg, 3 - (int)os::vm_page_size());
1712
1713 // Save the test result, for recursive case, the result is zero
1714 __ movptr(Address(lock_reg, mark_word_offset), swap_reg);
1715 __ jcc(Assembler::notEqual, slow_path_lock);
1716 } else {
1717 assert(LockingMode == LM_LIGHTWEIGHT, "must be");
1718 // Load object header
1719 __ movptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1720 __ lightweight_lock(obj_reg, swap_reg, thread, lock_reg, slow_path_lock);
1721 }
1722 __ bind(count_mon);
1723 __ inc_held_monitor_count();
1724
1725 // Slow path will re-enter here
1726 __ bind(lock_done);
1727 }
1728
1729
1730 // Finally just about ready to make the JNI call
1731
1732 // get JNIEnv* which is first argument to native
1733 __ lea(rdx, Address(thread, in_bytes(JavaThread::jni_environment_offset())));
1734 __ movptr(Address(rsp, 0), rdx);
1735
1736 // Now set thread in native
1737 __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native);
1738
1739 __ call(RuntimeAddress(native_func));
1857 }
1858
1859 if (LockingMode == LM_MONITOR) {
1860 __ jmp(slow_path_unlock);
1861 } else if (LockingMode == LM_LEGACY) {
1862 // get old displaced header
1863 __ movptr(rbx, Address(rbp, lock_slot_rbp_offset));
1864
1865 // get address of the stack lock
1866 __ lea(rax, Address(rbp, lock_slot_rbp_offset));
1867
1868 // Atomic swap old header if oop still contains the stack lock
1869 // src -> dest iff dest == rax, else rax, <- dest
1870 // *obj_reg = rbx, iff *obj_reg == rax, else rax, = *(obj_reg)
1871 __ lock();
1872 __ cmpxchgptr(rbx, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1873 __ jcc(Assembler::notEqual, slow_path_unlock);
1874 __ dec_held_monitor_count();
1875 } else {
1876 assert(LockingMode == LM_LIGHTWEIGHT, "must be");
1877 __ movptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1878 __ andptr(swap_reg, ~(int32_t)markWord::lock_mask_in_place);
1879 __ lightweight_unlock(obj_reg, swap_reg, lock_reg, slow_path_unlock);
1880 __ dec_held_monitor_count();
1881 }
1882
1883 // slow path re-enters here
1884 __ bind(unlock_done);
1885 if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) {
1886 restore_native_result(masm, ret_type, stack_slots);
1887 }
1888
1889 __ bind(fast_done);
1890 }
1891
1892 {
1893 SkipIfEqual skip_if(masm, &DTraceMethodProbes, 0, noreg);
1894 // Tell dtrace about this method exit
1895 save_native_result(masm, ret_type, stack_slots);
1896 __ mov_metadata(rax, method());
1897 __ call_VM_leaf(
1898 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit),
1899 thread, rax);
|
1 /*
2 * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
1698 __ cmpxchgptr(lock_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1699 __ jcc(Assembler::equal, count_mon);
1700
1701 // Test if the oopMark is an obvious stack pointer, i.e.,
1702 // 1) (mark & 3) == 0, and
1703 // 2) rsp <= mark < mark + os::pagesize()
1704 // These 3 tests can be done by evaluating the following
1705 // expression: ((mark - rsp) & (3 - os::vm_page_size())),
1706 // assuming both stack pointer and pagesize have their
1707 // least significant 2 bits clear.
1708 // NOTE: the oopMark is in swap_reg %rax, as the result of cmpxchg
1709
1710 __ subptr(swap_reg, rsp);
1711 __ andptr(swap_reg, 3 - (int)os::vm_page_size());
1712
1713 // Save the test result, for recursive case, the result is zero
1714 __ movptr(Address(lock_reg, mark_word_offset), swap_reg);
1715 __ jcc(Assembler::notEqual, slow_path_lock);
1716 } else {
1717 assert(LockingMode == LM_LIGHTWEIGHT, "must be");
1718 __ lightweight_lock(obj_reg, swap_reg, thread, lock_reg, slow_path_lock);
1719 }
1720 __ bind(count_mon);
1721 __ inc_held_monitor_count();
1722
1723 // Slow path will re-enter here
1724 __ bind(lock_done);
1725 }
1726
1727
1728 // Finally just about ready to make the JNI call
1729
1730 // get JNIEnv* which is first argument to native
1731 __ lea(rdx, Address(thread, in_bytes(JavaThread::jni_environment_offset())));
1732 __ movptr(Address(rsp, 0), rdx);
1733
1734 // Now set thread in native
1735 __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native);
1736
1737 __ call(RuntimeAddress(native_func));
1855 }
1856
1857 if (LockingMode == LM_MONITOR) {
1858 __ jmp(slow_path_unlock);
1859 } else if (LockingMode == LM_LEGACY) {
1860 // get old displaced header
1861 __ movptr(rbx, Address(rbp, lock_slot_rbp_offset));
1862
1863 // get address of the stack lock
1864 __ lea(rax, Address(rbp, lock_slot_rbp_offset));
1865
1866 // Atomic swap old header if oop still contains the stack lock
1867 // src -> dest iff dest == rax, else rax, <- dest
1868 // *obj_reg = rbx, iff *obj_reg == rax, else rax, = *(obj_reg)
1869 __ lock();
1870 __ cmpxchgptr(rbx, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1871 __ jcc(Assembler::notEqual, slow_path_unlock);
1872 __ dec_held_monitor_count();
1873 } else {
1874 assert(LockingMode == LM_LIGHTWEIGHT, "must be");
1875 __ lightweight_unlock(obj_reg, swap_reg, thread, lock_reg, slow_path_unlock);
1876 __ dec_held_monitor_count();
1877 }
1878
1879 // slow path re-enters here
1880 __ bind(unlock_done);
1881 if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) {
1882 restore_native_result(masm, ret_type, stack_slots);
1883 }
1884
1885 __ bind(fast_done);
1886 }
1887
1888 {
1889 SkipIfEqual skip_if(masm, &DTraceMethodProbes, 0, noreg);
1890 // Tell dtrace about this method exit
1891 save_native_result(masm, ret_type, stack_slots);
1892 __ mov_metadata(rax, method());
1893 __ call_VM_leaf(
1894 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit),
1895 thread, rax);
|