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 *
1697 __ cmpxchgptr(lock_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1698 __ jcc(Assembler::equal, count_mon);
1699
1700 // Test if the oopMark is an obvious stack pointer, i.e.,
1701 // 1) (mark & 3) == 0, and
1702 // 2) rsp <= mark < mark + os::pagesize()
1703 // These 3 tests can be done by evaluating the following
1704 // expression: ((mark - rsp) & (3 - os::vm_page_size())),
1705 // assuming both stack pointer and pagesize have their
1706 // least significant 2 bits clear.
1707 // NOTE: the oopMark is in swap_reg %rax, as the result of cmpxchg
1708
1709 __ subptr(swap_reg, rsp);
1710 __ andptr(swap_reg, 3 - (int)os::vm_page_size());
1711
1712 // Save the test result, for recursive case, the result is zero
1713 __ movptr(Address(lock_reg, mark_word_offset), swap_reg);
1714 __ jcc(Assembler::notEqual, slow_path_lock);
1715 } else {
1716 assert(LockingMode == LM_LIGHTWEIGHT, "must be");
1717 // Load object header
1718 __ movptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1719 __ lightweight_lock(obj_reg, swap_reg, thread, lock_reg, slow_path_lock);
1720 }
1721 __ bind(count_mon);
1722 __ inc_held_monitor_count();
1723
1724 // Slow path will re-enter here
1725 __ bind(lock_done);
1726 }
1727
1728
1729 // Finally just about ready to make the JNI call
1730
1731 // get JNIEnv* which is first argument to native
1732 __ lea(rdx, Address(thread, in_bytes(JavaThread::jni_environment_offset())));
1733 __ movptr(Address(rsp, 0), rdx);
1734
1735 // Now set thread in native
1736 __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native);
1737
1738 __ call(RuntimeAddress(native_func));
1856 }
1857
1858 if (LockingMode == LM_MONITOR) {
1859 __ jmp(slow_path_unlock);
1860 } else if (LockingMode == LM_LEGACY) {
1861 // get old displaced header
1862 __ movptr(rbx, Address(rbp, lock_slot_rbp_offset));
1863
1864 // get address of the stack lock
1865 __ lea(rax, Address(rbp, lock_slot_rbp_offset));
1866
1867 // Atomic swap old header if oop still contains the stack lock
1868 // src -> dest iff dest == rax, else rax, <- dest
1869 // *obj_reg = rbx, iff *obj_reg == rax, else rax, = *(obj_reg)
1870 __ lock();
1871 __ cmpxchgptr(rbx, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1872 __ jcc(Assembler::notEqual, slow_path_unlock);
1873 __ dec_held_monitor_count();
1874 } else {
1875 assert(LockingMode == LM_LIGHTWEIGHT, "must be");
1876 __ movptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1877 __ andptr(swap_reg, ~(int32_t)markWord::lock_mask_in_place);
1878 __ lightweight_unlock(obj_reg, swap_reg, lock_reg, slow_path_unlock);
1879 __ dec_held_monitor_count();
1880 }
1881
1882 // slow path re-enters here
1883 __ bind(unlock_done);
1884 if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) {
1885 restore_native_result(masm, ret_type, stack_slots);
1886 }
1887
1888 __ bind(fast_done);
1889 }
1890
1891 {
1892 SkipIfEqual skip_if(masm, &DTraceMethodProbes, 0, noreg);
1893 // Tell dtrace about this method exit
1894 save_native_result(masm, ret_type, stack_slots);
1895 __ mov_metadata(rax, method());
1896 __ call_VM_leaf(
1897 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit),
1898 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 *
1697 __ cmpxchgptr(lock_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1698 __ jcc(Assembler::equal, count_mon);
1699
1700 // Test if the oopMark is an obvious stack pointer, i.e.,
1701 // 1) (mark & 3) == 0, and
1702 // 2) rsp <= mark < mark + os::pagesize()
1703 // These 3 tests can be done by evaluating the following
1704 // expression: ((mark - rsp) & (3 - os::vm_page_size())),
1705 // assuming both stack pointer and pagesize have their
1706 // least significant 2 bits clear.
1707 // NOTE: the oopMark is in swap_reg %rax, as the result of cmpxchg
1708
1709 __ subptr(swap_reg, rsp);
1710 __ andptr(swap_reg, 3 - (int)os::vm_page_size());
1711
1712 // Save the test result, for recursive case, the result is zero
1713 __ movptr(Address(lock_reg, mark_word_offset), swap_reg);
1714 __ jcc(Assembler::notEqual, slow_path_lock);
1715 } else {
1716 assert(LockingMode == LM_LIGHTWEIGHT, "must be");
1717 __ lightweight_lock(obj_reg, swap_reg, thread, lock_reg, slow_path_lock);
1718 }
1719 __ bind(count_mon);
1720 __ inc_held_monitor_count();
1721
1722 // Slow path will re-enter here
1723 __ bind(lock_done);
1724 }
1725
1726
1727 // Finally just about ready to make the JNI call
1728
1729 // get JNIEnv* which is first argument to native
1730 __ lea(rdx, Address(thread, in_bytes(JavaThread::jni_environment_offset())));
1731 __ movptr(Address(rsp, 0), rdx);
1732
1733 // Now set thread in native
1734 __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native);
1735
1736 __ call(RuntimeAddress(native_func));
1854 }
1855
1856 if (LockingMode == LM_MONITOR) {
1857 __ jmp(slow_path_unlock);
1858 } else if (LockingMode == LM_LEGACY) {
1859 // get old displaced header
1860 __ movptr(rbx, Address(rbp, lock_slot_rbp_offset));
1861
1862 // get address of the stack lock
1863 __ lea(rax, Address(rbp, lock_slot_rbp_offset));
1864
1865 // Atomic swap old header if oop still contains the stack lock
1866 // src -> dest iff dest == rax, else rax, <- dest
1867 // *obj_reg = rbx, iff *obj_reg == rax, else rax, = *(obj_reg)
1868 __ lock();
1869 __ cmpxchgptr(rbx, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1870 __ jcc(Assembler::notEqual, slow_path_unlock);
1871 __ dec_held_monitor_count();
1872 } else {
1873 assert(LockingMode == LM_LIGHTWEIGHT, "must be");
1874 __ lightweight_unlock(obj_reg, swap_reg, thread, lock_reg, slow_path_unlock);
1875 __ dec_held_monitor_count();
1876 }
1877
1878 // slow path re-enters here
1879 __ bind(unlock_done);
1880 if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) {
1881 restore_native_result(masm, ret_type, stack_slots);
1882 }
1883
1884 __ bind(fast_done);
1885 }
1886
1887 {
1888 SkipIfEqual skip_if(masm, &DTraceMethodProbes, 0, noreg);
1889 // Tell dtrace about this method exit
1890 save_native_result(masm, ret_type, stack_slots);
1891 __ mov_metadata(rax, method());
1892 __ call_VM_leaf(
1893 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit),
1894 thread, rax);
|