< prev index next >

src/hotspot/cpu/x86/sharedRuntime_x86_64.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  *

2172 
2173       // Hmm should this move to the slow path code area???
2174 
2175       // Test if the oopMark is an obvious stack pointer, i.e.,
2176       //  1) (mark & 3) == 0, and
2177       //  2) rsp <= mark < mark + os::pagesize()
2178       // These 3 tests can be done by evaluating the following
2179       // expression: ((mark - rsp) & (3 - os::vm_page_size())),
2180       // assuming both stack pointer and pagesize have their
2181       // least significant 2 bits clear.
2182       // NOTE: the oopMark is in swap_reg %rax as the result of cmpxchg
2183 
2184       __ subptr(swap_reg, rsp);
2185       __ andptr(swap_reg, 3 - (int)os::vm_page_size());
2186 
2187       // Save the test result, for recursive case, the result is zero
2188       __ movptr(Address(lock_reg, mark_word_offset), swap_reg);
2189       __ jcc(Assembler::notEqual, slow_path_lock);
2190     } else {
2191       assert(LockingMode == LM_LIGHTWEIGHT, "must be");
2192       // Load object header
2193       __ movptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
2194       __ lightweight_lock(obj_reg, swap_reg, r15_thread, rscratch1, slow_path_lock);
2195     }
2196     __ bind(count_mon);
2197     __ inc_held_monitor_count();
2198 
2199     // Slow path will re-enter here
2200     __ bind(lock_done);
2201   }
2202 
2203   // Finally just about ready to make the JNI call
2204 
2205   // get JNIEnv* which is first argument to native
2206   __ lea(c_rarg0, Address(r15_thread, in_bytes(JavaThread::jni_environment_offset())));
2207 
2208   // Now set thread in native
2209   __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native);
2210 
2211   __ call(RuntimeAddress(native_func));
2212 
2213   // Verify or restore cpu control state after JNI call

2316     // Must save rax if it is live now because cmpxchg must use it
2317     if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) {
2318       save_native_result(masm, ret_type, stack_slots);
2319     }
2320 
2321     if (LockingMode == LM_MONITOR) {
2322       __ jmp(slow_path_unlock);
2323     } else if (LockingMode == LM_LEGACY) {
2324       // get address of the stack lock
2325       __ lea(rax, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size));
2326       //  get old displaced header
2327       __ movptr(old_hdr, Address(rax, 0));
2328 
2329       // Atomic swap old header if oop still contains the stack lock
2330       __ lock();
2331       __ cmpxchgptr(old_hdr, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
2332       __ jcc(Assembler::notEqual, slow_path_unlock);
2333       __ dec_held_monitor_count();
2334     } else {
2335       assert(LockingMode == LM_LIGHTWEIGHT, "must be");
2336       __ movptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
2337       __ andptr(swap_reg, ~(int32_t)markWord::lock_mask_in_place);
2338       __ lightweight_unlock(obj_reg, swap_reg, lock_reg, slow_path_unlock);
2339       __ dec_held_monitor_count();
2340     }
2341 
2342     // slow path re-enters here
2343     __ bind(unlock_done);
2344     if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) {
2345       restore_native_result(masm, ret_type, stack_slots);
2346     }
2347 
2348     __ bind(fast_done);
2349   }
2350   {
2351     SkipIfEqual skip(masm, &DTraceMethodProbes, false, rscratch1);
2352     save_native_result(masm, ret_type, stack_slots);
2353     __ mov_metadata(c_rarg1, method());
2354     __ call_VM_leaf(
2355          CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit),
2356          r15_thread, c_rarg1);
2357     restore_native_result(masm, ret_type, stack_slots);
2358   }

   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  *

2172 
2173       // Hmm should this move to the slow path code area???
2174 
2175       // Test if the oopMark is an obvious stack pointer, i.e.,
2176       //  1) (mark & 3) == 0, and
2177       //  2) rsp <= mark < mark + os::pagesize()
2178       // These 3 tests can be done by evaluating the following
2179       // expression: ((mark - rsp) & (3 - os::vm_page_size())),
2180       // assuming both stack pointer and pagesize have their
2181       // least significant 2 bits clear.
2182       // NOTE: the oopMark is in swap_reg %rax as the result of cmpxchg
2183 
2184       __ subptr(swap_reg, rsp);
2185       __ andptr(swap_reg, 3 - (int)os::vm_page_size());
2186 
2187       // Save the test result, for recursive case, the result is zero
2188       __ movptr(Address(lock_reg, mark_word_offset), swap_reg);
2189       __ jcc(Assembler::notEqual, slow_path_lock);
2190     } else {
2191       assert(LockingMode == LM_LIGHTWEIGHT, "must be");


2192       __ lightweight_lock(obj_reg, swap_reg, r15_thread, rscratch1, slow_path_lock);
2193     }
2194     __ bind(count_mon);
2195     __ inc_held_monitor_count();
2196 
2197     // Slow path will re-enter here
2198     __ bind(lock_done);
2199   }
2200 
2201   // Finally just about ready to make the JNI call
2202 
2203   // get JNIEnv* which is first argument to native
2204   __ lea(c_rarg0, Address(r15_thread, in_bytes(JavaThread::jni_environment_offset())));
2205 
2206   // Now set thread in native
2207   __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native);
2208 
2209   __ call(RuntimeAddress(native_func));
2210 
2211   // Verify or restore cpu control state after JNI call

2314     // Must save rax if it is live now because cmpxchg must use it
2315     if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) {
2316       save_native_result(masm, ret_type, stack_slots);
2317     }
2318 
2319     if (LockingMode == LM_MONITOR) {
2320       __ jmp(slow_path_unlock);
2321     } else if (LockingMode == LM_LEGACY) {
2322       // get address of the stack lock
2323       __ lea(rax, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size));
2324       //  get old displaced header
2325       __ movptr(old_hdr, Address(rax, 0));
2326 
2327       // Atomic swap old header if oop still contains the stack lock
2328       __ lock();
2329       __ cmpxchgptr(old_hdr, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
2330       __ jcc(Assembler::notEqual, slow_path_unlock);
2331       __ dec_held_monitor_count();
2332     } else {
2333       assert(LockingMode == LM_LIGHTWEIGHT, "must be");
2334       __ lightweight_unlock(obj_reg, swap_reg, r15_thread, lock_reg, slow_path_unlock);


2335       __ dec_held_monitor_count();
2336     }
2337 
2338     // slow path re-enters here
2339     __ bind(unlock_done);
2340     if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) {
2341       restore_native_result(masm, ret_type, stack_slots);
2342     }
2343 
2344     __ bind(fast_done);
2345   }
2346   {
2347     SkipIfEqual skip(masm, &DTraceMethodProbes, false, rscratch1);
2348     save_native_result(masm, ret_type, stack_slots);
2349     __ mov_metadata(c_rarg1, method());
2350     __ call_VM_leaf(
2351          CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit),
2352          r15_thread, c_rarg1);
2353     restore_native_result(masm, ret_type, stack_slots);
2354   }
< prev index next >