论坛首页 编程语言技术论坛

athrow程序执行代码

浏览 1456 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-10-10  
C

    看看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); 调用真正的方法

*/
            }

     }

论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics