浅谈把Java字节码译为C代码的意义

Java字节码是基于栈的一种编码。这种编码方式十分方便解释器的设计,但同时不利于程序分析,所以一些高效的代码优化技术没法方便的Java字节码上实现。程序员

先大致说说Java字节码的特色。目前版本的Java大概有200+的字节码指令,其中大部分都是1字节指令,这也是为何叫作字节码。少部分指令是多字节或不定长指令。对于解释器来讲,解释指令时通常都是在操做两个区域。一个是栈,一个是局部变量表。举例来讲,iload1指令,就是从局部变量表的1号槽位的数据放入操做数栈中,即*stack++ = locals。编程

与C或者其余经常使用的编程语言不一样的是,Java字节码的操做数类型是隐含的,操做的类型的显示的,而C语言中操做数类型都是显示的,可是操做是多态的。好比“+”,在C语言中“+”两边的操做数类型能够是int型,能够是double。尚学堂•百战程序员陈老师指出Java字节码中iadd指令明确表示了要操做相加的两个数必定是int型。可是当抛开iadd指令而直接观测操做数栈时,并不知道栈上操做数的类型。编程语言

Java字节码在每一条指令执行时,操做数栈的深度,局部变量表的大小,以及它们上面的操做数类型都是能够肯定的。并且,不管从何种路径执行到某一条指令,操做数栈深度及操做数类型都是肯定的,以一个简单的a=b+c的例子来讲明这个翻译过程。优化

其中局部变量的类型都是已知的。能够看到s0,s1跟Java操做数栈的功能同样,是为了存放临时的计算结果。上面的代码彻底能够化简为“l1 = l1 + l2”。但前期没有必要引入这种复杂性,这种化简彻底能够由后续的各类优化完成。编码

上面的例子实际上的存在一些问题的。虽然Java操做数栈和局部变量表里面存放的数据都是有类型,可是栈和局部变量表自己只是一个存储空间罢了,并无规定里面必须存放什么类型的数据。因此每次在给栈空间或者局部变量赋值的时候,咱们有必要新声明一个局部变量。翻译

经过数据流分析能够求出def-use,方便作上面的这种变量分裂,这里不详细说了。最近在研究Soot,因为Soot的目的是对字节码作优化,因此里面也有将字节码翻译为Jimple的逻辑。可是不明白Soot为何须要类型推导,目前我感受将Java字节码翻译为Jimple彻底不须要推导类型。设计

相关文章
相关标签/搜索