项目地址 https://github.com/partic2/pwart https://gitee.com/partic/pwart
找了几个 WebAssembly JIT 引擎,感觉比较重,像 wasmtime 的话至少需要建 Rust 环境,WAMR 的话现在是用 LLVM 生成程序的,内存占用和库尺寸都会比较大(fast-jit 版本好像在开发中了,不过不知道什么时候完成)。后来碰到个 jit 库 SLJIT ,看起来比较简单,就找了一个 wasm 解释器 wac,用 sljit 做代码生成,慢慢改了一个。源码全部是 C 的。
虽然有做一些测试,但都是比较简单的测试用例,没有跑过大的应用,可能还会存在一些 BUG ,欢迎提 Issue 和 PR 。接下来是在写这个项目时的一些想法和吐槽,可能有一些错误,欢迎大佬指出。
webassembly 中的 memory 要求是一块线性的内存,存取数据使用一个 32 位的 int,而不是指针,因此在实现上每次存取 memory 的数据我都要将地址加上基址偏移,虽然在项目中已经把基地址存放到寄存器里以加速这个过程,但感觉还是有点多余。同样的函数的间接调用也是要将函数放在 table 里再用索引去调用。引入指针 /引用概念,并增加类似获取 sizeof(void *)的指令感觉会不会好一些?
跳转必须以块为单位向外跳转,没有任意 label 跳转的模式,作为 ir ,或者 v-isa ,似乎是增加了一些代码生成器的工作量,还降低了一些代码优化空间。为什么 wasm 会选择这样的设计呢?
另外,可能是我学艺不精,我一开始看 webassembly spec 的文档像在看天书,各种符号,后面结合解释器的源码才勉强看明白。 做这个项目的本来还有个想法是让 wasm 成为可以衔接各种语言的一个平台,不过在做的过程中发现,从生态来讲,用 C 作为一个目标平台似乎更好的选择。所以我还建了个将 tinycc 裁剪一下主要为满足 JIT 需要的分支 https://github.com/partic2/tinycc-min.git 。
1
EulerChen 2022-11-14 14:17:38 +08:00
请问您做的这个轻量级 JIT 打算是应用在什么场景下呢?
我们团队这边目标场景是区块链,也做了一个对标 WAMR fastjit 的轻量级 JIT ,并已经上线蚂蚁链生产环境,JIT 整体编译+执行时间比 wasmer-singlepas 、wasmer-cralieft 、wasmer-llvm 都要好😁 |
2
pursuer OP @EulerChen
原想法是 写一个承载各种语言的跨平台通用运行时 /虚拟机,实现生态复用(类似 minijvm 项目,不过是 wasm)。不想依赖 llvm ,是因为 llvm 太重,在客户端场景使用可能效果不理想。再加上发现了比较成熟的轻量 jit 引擎 sljit ,支持很多 cpu 和操作系统,于是就实现了这个库。 现在的想法就像正文里写的。从现在的语言生态来说,使用 c(tinycc) + js(quickjs)作为轻量通用跨平台层似乎更好,毕竟上面两个语言已经承载了非常庞大的生态。当然这还要看 wasm 后续生态的发展。 虽然暂时工作重心不在这个项目,不过如果有人报 BUG 或者 PR ,我也会花时间搞一搞。 |