我使用计算的goto实现了一个小字节码解释器(如果不熟悉,请参见此处)。
似乎可以通过在标签之间复制内存来进行简单的JITting,从而优化跳转。例如,假设我的解释器中包含以下内容:
op_inc: val++; DISPATCH();
Run Code Online (Sandbox Code Playgroud)
我将其更改为:
op_inc: val++;
op_inc_end:
Run Code Online (Sandbox Code Playgroud)
JITting时,我会将标签之间的内存附加到我的输出中:
memcpy(jit_code+offset, &&op_inc, &&op_inc_end - &&op_inc);
(jit_code使用标记为可执行mmap)
最后,我将使用compute goto跳转到复制的机器代码的开头:
goto *(void*)jit_code
这样行吗?我的机器代码思维模型中是否缺少某些东西可以阻止这个想法?
假设代码和数据共享相同的地址空间。我们还假设PIC。
更新资料
查看链接文章中的示例,删除后DISPATCH,我们有:
do_inc:
val++;
do_dec:
val--;
do_mul2:
val *= 2;
do_div2:
val /= 2;
do_add7:
val += 7;
do_neg:
val = -val;
do_halt:
return val;
Run Code Online (Sandbox Code Playgroud)
生成的代码do_inc(无优化)很简单:
Ltmp0: ## Block address taken
## %bb.1:
movl -20(%rbp), %eax
addl $1, %eax
movl %eax, -20(%rbp)
Run Code Online (Sandbox Code Playgroud)
(后接do_dec)。似乎可以剪切掉该小片段。
这是无法在一种架构上运行的另一个原因:
ARM Thumb代码将离线即时值与PC相对寻址一起使用。像这样的操作
a += 12345;
Run Code Online (Sandbox Code Playgroud)
可以编译为:
a += 12345;
Run Code Online (Sandbox Code Playgroud)
复制此函数的片段会使对常量的引用未解决;最终将使用内存中其他位置的意外值。
| 归档时间: |
|
| 查看次数: |
136 次 |
| 最近记录: |