java - 如何在低(汇编)级别捕获和处理异常?

标签 java code-generation jit

我有这个代码 -

try {
     doSomething();
} catch (Exception e) {
   e.printStackTrace();
}

这将如何由编译器实际实现。生成的汇编代码中实际放置异常的检查在哪里?

更新
我知道上面的代码是如何翻译成字节码的。字节码仅将 try-catch 转换为相应的 try-handler block 。我感兴趣的是它将如何转换为程序集/和/或由 jvm 处理。

最佳答案

如果我没有正确理解你的问题,下面的代码

public class Example {
    public static void main(String[] args) {
        try {
            otherMethod();
        }
        catch (Exception e) {}
        try {
            otherMethod();
            someMethod();
        }
        catch (SQLException e) {}
        catch (IOException e) {}
    }

    public static void someMethod() throws IOException {throw new IOException();}
    public static void otherMethod() throws SQLException, IOException {}
}

产生以下(人类可读版本的摘录)字节码。

//  main method
     0: invokestatic  #2                  // Method otherMethod:()V
     3: goto          7
     6: astore_1      
     7: invokestatic  #2                  // Method otherMethod:()V
    10: invokestatic  #4                  // Method someMethod:()V
    13: goto          21
    16: astore_1      
    17: goto          21
    20: astore_1      
    21: return        
  Exception table:
     from    to  target type
         0     3     6   Class java/lang/Exception
         7    13    16   Class java/sql/SQLException
         7    13    20   Class java/io/IOException

您会注意到异常表。此构造指示 VM,如果类型 type 的异常发生在从 fromto 的指令之间,则它必须 goto 指令(偏移量)目标。它还指示它将 Exception 引用压入堆栈,以便可以复制其值并将其绑定(bind)到 catch block 中的参数。

你还有这篇文章与上面的 throw 语句有关。

// someMethod method
     0: new           #6                  // class java/io/IOException
     3: dup           
     4: invokespecial #7                  // Method java/io/IOException."<init>":()V
     7: athrow        

The instruction athrow does the following

throws an error or exception (notice that the rest of the stack is cleared, leaving only a reference to the Throwable)

The JVM explains what happens

The objectref must be of type reference and must refer to an object that is an instance of class Throwable or of a subclass of Throwable. It is popped from the operand stack. The objectref is then thrown by searching the current method (§2.6) for the first exception handler that matches the class of objectref, as given by the algorithm in §2.10.

If an exception handler that matches objectref is found, it contains the location of the code intended to handle this exception. The pc register is reset to that location, the operand stack of the current frame is cleared, objectref is pushed back onto the operand stack, and execution continues.

If no matching exception handler is found in the current frame, that frame is popped. If the current frame represents an invocation of a synchronized method, the monitor entered or reentered on invocation of the method is exited as if by execution of a monitorexit instruction (§monitorexit). Finally, the frame of its invoker is reinstated, if such a frame exists, and the objectref is rethrown. If no such frame exists, the current thread exits.

因此堆栈帧不断弹出,直到找到一个可以处理抛出的异常为止。

How will this actually be implemented by the compiler. Where is the check for the exception actually put in the assembly code generated?

编译器生成上面的字节码。没有异常检查,只有字节码指令。 athrow 将指示 VM 执行我们称之为抛出异常的任务,这将导致弹出堆栈、在当前堆栈帧中搜索异常表等.

关于java - 如何在低(汇编)级别捕获和处理异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58936087/

相关文章:

Java Sockets Eclipse 空白错误弹出窗口

python - 在类中生成动态方法

javascript - Angular 2 AOT 与 JIT 负载比较

java - 如何在关闭 xchart 图表时不关闭整个 JVM

java - Powermockito如何调用ProcessBuilder重定向错误(文件文件)

java - 未经授权调用汇率服务

java - 如何修复: Jooq code does not generate java code for sqlite in memory db from sql script

java - 使用 java 程序生成源代码(COBOL)

ios-simulator - 在模拟器中运行单点触控与在设备上运行有什么区别?

compiler-construction - 与传统编译器相比,JIT 编译器有什么缺点吗?