个人理解
Graph的功能:一种用于将字节码转换为机器码的数据结构,或者叫ir?
Graal的功能就是将字节码转换为机器码,但这个功能还是需要一定的理论支持,并不能只是简单的翻译。这时候Graph就充当了这样的一个角色。
图的生成基本都离不开BytecodeParser.java, 可以参考该文件中的processBytecode方法。
关于图结构:https://www.yuque.com/anruofusheng/bytlpr/ti1487c1phtwkyfb
查看Graph
public class HelloWorld
{
public static int addwj(int x, int y) {
return x + y;
}
public static void main(String[] args) {
int lastSum = 0;
for (int i = 0; i < 100000; i++) {
lastSum = addwj(i, 2);
}
System.out.println("Sum from 0 to 4999: " + lastSum);
}
}
编译上面的文件
$ cd graal/compiler
$ javac HelloWorld.java
$ mx vm -Djdk.graal.Dump=:1 \
-Djdk.graal.PrintGraph=File \
-XX:+UseJVMCICompiler -XX:+UnlockExperimentalVMOptions \
-XX:+BootstrapJVMCI -XX:-TieredCompilation HelloWorld
$ 会在当前目录生成一个graal_dumps目录,找到文件名中带addwj的文件
$ mx igv
$ 使用igv打开生成的addwj文件就可以看到生成的Graph
如何不使用第三方库分析字节码并生成类似上图的图结构?
分析下面代码:
public class HelloWorld
{
public static int addwj(int x, int y) {
return x + y;
}
public static void main(String[] args) {
addwj(101, 112);
}
}
思路:
1、通过jvmci获取字节码,参考第四章
2、通过分析字节码,递归遍历全部方法和方法中的字节码 参考第十章
3、先生成一个简单的树结构对象,关键对象有:
- Graph: 对外提供插入节点、和边的方法
- Node: 每个节点的属性,比如方法名,java方法、数值、变量名等…
- Relation: 在添加每条边时的描述
通过Graal官方关于图的一些介绍可以了解到边代表了节点之间的关系,所以这里需要Relation对象去说明。
4、在遍历字节码时根据不同的含义生成不同的节点,同时将前一个节点和后一个节点相连(也可能不相连,这里需要深入了解jvm和字节码,这里我们只是做一个demo,所以可以简单处理一下)。
上面demo对应的图,每条边都应该有对应的描述,可以自行定义
参考资料
https://chrisseaton.com/truffleruby/basic-graal-graphs/
https://chrisseaton.com/truffleruby/jokerconf17/
后续内容和示例代码可通过知识星球查看:https://t.zsxq.com/153Fqg272
本人正在找(web前端、工具链方向、IDE方向、小程序容器方向),有合适的老板们请联系我。