我正在开发一种为其自己的虚拟机编译的脚本语言,这是一种简单的语言,它具有处理某种数据(如点、向量、浮点数等)的指令。内存单元以这种方式表示:
struct memory_cell
{
u32 id;
u8 type;
union
{
u8 b; /* boolean */
double f; /* float */
struct { double x, y, z; } v; /* vector */
struct { double r, g, b; } c; /* color */
struct { double r, g, b; } cw; /* color weight */
struct { double x, y, z; } p; /* point variable */
struct { u16 length; memory_cell **cells; } l; /* list variable */
};
};
指令是通用的,能够处理许多不同的操作数。例如
ADD dest, src1, src2
可以使用浮点数、向量、点、颜色根据操作数设置正确的目标类型。
主执行周期只是检查指令的操作码(这是一个包含联合来定义任何类型指令的结构)并执行它。我使用了一种简化的方法,其中没有寄存器,只有一大堆存储单元。
我想知道 JIT 是否可以帮助我获得最佳性能以及如何实现它。
正如我所说,到目前为止达到的最佳实现是这样的:
void VirtualMachine::executeInstruction(instr i)
{
u8 opcode = (i.opcode[0] & (u8)0xFC) >> 2;
if (opcode >= 1 && opcode <= 17) /* RTL instruction */
{
memory_cell *dest;
memory_cell *src1;
memory_cell *src2;
/* fetching destination */
switch (i.opcode[0] & 0x03)
{
/* skip fetching for optimization */
case 0: { break; }
case MEM_CELL: { dest = memory[stack_pointer+i.rtl.dest.cell]; break; }
case ARRAY_VAL: { dest = memory[stack_pointer+i.rtl.dest.cell]->l.cells[i.rtl.dest.index]; break; }
case ARRAY_CELL: { dest = memory[stack_pointer+i.rtl.dest.cell]->l.cells[(int)i.rtl.dest.value]; break; }
}
/* omitted code */
switch (opcode)
{
case ADD:
{
if (src1->type == M_VECTOR && src2->type == M_VECTOR)
{
dest->type = M_VECTOR;
dest->v.x = src1->v.x + src2->v.x;
dest->v.y = src1->v.y + src2->v.y;
dest->v.z = src1->v.z + src2->v.z;
}
/* omitted code */
尝试 jit 编译是否容易/方便?但我真的不知道从哪里开始,这就是为什么我要问一些建议。
除此之外,在开发它时我还应该考虑其他建议吗?
这个虚拟机应该足够快来计算光线追踪器的着色器,但我还没有做过任何基准测试。