3 内存值管理
本文描述的内存值管理主要是指:解释器的内存值如何表示,如何读取和存放。事实上,如果用值的类型去存储内存值,是很难做到一个统一内存值模型的。
复杂的方法如JCUTE、CRest的实现(符合执行框架,和解释器有类似之处),将内存值模型表示为一个结构体或者类,每一个值实例只在 结构体的一个域或者类中的一个成员变量有效,其他的均为冗余数据。这样做的问题是显而易见的,冗余数据太多,对每一个内存实例值来讲,都需要分配所有域或者成员变量的空间(这里的分配工作是由JVM完成,解释器的运行环境来,而不是解释器)。显然,这是冗余数据是没有必要的。
我们的做法是将内存值模型大概表示如下:
public class MemoryValue{
private byte[] values;
private Type type;
//...
public MemoryValue(Type type){
int size = SizeofCalculator.sizeAndAlignment(type).size;
ths.type = type;
values = new byte[size];
for(int i=0;i<size;i++){
byte[i] = 0;
}
}
public MemoryValue(Number value,Type type){
//....
}
public MemoryValue(Character value,Type type){
//....
}
//.....
/**
* 将字节数组转化为T类型的值,T为java类型的
* 转化需要根据 type 来进行
*/
public <T> getValue(T class){
//1、根据type将字节数组转化为type类型的值
//2、将type类型的值转化为T类型的值(这一步是java的类型转化)
}
}
在生成或者存储内存值实例时,将值根据类型转化为字节数组。这里注意的是,进行存储时,type类型是java类型,但是byte的长度应该是c语言对应类型的长度。如存储一个long值,在C语言中,long是32位的4字节长度,所以,在存储为字节数组时,需要存储为4个字节,而不是根据java的long类型长度(64位8字节)存储为8个字节。这样做的目的是:当需要获取字节数组的某一段的值时,比如获取数组元素的某个下标值时,直接根据C语言类型计算偏移量即可。否则,可能会读取内存到错误的值。
读取内存值时,根据值的类型和要读取到的类型进行转化。
关于如何将java类型的值转化为C语言对应类型的字节数组,以及将C语言类型对应的字节数组转化为java的值,将在下一节进行详细讲解。