< prev index next >

src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp

Print this page

   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);
< prev index next >