Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8253540: InterpreterRuntime::monitorexit should be a JRT_LEAF function
Reviewed-by: rehn, mdoerr, dcubed, pchilanomate
  • Loading branch information
coleenp committed Sep 28, 2020
1 parent 0054c15 commit 77a0f3999afa322b64643afd4a161164440af975
@@ -812,9 +812,7 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg)
assert(lock_reg == c_rarg1, "The argument is only for looks. It must be rarg1");

if (UseHeavyMonitors) {
call_VM(noreg,
CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit),
lock_reg);
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
} else {
Label done;

@@ -850,9 +848,7 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg)

// Call the runtime routine for slow case.
str(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes())); // restore obj
call_VM(noreg,
CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit),
lock_reg);
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);

bind(done);

@@ -990,7 +990,7 @@ void InterpreterMacroAssembler::unlock_object(Register Rlock) {
assert(Rlock == R1, "the second argument");

if (UseHeavyMonitors) {
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), Rlock);
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), Rlock);
} else {
Label done, slow_case;

@@ -1031,7 +1031,7 @@ void InterpreterMacroAssembler::unlock_object(Register Rlock) {

// Call the runtime routine for slow case.
str(Robj, Address(Rlock, obj_offset)); // restore obj
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), Rlock);
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), Rlock);

bind(done);
}
@@ -997,8 +997,7 @@ void InterpreterMacroAssembler::lock_object(Register monitor, Register object) {
// Throw IllegalMonitorException if object is not locked by current thread.
void InterpreterMacroAssembler::unlock_object(Register monitor, bool check_for_exceptions) {
if (UseHeavyMonitors) {
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit),
monitor, check_for_exceptions);
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), monitor);
} else {

// template code:
@@ -1011,7 +1010,7 @@ void InterpreterMacroAssembler::unlock_object(Register monitor, bool check_for_e
// monitor->set_obj(NULL);
// } else {
// // Slow path.
// InterpreterRuntime::monitorexit(THREAD, monitor);
// InterpreterRuntime::monitorexit(monitor);
// }

const Register object = R7_ARG5;
@@ -1065,13 +1064,12 @@ void InterpreterMacroAssembler::unlock_object(Register monitor, bool check_for_e

// } else {
// // Slow path.
// InterpreterRuntime::monitorexit(THREAD, monitor);
// InterpreterRuntime::monitorexit(monitor);

// The lock has been converted into a heavy lock and hence
// we need to get into the slow case.
bind(slow_case);
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit),
monitor, check_for_exceptions);
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), monitor);
// }

Label done;
@@ -1080,7 +1080,7 @@ void InterpreterMacroAssembler::lock_object(Register monitor, Register object) {
void InterpreterMacroAssembler::unlock_object(Register monitor, Register object) {

if (UseHeavyMonitors) {
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), monitor);
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), monitor);
return;
}

@@ -1095,7 +1095,7 @@ void InterpreterMacroAssembler::unlock_object(Register monitor, Register object)
// monitor->set_obj(NULL);
// } else {
// // Slow path.
// InterpreterRuntime::monitorexit(THREAD, monitor);
// InterpreterRuntime::monitorexit(monitor);
// }

const Register displaced_header = Z_ARG4;
@@ -1149,12 +1149,12 @@ void InterpreterMacroAssembler::unlock_object(Register monitor, Register object)

// } else {
// // Slow path.
// InterpreterRuntime::monitorexit(THREAD, monitor);
// InterpreterRuntime::monitorexit(monitor);

// The lock has been converted into a heavy lock and hence
// we need to get into the slow case.
z_stg(object, obj_entry); // Restore object entry, has been cleared above.
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), monitor);
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), monitor);

// }

@@ -1281,9 +1281,7 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg) {
"The argument is only for looks. It must be c_rarg1");

if (UseHeavyMonitors) {
call_VM(noreg,
CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit),
lock_reg);
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
} else {
Label done;

@@ -1324,12 +1322,10 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg) {
// zero for simple unlock of a stack-lock case
jcc(Assembler::zero, done);


// Call the runtime routine for slow case.
movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()),
obj_reg); // restore obj
call_VM(noreg,
CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit),
lock_reg);
movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), obj_reg); // restore obj
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);

bind(done);

