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 }
|