内存分段机制
在冯诺依曼机中,内存是一整块。数据放在数据段,代码放在代码段,二者之间不能混合。假设内存分布如下。
JVM的实现
CodeSection类
为了模拟内存中的这种机制,首先定义了CodeSection
类。该类用于描述段。
不考虑重定位计算,该类的关键属性包括下面几个方面
属性名 | 备注 |
---|---|
_start | 数据记录内存起始地址 |
_end | 当前数据记录内存终止地址 |
_limit | 分配的最后一个地址 |
_mark | 这个属性用于标记该段section,一般就是第一条指令 |
_index | 用于标记该段属于什么类型。 |
注意,通常我们在Java或者C#中描述某种固定类型通常使用enum关键字描述,但由于Java和C#是强类型语言,因此都是用enum的具体值来描述。例如在C#中定义段类型:
public enum EnumCodeSectionType{
SECT_CONSTS, //放置常量值
SECT_INST, //放置指令值
SECT_STUB, //放置装代码
SECT_NONE=-1 //非代码段
}
public class CodeSection{
private EnumCodeSectionType _codeSectionType=;
...
}
但是C或者C++是弱类型语言,其枚举类型的本质是整形,因此段枚举如下:
enum {
// Here is the list of all possible sections. The order reflects
// the final layout.
SECT_FIRST = 0,
SECT_CONSTS = SECT_FIRST, // Non-instruction data: Floats, jump tables, etc.
SECT_INSTS, // Executable instructions.
SECT_STUBS, // Outbound trampolines for supporting call sites.
SECT_LIMIT, SECT_NONE = -1
};
我们在CodeSection类中,使用_index字段描述该该枚举值。
public class CodeSection{
private:
int _index; //默认值由构造函数决定,否则为原内存中的遗留值
}
CodeBuffer类
在JVM中,定义CodeBuffer类用于保存各种CodeSection
这里可以看到有3个CodeSection类对象,分别是_consts,_insts以及_stubs。这3个字段分别对应3种CodeSection。在内存上的分别可以用下图显示。
其他相关字段功能如下
字段名 | 用途 |
---|---|
_name | CodeBuffer的名称,用于打印信息 |
_total_start | 整个CodeBuffer的起始地址 |
_total_size | 整个CodeBuffer的大小 |
_last_insn | 最后一条指令 |
如何将指令插入_insts字段
假设