目前我能找到的好用的jit有两个:libjit和llvm。其中对于现在最出名的要数llvm,libjit可能有的人连听都没听说过。
这后面有一个悲伤的故事:
libjit是dotgnu的子项目。在2004年前后的几年,libjit力压llvm,是最流行的jit工具,几乎没人对oop过度设计的llvm感兴趣(这一点现在也一直在恶心我)。但是,dotgnu最终解体(后面大名鼎鼎的mono项目和dotgnu有很大的关系),libjit逐渐没落,众多开发人员如今只剩下一个人,其还在默默维护着libjit,但是已经没有新增特性了。所以,llvm便逐渐成了现在的样子。
但是我还是要先介绍libjit。对比libjit和llvm,很多api与设计理念是差不多的,先了解学习libjit有助于了解这些jit工具的通用套路。
libjit目前的主页在http://www.gnu.org/software/libjit/,最新的released版本还停留在一个2008年发布的0.1.2(git上的版本不推荐用),虽然“古老”,但是支持的平台还是较多的,但能生成机器码(libjit和llvm都有两种模式:解释和编译,解释就是所谓的“一句一句”执行,编译则是转换成机器码)的平台只有x86和x86-64。
libjit不是我们教程的重点,这里就简单说说。
先看代码(看之前最好看看libjit的document):
#include <stdio.h>
#include <jit/jit.h>
#include <jit/jit-dump.h>
#include <jit/jit-elf.h>
#include <iostream>
using namespace std;
#define prt(x) cout << x << endl;
int tfunc(int a, int b) //我们的目标函数样本,我们将尝试转换成jit
{
int x = 0;
struct ts
{
int c;
int d;
};
ts ats;
ats.c = 10;
ats.d = 1;
while (a < b)
{
x += a;
a++;
}
prt(x);
prt(ats.c);
return x;
}
void prt_int(int a)
{
prt("Sound from jit:" << a);
}
inline jit_nuint getoff(jit_value_t val, const char *name)
{
jit_type_t vt = jit_value_get_type(val);
return jit_type_get_offset(vt, jit_type_find_name(vt, name));