CASE(_monitorexit): { oop lockee = STACK_OBJECT(-1); CHECK_NULL(lockee); // derefing's lockee ought to provoke implicit null check // find our monitor slot BasicObjectLock* limit = istate->monitor_base(); BasicObjectLock* most_recent = (BasicObjectLock*) istate->stack_base(); // 从低往高遍历栈的Lock Record while (most_recent != limit ) { // 如果Lock Record关联的是该锁对象 if ((most_recent)->obj() == lockee) { BasicLock* lock = most_recent->lock(); markOop header = lock->displaced_header(); // 释放Lock Record most_recent->set_obj(NULL); // 如果是偏向模式,仅仅释放Lock Record就好了。否则要走轻量级锁or重量级锁的释放流程 if (!lockee->mark()->has_bias_pattern()) { bool call_vm = UseHeavyMonitors; // header!=NULL说明不是重入,则需要将Displaced Mark Word CAS到对象头的Mark Word if (header != NULL || call_vm) { if (call_vm || Atomic::cmpxchg_ptr(header, lockee->mark_addr(), lock) != lock) { // CAS失败或者是重量级锁则会走到这里,先将obj还原,然后调用monitorexit方法 most_recent->set_obj(lockee); CALL_VM(InterpreterRuntime::monitorexit(THREAD, most_recent), handle_exception); } } } //执行下一条命令 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); } //处理下一条Lock Record most_recent++; } // Need to throw illegal monitor state exception CALL_VM(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD), handle_exception); ShouldNotReachHere(); }
轻量级锁释放时需要将Displaced Mark Word替换到对象头的mark word中。如果CAS失败或者是重量级锁则进入到InterpreterRuntime::monitorexit方法中。
1 2 3 4 5 6 7 8 9 10 11
//%note monitor_1 IRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorexit(JavaThread* thread, BasicObjectLock* elem)) Handle h_obj(thread, elem->obj()); ... ObjectSynchronizer::slow_exit(h_obj(), elem->lock(), thread); // Free entry. This must be done here, since a pending exception might be installed on //释放Lock Record elem->set_obj(NULL); ... IRT_END