思考了一下如何在 WebAssembly 这种哈弗架构中做 JIT:
主模块中需要导出的东西:
1.
2.
在主模块中动态生成 Wasm Module Binary(JIT 模块),放到
JavaScript 在实例化模块后,需要做 late linking,把 JIT 模块导出的函数注册到主模块的
另外 JIT 模块导出的函数也会直接读写主模块的内存,减少数据交换。这就要求 JIT 模块导入主模块的
当主模块需要调用 JIT 出来的函数时,使用
主模块中需要导出的东西:
1.
indirect function table :实现“函数指针”调用2.
memory :用于把动态生成的 wasm module 传给 JavaScript在主模块中动态生成 Wasm Module Binary(JIT 模块),放到
memory 里面,然后调用 JavaScript,JavaScript 从 memory 拿到数据后编译并实例化模块。JavaScript 在实例化模块后,需要做 late linking,把 JIT 模块导出的函数注册到主模块的
indirect function table 。另外 JIT 模块导出的函数也会直接读写主模块的内存,减少数据交换。这就要求 JIT 模块导入主模块的
memory ,这一步可以在 JIT 模块初始化时完成。当主模块需要调用 JIT 出来的函数时,使用
call_indirect $function_table_index 即可。[11:18 PM] ksco: I was tired of debugging so I took a nap, after waking up, it took me like 5 minutes to find the cause.
[11:19 PM] ksco: amazing.
[11:19 PM] ksco: amazing.
#DynamoRIO 目前针对 thread pointer 的做法是:在进入 guest 之前,把 tp 存起来,然后把 tp 指向 spill state。guest 所有的访问 tp 的指令当然都需要 mangle。从 guest 中退出的时候,再把 tp 恢复即可。这样有个好处就是,不需要再偷一个寄存器放 tp 的原始值(host thread pointer)了。
但今天发现一个大问题是,如果 client 设置了 itimer,跳转的地方是 guest 代码时,tp 的值其实是 spill state 而不是 host thread pointer,这样一来 sighandler 在读 thread private context 的时候就炸掉了。
所以合适的做法可能还是要偷一个寄存器,让 tp 的值始终保持 host thread pointer 不变。明天把这部分重写一下吧。
但今天发现一个大问题是,如果 client 设置了 itimer,跳转的地方是 guest 代码时,tp 的值其实是 spill state 而不是 host thread pointer,这样一来 sighandler 在读 thread private context 的时候就炸掉了。
所以合适的做法可能还是要偷一个寄存器,让 tp 的值始终保持 host thread pointer 不变。明天把这部分重写一下吧。
#DynamoRIO 遇到了大问题。对于类似
这可咋办了,感觉要识别这种序列,然后特殊处理了,先睡觉吧。
lr beq sc 这种指令序列,因为中间的 cbr 存在,所以这个序列会被 DynamoRIO 撕成两个 basic block,然后两个 basic block 中间,就不可避免的会执行一些访存指令。这在 Unmatched 上就会直接卡死,这是正常的,因为 spec 不允许 lr sc 中间插访存。这可咋办了,感觉要识别这种序列,然后特殊处理了,先睡觉吧。
ksco 的工作日志
#DynamoRIO 目前针对 thread pointer 的做法是:在进入 guest 之前,把 tp 存起来,然后把 tp 指向 spill state。guest 所有的访问 tp 的指令当然都需要 mangle。从 guest 中退出的时候,再把 tp 恢复即可。这样有个好处就是,不需要再偷一个寄存器放 tp 的原始值(host thread pointer)了。 但今天发现一个大问题是,如果 client 设置了 itimer,跳转的地方是 guest 代码时,tp 的值其实是 spill state…
花了两天刚把 thread pointer 问题修好了,又遇到
lr sc ,不知道什么时候才能推进多线程的支持了。😞