@@ -459,10 +459,8 @@ int ZeroInterpreter::native_entry(Method* method, intptr_t UNUSED, TRAPS) {
if (header.to_pointer() != NULL) {
markWord old_header = markWord::encode(lock);
if (rcvr->cas_set_mark(header, old_header) != old_header) {
monitor->set_obj(rcvr); {
HandleMark hm(thread);
CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(thread, monitor));
}
monitor->set_obj(rcvr);
InterpreterRuntime::monitorexit(monitor);
}
}
}
@@ -733,24 +733,21 @@ JRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorenter(JavaThread* thread, Ba
JRT_END


//%note monitor_1
JRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorexit(JavaThread* thread, BasicObjectLock* elem))
#ifdef ASSERT
thread->last_frame().interpreter_frame_verify_monitor(elem);
#endif
Handle h_obj(thread, elem->obj());
assert(Universe::heap()->is_in_or_null(h_obj()),
"must be NULL or an object");
if (elem == NULL || h_obj()->is_unlocked()) {
THROW(vmSymbols::java_lang_IllegalMonitorStateException());
JRT_LEAF(void, InterpreterRuntime::monitorexit(BasicObjectLock* elem))
oop obj = elem->obj();
assert(Universe::heap()->is_in(obj), "must be an object");
// The object could become unlocked through a JNI call, which we have no other checks for.
// Give a fatal message if CheckJNICalls. Otherwise we ignore it.
if (obj->is_unlocked()) {
if (CheckJNICalls) {
fatal("Object has been unlocked by JNI");
}
return;
}
ObjectSynchronizer::exit(h_obj(), elem->lock(), thread);
// Free entry. This must be done here, since a pending exception might be installed on
// exit. If it is not cleared, the exception handling code will try to unlock the monitor again.
ObjectSynchronizer::exit(obj, elem->lock(), Thread::current());
// Free entry. If it is not cleared, the exception handling code will try to unlock the monitor
// again at method exit or in the case of an exception.
elem->set_obj(NULL);
#ifdef ASSERT
thread->last_frame().interpreter_frame_verify_monitor(elem);
#endif
JRT_END


@@ -101,7 +101,7 @@ class InterpreterRuntime: AllStatic {
public:
// Synchronization
static void monitorenter(JavaThread* thread, BasicObjectLock* elem);
static void monitorexit (JavaThread* thread, BasicObjectLock* elem);
static void monitorexit (BasicObjectLock* elem);

static void throw_illegal_monitor_state_exception(JavaThread* thread);
static void new_illegal_monitor_state_exception(JavaThread* thread);
@@ -627,7 +627,7 @@ BytecodeInterpreter::run(interpreterState istate) {
(* BiasedLocking::rebiased_lock_entry_count_addr())++;
}
} else {
CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception);
InterpreterRuntime::monitorenter(THREAD, mon);
}
success = true;
} else {
@@ -1822,7 +1822,7 @@ BytecodeInterpreter::run(interpreterState istate) {
if (call_vm || lockee->cas_set_mark(header, old_header) != old_header) {
// restore object for the slow case
most_recent->set_obj(lockee);
CALL_VM(InterpreterRuntime::monitorexit(THREAD, most_recent), handle_exception);
InterpreterRuntime::monitorexit(most_recent);
}
}
}
@@ -2959,11 +2959,7 @@ BytecodeInterpreter::run(interpreterState istate) {
if (lockee->cas_set_mark(header, old_header) != old_header) {
// restore object for the slow case
end->set_obj(lockee);
{
// Prevent any HandleMarkCleaner from freeing our live handles
HandleMark __hm(THREAD);
CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, end));
}
InterpreterRuntime::monitorexit(end);
}
}
}
@@ -3013,11 +3009,7 @@ BytecodeInterpreter::run(interpreterState istate) {
THREAD->clear_pending_exception();
}
} else if (UseHeavyMonitors) {
{
// Prevent any HandleMarkCleaner from freeing our live handles.
HandleMark __hm(THREAD);
CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, base));
}
InterpreterRuntime::monitorexit(base);
if (THREAD->has_pending_exception()) {
if (!suppress_error) illegal_state_oop = Handle(THREAD, THREAD->pending_exception());
THREAD->clear_pending_exception();
@@ -3035,11 +3027,7 @@ BytecodeInterpreter::run(interpreterState istate) {
if (rcvr->cas_set_mark(header, old_header) != old_header) {
// restore object for the slow case
base->set_obj(rcvr);
{
// Prevent any HandleMarkCleaner from freeing our live handles
HandleMark __hm(THREAD);
CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, base));
}
InterpreterRuntime::monitorexit(base);
if (THREAD->has_pending_exception()) {
if (!suppress_error) illegal_state_oop = Handle(THREAD, THREAD->pending_exception());
THREAD->clear_pending_exception();
@@ -2097,6 +2097,14 @@ void SharedRuntime::monitor_exit_helper(oopDesc* obj, BasicLock* lock, JavaThrea
assert(JavaThread::current() == thread, "invariant");
// Exit must be non-blocking, and therefore no exceptions can be thrown.
EXCEPTION_MARK;
// The object could become unlocked through a JNI call, which we have no other checks for.
// Give a fatal message if CheckJNICalls. Otherwise we ignore it.
if (obj->is_unlocked()) {
if (CheckJNICalls) {
fatal("Object has been unlocked by JNI");
}
return;
}
ObjectSynchronizer::exit(obj, lock, THREAD);
}

0 comments on commit 77a0f39

Please sign in to comment.