我们目前正在开发我们自己的 Java 虚拟机实现的 JIT 编译部分。我们现在的想法是将给定的 Java 字节码简单地转换为操作码,将它们写入可执行内存并在方法开始时调用。
假设给定的 Java 代码是:
int a = 13372338;
int b = 32 * a;
return b;
现在,采用了以下方法(假设给定的内存从 0x1000 开始,并且在 eax 中预期返回值):
0x1000: first local variable - accessible via [eip - 8]
0x1004: second local variable - accessible via [eip - 4]
0x1008: start of the code - accessible via [eip]
Java bytecode | Assembler code (NASM syntax)
--------------|------------------------------------------------------------------
| // start
| mov edx, eip
| push ebx
|
| // method content
ldc | mov eax, 13372338
| push eax
istore_0 | pop eax
| mov [edx - 8], eax
bipush | push 32
iload_0 | mov eax, [edx - 8]
| push eax
imul | pop ebx
| pop eax
| mul ebx
| push eax
istore_1 | pop eax
| mov [edx - 4], eax
iload_1 | mov eax, [edx - 4]
| push eax
ireturn | pop eax
|
| // end
| pop ebx
| ret
这将像虚拟机本身一样简单地使用堆栈。关于这个解决方案的问题是:
- 这种编译方法可行吗?
- 是否有可能以这种方式实现所有 Java 指令?如何翻译诸如throw/instanceof 和类似命令之类的东西?