看看openjdk中的athrow处理流程
{
oop except_oop = STACK_OBJECT(-1); //从栈中弹出异常的引用
CHECK_NULL(except_oop); //检查异常引用是否为空
THREAD->set_pending_exception(except_oop, NULL, 0);
goto handle_exception; //处理异常执行代码
}
处理异常的代码handle_exception
{
Handle except_oop(THREAD, THREAD->pending_exception());
CALL_VM(continuation_bci = (intptr_t)InterpreterRuntime::exception_handler_for_exception(THREAD, except_oop()), handle_exception); //此为查找异常表,也就是执行InterpreterRuntime::exception_handler_for_exception,如果在执行的过程中还抛出异常,回到handle_exception开始地方,继续执行
except_oop = (oop) THREAD->vm_result();
THREAD->set_vm_result(NULL);
if (continuation_bci >= 0) { //一般都是大于0,详见查找异常表exception_handler_for_exception的操作的说明
SET_STACK_OBJECT(except_oop(), 0);
MORE_STACK(1);
pc = METHOD->code_base() + continuation_bci; //pc指针
............
goto run ; //转到解释器处理循环,如果到这,不会执行if以后的代码
}
THREAD->set_pending_exception(except_oop(), NULL, 0);
goto handle_return; //本方法没有找到相应的异常处理,继续往上抛出
}
先看看查找异常表的代码
InterpreterRuntime::exception_handler_for_exception(JavaThread* thread, oopDesc* exception)
{
.............
if (thread->do_not_unlock_if_synchronized()) {
return Interpreter::remove_activation_entry();
}
do {
KlassHandle h_klass(THREAD, h_exception->klass());
handler_bci = h_method->fast_exception_handler_bci_for(h_klass, current_bci, THREAD);
if (HAS_PENDING_EXCEPTION) { //需要处理异常
h_exception = Handle(THREAD, PENDING_EXCEPTION);
CLEAR_PENDING_EXCEPTION;
if (handler_bci >= 0) { //这个地方有点看不明白,大于0应该是表示找到了catch里面对应的异常处理,怎么还继续循环?
current_bci = handler_bci;
should_repeat = true;
}
}
}while (should_repeat == true);
address continuation = NULL;
if (handler_bci < 0 || !thread->reguard_stack((address) &continuation)) {
continuation = Interpreter::remove_activation_entry();
h_method->interpreter_throwout_increment();
}else{
handler_pc = h_method->code_base() + handler_bci;
set_bcp_and_mdp(handler_pc, thread);
continuation = Interpreter::dispatch_table(vtos)[*handler_pc];
}
thread->set_vm_result(h_exception());
return continuation;
}
上面是在本方法里面找到的异常处理的代码,如果没有找到,应该是执行handle_return代码,handle_return处理的应该是本方法没有处理异常,也就是应该由上层方法处理。
handle_return:
{
if (THREAD->do_not_unlock()) { //对方法中监视器的处理
}else{
}
if (illegal_state_oop() != NULL || original_exception() != NULL) {
istate->set_msg(throwing_exception);
if (illegal_state_oop() != NULL)
THREAD->set_pending_exception(illegal_state_oop(), NULL, 0);
else
THREAD->set_pending_exception(original_exception(), NULL, 0);
istate->set_return_kind((Bytecodes::Code)opcode);
UPDATE_PC_AND_RETURN(0);
/*注意,这个地方采用的是return,也就是说它会跳出解释器的while(1)循环,从而结束javaCalls:call方法,这个就返回了上一个方法的处理流程中,具体得看InterpreterGenerator::generate_normal_entry,这个地方有些难于看懂,是怎么从调用的方法中返回,然后进行下一句的执行的。
在generate_normal_entry中注意下面的两句
__ pushptr(return_from_native_method.addr());调用前的返回地址(这就是上面return返回后的地址)
__ jmp(rax); 调用真正的方法
*/
}
}