资讯专栏INFORMATION COLUMN

将Java字节码翻译为C代码

banana_pi / 2622人阅读

摘要:为什么要将字节码翻译为代码字节码是基于栈的一种编码。最近在研究,由于的目的是对字节码做优化,所以里面也有将字节码翻译为的逻辑。但是不明白为什么需要类型推导,目前我感觉将字节码翻译为完全不需要推导类型。

为什么要将Java字节码翻译为C代码?

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

先大体说说Java字节码的特点。目前版本的Java大概有200+的字节码指令,其中大部分都是1字节指令,这也是为什么叫做字节码。少部分指令是多字节或不定长指令。

对于解释器来说,解释指令时一般都是在操作两个区域。一个是栈,一个是局部变量表。举例来说,iload1指令,就是从局部变量表的1号槽位的数据放入操作数栈中,即*stack++ = locals[1]。

与C或者其他常用的编程语言不同的是,Java字节码的操作数类型是隐含的,操作的类型的显示的,而C语言中操作数类型都是显示的,但是操作是多态的。比如“+”,在C语言中“+”两边的操作数类型可以是int型,可以是double。Java字节码中iadd指令明确表示了要操作相加的两个数一定是int型。但是当抛开iadd指令而直接观测操作数栈时,并不知道栈上操作数的类型。

直接说结论。

Java字节码在每一条指令执行时,操作数栈的深度,局部变量表的大小,以及它们上面的操作数类型都是可以确定的。而且,无论从何种路径执行到某一条指令,操作数栈深度及操作数类型都是确定的[1]。Java虚拟机规范的4.10.2章节介绍了字节码校验的一个算法,可以参考。

以一个简单的a=b+c的例子来说明这个翻译过程。

对应的Java字节码如下:

iload1
iload2
iadd
istore1

我们可以暂时将操作数栈和局部变量表的每一个槽位看成一个局部变量。上面的代码就翻译为:

s0 = l1;
s1 = l2;
s0 = s0 + s1;
l1 = s0;

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

上面的例子实际上的存在一些问题的。虽然Java操作数栈和局部变量表里面存放的数据都是有类型,但是栈和局部变量表本身只是一个存储空间罢了,并没有规定里面必须存放什么类型的数据。所以每次在给栈空间或者局部变量赋值的时候,我们有必要新声明一个局部变量。上面的例子翻译为:

s0 = l1;
s1 = l2;
s0_1 = s0 + s1;
l1_1 = s0;

通过数据流分析可以求出def-use,方便做上面的这种变量分裂,这里不详细说了。

最近在研究Soot,由于Soot的目的是对字节码做优化,所以里面也有将字节码翻译为Jimple的逻辑。但是不明白Soot为什么需要类型推导,目前我感觉将Java字节码翻译为Jimple完全不需要推导类型。

[1] Toba: Java For ApplicationsA Way Ahead of Time (WAT) Compiler

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69223.html

相关文章

  • Java字节码翻译为C代码

    摘要:为什么要将字节码翻译为代码字节码是基于栈的一种编码。最近在研究,由于的目的是对字节码做优化,所以里面也有将字节码翻译为的逻辑。但是不明白为什么需要类型推导,目前我感觉将字节码翻译为完全不需要推导类型。 为什么要将Java字节码翻译为C代码? Java字节码是基于栈的一种编码。这种编码方式十分方便解释器的设计,但同时不利于程序分析,因此一些高效的代码优化技术无法方便的Java字节码上实现...

    legendmohe 评论0 收藏0
  • 【修炼内功】[JVM] 虚拟机视角的方法调用

    摘要:本文已收录修炼内功跃迁之路我们写的方法在被编译为文件后是如何被虚拟机执行的对于重写或者重载的方法,是在编译阶段就确定具体方法的么如果不是,虚拟机在运行时又是如何确定具体方法的方法调用不等于方法执行,一切方法调用在文件中都只是常量池中的符号引 本文已收录【修炼内功】跃迁之路 showImg(https://segmentfault.com/img/bVbuesq?w=2114&h=12...

    shevy 评论0 收藏0
  • Java™ 教程(“Hello World!”应用程序)

    Hello World!应用程序 下面列出的小节提供了编译和运行一个简单的Hello World!应用程序的详细说明,第一部分提供了关于使用NetBeans IDE入门的信息,集成开发环境极大地简化了软件开发过程。NetBeans IDE运行在下面列出的所有平台上,其余部分提供了特定于平台的指示,用于在没有集成开发环境的情况下启动。如果遇到问题,一定要参考常见问题部分,它为新用户遇到的许多问题提供...

    skinner 评论0 收藏0
  • python入门

    摘要:零预备知识字符编码计算机只能处理数字,所以为文本需要转化为数字才能被计算机处理,计算机里八个比特作为一个字节,这是数据的存储基础单位。 零、预备知识 0.1 字符编码计算机只能处理数字,所以为文本需要转化为数字才能被计算机处理,计算机里八个比特(bit)作为一个字节(byte),这是数据的存储基础单位。计算机为了处理文本,有以下三种编码方式: ASCII码:只有大小写英文字母,数字...

    xeblog 评论0 收藏0
  • 第2章:软件构建的过程和工具 2.2软件构建的过程,系统和工具

    摘要:建模语言建模语言是可用于表达信息或知识或系统的任何人造语言,该结构由一组一致的规则定义,目标是可视化,推理,验证和传达系统设计。将这些文件安排到不同的地方称为源代码树。源代码树的结构通常反映了软件的体系结构。 大纲 软件构建的一般过程: 编程/重构 审查和静态代码分析 调试(倾倒和记录)和测试 动态代码分析/分析 软件构建的狭义过程(Build): 构建系统:组件和过程 构建变体...

    godiscoder 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<