深机笔记 - 17 基于栈的字节码解释解释执行引擎

《深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)》8.4节

解释执行


上图中:
下边那条分支,是传统编译原理中程序代码到目标机器代码的生成过程
中间那条分支,是解释执行过程

词法分析、语法分析以至后面的优化器、目标代码生成器选择独立于执行引擎,形成一个完整意义的编译器实现,这类代表是C/C++语言
把其中一部分步骤(如生成抽象语法树之前的步骤)实现为一个半独立编译器,在虚拟机之外进行,而解释器在虚拟机内部,这类代表是Java语言
把这些步骤和执行引擎全部集中封装在一个封闭的黑匣子之中,这类代表是大多数的JavaScript执行器

基于栈的指令集架构(Instruction Set Architecture, ISA)

Java编译器输出的指令流,基本上是一种基于栈的指令集架构,指令流中的指令大部分都是零地址指令,它们依赖操作数栈进行工作
例,计算“1+1”的指令序列:
iconst_1
iconst_1
iadd
istore_0
两条iconst_1指令连续把两个常量1压入栈
然后iadd指令把栈顶两个值出栈、相加,把结果放回栈顶
最后istore_0把栈顶的值放到局部变量表第0个Slot中

优点:
可移植,寄存器由硬件直接提供,程序不直接依赖硬件寄存器
代码相对更加紧凑(字节码中每个字节就对应一条指令,而多地址指令集中还需要存放参数)
编译器实现更加简单(不需要考虑空间分配的问题,所需空间都在栈上操作)

缺点:
由于指令数量和内存访问的原因,导致栈架构指令集的执行速度会相对较慢
完成相同功能所需的指令数量会比寄存器架构多,因为出栈、入栈操作本身就产生了相当多的指令数量
栈实现在内存中,频繁的栈访问意味着频繁的内存访问,相对于处理器来说,内存始终是执行速度的瓶颈

基于栈的解释器执行过程


例:
/**
 * 四则运算
 */
public int calc() {
    int a = 100;
    int b = 200;
    int c = 300;
    return (a + b) * c;
}

四则运算对应字节码表示:
public int calc();
Code:
Stack=2, Locals=4, Args_size=1
0:bipush100
2:istore_1
3:sipush200
6:istore_2
7:sipush300
10:istore_3
11:iload_1
12:iload_2
13:iadd
14:iload_3
15:imul
16:ireturn
}

四则运算对应字节码执行过程中代码、操作数栈和局部变量表的变化情况:
以下执行过程仅仅是一种概念模型,虚拟机中解析器、即时编译器会对字节码进行优化以提高性能,实际情况会和概念模型描述差距非常大
但从以下执行中可看出栈结构指令集的一般运行过程,中间变量以操作数栈的出栈、入栈为信息交换途径







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值