我知道JVM有一个异常表,用于映射可能在给定字节码索引处抛出的异常。我也阅读了athrow字节码会抛出栈顶上存在的引用类型的异常。我的问题更与irem这样的指令如何“throw”异常有关。
JVM是否在每次执行指令后检查栈顶是否存在异常?非常感谢对底层发生的任何事情的洞察力。
JVM是否在每次执行指令后检查栈顶是否存在异常?非常感谢对底层发生的任何事情的洞察力。
irem是“逻辑int余数”运算符。Java虚拟机规范writes:
运行时异常
如果int余数运算符的除数为0,则irem会抛出ArithmeticException。
JVM实现的方式并未指定。它可以指示CPU在执行除法之前将除数与零进行比较,或者执行除法,并对CPU发出的除以0的信号做出反应。由于除以零的情况很少发生,因此后一种策略可能更有效。
例如,Intel 64和IA-32体系结构软件开发人员手册合并卷3A、3B和3C:系统编程指南写道:
6.1 中断和异常概述
当处理器在执行指令时检测到错误条件(例如除以零),就会发生异常。处理器检测到各种错误条件,包括保护违规、页面故障和内部机器故障。Pentium 4、Intel Xeon、P6系列和Pentium处理器的机器检查架构还允许在检测到内部硬件错误和总线错误时生成机器检查异常。
当接收到中断或检测到异常时,当前正在运行的过程或任务将被挂起,而处理器执行中断或异常处理程序。当处理程序的执行完成后,处理器会恢复中断的过程或任务的执行。中断的过程或任务的恢复发生时不会丢失程序连续性,除非无法从异常中恢复或中断导致当前运行的程序被终止。
JVM因此定义异常处理程序来创建异常对象,在一个已知寄存器中留下对它的引用,然后像athrow bytecode指令一样继续执行。