|
接下来的两篇将介绍在KVM中字节是如何执行的,这是KVM中比较核心的内容,分为两部分来讲,本篇先介绍虚拟机中的栈和帧是如何实现的。
首先来看一些全局指针,在头文件kvm/vmcommon/h/interpret.h中定义有以下结构:
Word-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
str UCt GlobalStateStruct { BYTE* gs_ip; /* Instruction pointer (program counter) */ cell* gs_sp; /* Execution stack pointer */ cell* gs_lp; /* Local variable pointer */ FRAME gs_fp; /* Current frame pointer */ CONSTANTPOOL gs_cp; /* Constant pool pointer */ };
这五个变量就像CPU中的寄存器一样,在KVM的运行过程中起到非常基础性的作用。它们分别是程序计数器、执行栈指针、局部变量指针、当前帧指针和当前常量池指针。
Java虚拟机为每一个线程开设一个栈,栈中存储的数据以“帧”为单位,虚拟机在调用一个新的方法时,会向栈中压入一个新帧,帧内数据是这个方法的运行状态,Java字节码的执行总是在当前帧内进行,方法运行结束时这个帧会被弹出。所以这个栈可以称为“方法栈”,帧可以称为“方法帧”。
按照Java虚拟机的规范,一个帧应由三个部分组成:局部变量区,操作数栈和帧数据区。每个帧的局部变量区和操作数栈的大小都可能不一样,要依方法本身的庞大程度而定,但在调用一个方法时,可以根据这个方法的字节码计算出所需要的局部变量区和操作数栈的大小。规范对帧数据区的大小没有规定,帧数据区的大小和内容可由虚拟机实现来决定。
局部变量区:
局部变量区一般会位于帧中最前面(即地址最小)的位置,它包含了对应方法的参数和局部变量,一般情况下,它的大小是向4字节对齐的,每4字节是一个“字”,变量以“字”为单位来存入。在它的最前面顺序存放的是对应方法的参数,类型为int、float、reference和returnAddress的参数占一个“字”,类型为byte、short和char类型的参数对被转化为int型,所以也占一个字;long和double类型的值要占用两个字。当然,“字长”选为多少是由虚拟机实现自己来决定的,不是一定要选4字节为一个字,如果选8字节构成一个字的话,所有值都只占一个字,更加整齐,但是浪费了很多空间。
如果方法不是静态的,那么虚拟机会自动将方法所在对象的句柄存在局部变量区中索引为0的位置,真正的参数从位置1开始存;而如果方法是静态的,它就与具体的对象没有关系,所以不必存放对象句柄,参数从位置0开始存放。
在局部变量区接下来的空间中,虚拟机可以按照任意的方式来存贮方法内的局部变量。
上一篇:UML应用的三重境界
下一篇:从Caché看后关系型数据库
|