小研究 - Java虚拟机即时编译器的一种实现原理

深入分析了 Kaffe虚拟机的 JIT(Just-In-Time)实现原理,以及在 JI中如何利用Trampoline技术来作为跳板达到提高 Kaffe虚拟机的执行性能,并通在 i386上结合实例来具体了解 Trampoline的实现。最后深入分析了作为 JIT核的翻译器在 JIT中如何将字节码映射成为中间码,并翻译成为本地代码的实现原理。

目录

1 引言

2  Kaffe中 JIT的实现原理

2.1 引入 Trampoline

2.2  Trampoline的实现思路

2.3  Trampoline的源码实现

2.4  翻译器的实现原理

3  结 束 语


1 引言

任何 Java虚拟机实现的核心都是它的执行引擎(如图 1)。Java虚拟机中的执行引擎就好比中央处理器,使得 Java虚拟机重复不断地读取字节码然后解释并执行,直到虚拟机进程退出。

Java虚拟机规范中规定,执行引擎的行为由指令集来规定动作。对于每条指令,规范都详细规定了执行该指令时应该“做什么”,但是没有说明“如何做”,因此 Java虚拟机的实现者可以采取解释执行技术、即时编译(JIT)技术或者直接在专用芯片上执行指令的技术,甚至可以是它们的混合技术。

Kaffe是按照 Java虚拟机规范实现的一种虚拟机。它是基于源代码开放的自由软件,在大部分平台上都能够成功的移植,且性能稳定。其执行引擎的实现(即“如何做”)也具有自身的特点。

Kaffe的执行引擎实现方式有解释执行与即时编译两种方式(可以在安装的时候选择)。解释执行是一种简单的实现方式:执行引擎读取每条字节码指令,然后将每条字节码解释成为本地代码,如此反复。这样的执行引擎实现方式比较简单,但是执行效率非常低下,因为解释工作是逐条地反复进行,导致程序中会有大量代码重复执行而浪费了许多时间。不过,Kaffe的即时编译器的执行效率得到了很大的提高:它是在第一次调用某个方法的时候,才将方法的字节码翻译成为本地代码,并在以后再次调用这个方法的时候,直接调用本地代码。由于是对整段代码的翻译,而且可以缓存本地代码,从而极大提高了虚拟机的运行速度。另外它还可以对整段代码进行本地优化,使解释字节码的效率得到大大提高,节约了大量的调用时间和空间。

2  Kaffe中 JIT的实现原理

2.1 引入 Trampoline

Kaffe采用JIT模式运行的时候,JIT会认为它正在执行的总是本地代码,因此需要在运行 Java方法之前将方法翻译成为本地代码。一种可能是在虚拟机装载 class文件的时候,将该类的所有方法都提前预编译为本地代码,这样在需要调用某个方法时,直接调用本地方法即可。但是这样的代价是装载一个类会耗费大量时间,而且经过提前翻译的方法不一定会得到运行,这样造成了时间和空间上的极大浪费,降低了性能。

2.2  Trampoline的实现思路

Kaffe的即时编译器(JIT)采用 Trampoline技术,其基本原理是:

1)创建 Trampoline阶段:每当虚拟机在装载类的时候,会为这个类的所有方法创建一个派遣表,该表中的每一项指向一个被称为 Trampoline的函数(见图 2)。该 Trampoline函数包含有足够的信息来通知一个叫做翻译器的函数来将该调用方法的字节码翻译成为本地代码。

2)调用方法阶段:每当虚拟机第一次调用某个方法的时候,调用者首先在一个派遣表中查找到该
方法,如果该方法还没有被翻译为本地代码,则该方法所指向的Trampoline函数会跳转到第一阶段存储的翻译器函数来负责将该方法的字节码翻译成本地代码。翻译结束之后,派遣表中的该方法被修改成指向翻译后的本地代码内存地址,并且将本地代码的地址返回给调用者。这样,以后再次调用该方法的时候,可以直接从派遣表中跳转到本地代码执行。

如图 2所示,调用路线直接从 a走向 b。Trampoline在其中起到了跳板的作用。

2.3  Trampoline的源码实现

Kaffe虚拟机由于是将字节码翻译成为本地代码,所以根据不同的平台,其实现原理虽然一致,但具体实现细节稍有不同。下面以 Kaffe在 i38平台下为例来分析一下 Trampoline的源代码。

在 Kaffe源代码目录的 config/i386/jit.h中,有一个 methodTrampoline结构体和 FILL_IN_TRAMPO-LINE的宏定义(见图 3)。methodTrampoline就是图2中 Trampoline的数据结构,它有 4个数据项,C语言中定义为 PACKED,表示 fixup项和 call项是紧挨着的,而不是 4字节对齐。FILL_IN_TRAMPOLINE宏的作用就是前面 2.2中描述的第一阶段。call=0xe8是 i386体系结构的汇编代码对应的 call指令。i386_do_fixup_trampoline是一个用汇编代码实现的函数,(int)t是 Trampoline的内存地址,汇编指令call占用 5个字节,所以要减去 5,最后得到的 fixup值是一个偏移量,该偏移量被汇编指令 call(0xe8)调用,方便以后跳转到 i386_do_fixup_trampoline中去执行。meth指向需要翻译成为本地代码的方法字节码。在 i386_do_fixup_trampoline中是作为参数传递给函数 soft_fixup_trampoline的(该函数调用了翻译器 Translate函数)。where指向派遣表中调用方法的位置。where因为和 meth在内存中是紧挨着的,所以最终它也传递给了函数 soft_fixup_trampo-line。

接下来看看 i386_do_fixup_trampoline的巧妙之处:popl%eax是将上面 meth的内存地址传递给%eax,之后压栈(push%eax),就可以将%eax(也就是meth的地址)作为参数传递给 soft_fixup_trampoline函数 了。soft_fixup_trampoline函数 调 用 翻 译 器(Translate方法)将字节码翻译成为本地代码,然后更新派遣表,使之指向本地代码。最后再跳转到本地代码并执行本地代码(见图 4)。

Kaffe针对其它平台也有类似的实现,虽然具体细节略有不同,但是其最终目的都是为了从 Trampo-line跳转到翻译器,把字节码翻译成为本地码。

2.4  翻译器的实现原理

Trampoline只是 Kaffe在 JIT中实现的跳板,而真正的将字节码翻译成本地代码的过程是由 Kaffe的翻译器来完成的。

Kaffe的 JIT在将字节码翻译成本地代码之前,会将字节码先翻译成对应的中间码,被称作 icode(intermediatecode)。Kaffe的中间码指令集的目的是为了在 Kaffe移植到一个新的体系架构过程中最大限度的获得代码重用,获得快速、高效的开发进度。

通过 Trampoline的巧妙设置后,此时翻译器并没有真正的执行,因为这只是在类装载时期完成的,还没有真正的调用 Java方法。而一旦第一次调用某个 Java方法时,JIT就会跳转到翻译器中来翻译字节码为中间码,再翻译为本地代码。翻译器在 JIT中起着核心的作用,主要完成三个步骤:

1)字节码的分析阶段:获得当前方法所需的栈信息(比如栈的大小等)、所有局部变量的有用信息等。

2)翻译阶段:首先将单个字节码指令映射到相应的中间码,然后通过中间码生成被称为“se-quence”对象的链表,这些链表各自对应着跟体系结构相关的本地函数,最后通过这些本地函数将中间码翻译成本地代码。

3)连接阶段:将所有生成的本地代码拷贝到一个新的空间,并且初始化连接。这里的初始化连接表示重写某些因为拷贝到新的空间造成的地址改变等信息。

3  结 束 语

不同虚拟机的执行引擎都有自己的具体实现方式,这里分析了 Kaffe虚拟机在 JIT上的实现原理。通过在不同平台上的运行效果看,Kaffe的 JIT在执行性能上还是有其优势的。

随着 Java虚拟机在各种平台的应用越来越广泛,Java的跨平台性也得到了广泛的认可,从而做好Java虚拟机的移植工作是非常重要的。在移植中,Kaffe执行引擎的移植是重要的一环,在这方面,Kaffe已经做的很出色。通过本文的分析,能够为程序员理解以及移植 Java虚拟机的执行引擎带来一定的参考价值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/92379.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CNN 01(CNN简介)

一、卷积神经网络的发展 convolutional neural network 在计算机视觉领域,通常要做的就是指用机器程序替代人眼对目标图像进行识别等。那么神经网络也好还是卷积神经网络其实都是上个世纪就有的算法,只是近些年来电脑的计算能力已非当年的那种计算水平…

kubernetes--技术文档--可视化管理界面dashboard安装部署

阿丹: 使用官方提供的可视化界面来完成。 Kubernetes Dashboard是Kubernetes集群的Web UI,用户可以通过Dashboard进行管理集群内所有资源对象,例如查看资源对象的运行情况,部署新的资源对象,伸缩Deployment中的Pod数量…

搜索二叉树的算法解析与实例演示

目录 一.搜索二叉树的特性与实现1.特点2.实现二.搜索二叉树的性能 一.搜索二叉树的特性与实现 1.特点 二叉搜索树是特殊的二叉树,它有着更严格的数据结构特点: (1)非空左子树的所有键值小于其根结点的键值。 (2&…

【C++入门到精通】C++入门 —— 多态(抽象类和虚函数的魅力)

阅读导航 前言一、多态的概念1. 概念2. 多态的特点 二、多态的定义及实现1. 多态的构成条件2. 虚函数3. 虚函数的重写⭕虚函数重写的两个例外1.协变(基类与派生类虚函数返回值类型不同)2.析构函数的重写(基类与派生类析构函数的名字不同) 4. override 和 final(C11 …

1.4亿X区城市运行“一网统管”体系建设项目项目招标WORD

导读:原文《1.4亿X区城市运行“一网统管”体系建设项目项目招标WORD》(获取来源见文尾),本文精选其中精华及架构部分,逻辑清晰、内容完整,为快速形成售前方案提供参考。 部分内容: 各部分需求…

为Claude的分析内容做准备:提取PDF页面内容的简易应用程序

由于Claude虽然可以分析整个文件,但是对文件的大小以及字数是有限制的,为了将pdf文件分批传入Claude人工智能分析和总结文章内容,才有了这篇博客: 在本篇博客中,我们将介绍一个基于 wxPython 和 PyMuPDF 库编写的简易的…

FreeSWITCH 1.10.10 简单图形化界面5 - 使用百度TTS

FreeSWITCH 1.10.10 简单图形化界面5 - 使用百度TTS 0、 界面预览1、注册百度AI开放平台,开通语音识别服务2、获取AppID/API Key/Secret Key3、 安装百度语音合成sdk4、合成代码5、在PBX中使用百度TTS6、音乐文件-TTS7、拨号规则-tts_command 0、 界面预览 http://…

FxFactory 8 Pro Mac 苹果电脑版 fcpx/ae/motion视觉特效软件包

FxFactory pro for mac是应用在Mac上的fcpx/ae/pr视觉特效插件包,包含了成百上千的视觉效果,打包了很多插件,如调色插件,转场插件,视觉插件,特效插件,文字插件,音频插件,…

C语言基础之——指针(下)

前言:本篇文章将继续讲解有关指针的剩余基础知识。 学无止境,一起加油叭!! 目录 一.指针运算 1.指针 - 整数 2.指针的关系运算 3.指针 - 指针 二.指针与数组 三.二级指针 四.指针数组 总结 一.指针运算 指针运算包括以下三…

09-微信小程序 网络请求API(实现轮播广告和简易的聊天窗口)

09-微信小程序API网络请求(实现轮播广告和简易的聊天窗口) 文章目录 微信小程序API服务器域名配置注意网络相关APIrequestRequestTask 请求任务对象object.success 回调函数object.fail 回调函数案例代码(实现轮播图) WebSocket案例代码(实现…

C++数据结构学习——栈

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、栈二、C语言实现1.声明代码2.实现增删查改代码3.测试代码 总结 前言 栈(Stack)是计算机科学中一种常见的数据结构,它是…

PHP敬老院管理系统Dreamweaver开发mysql数据库web结构php编程计算机网页

一、源码特点 PHP 敬老院管理系统(养老)是一套完善的web设计系统,对理解php编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。 论文 https://download.csdn.net/download/qq_41221322/…

Wlan——STA上线流程与802.11MAC帧讲解以及报文转发路径

目录 802.11MAC帧基本概念 802.11帧结构 802.11MAC帧的分类 管理帧 控制帧 数据帧 STA接入无线网络流程 信号扫描—管理帧 链路认证—管理帧 用户关联—管理帧 用户上线 不同802.11帧的转发路径 802.11MAC帧基本概念 802.11协议在802家族中的角色位置 其中802.3标…

数据结构——栈和队列OJ题

栈和队列小提升! 前言一、用队列实现栈队列接口实现(1)栈的接口定义(2)栈的初始化(3)入栈函数的定义(4)出栈函数的定义(5)查找栈顶元素&#xff0…

Python“牵手”当当网商品详情API接口运用场景及功能介绍,当当网API接口申请指南

当当网是全球知名的综合性网上购物商城,由国内著名出版机构科文公司、美国老虎基金、美国IDG集团、卢森堡剑桥集团、亚洲创业投资基金(原名软银中国创业基金)共同投资成立。当当网是北京当当网信息技术有限公司营运的一家中文购物网站&#x…

QT版权查询

文章目录 QT工具版权QT模块版权查询 根据条件自动筛选: Qt Features, Framework Essentials, Modules, Tools & Add-Ons QT工具版权 Licensing QT模块版权查询 在 All Modules 中点击进入每个模块,在详细内容中一般有Lisence相关内容。 Licens…

uniapp - 实现卡片式胶囊单选后右上角出现 “√“ 对勾对号选中效果功能,适用于小程序h5网页app全平台通用(一键复制组件源码,开箱即用!)

效果图 uniapp全平台兼容(小程序/h5网页/app)实现点击选择后,右上角出现 √ 对号效果(角标形式展现),功能组件, 改个样式,直接复制使用该组件。 组件源码 在 components 组件文件夹下,随便建立一个 .vue 文件,一键复制下方源码。

DockerFile解析

1. 是什么 Dockerfile是田来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本 1.1 概述 1.2 官网 Dockerfile reference | Docker Documentation 1.3 构建三步骤 1. 编写dockerfile文件 2. docker build命令构建镜像 3. docker run依镜像运…

文本分类任务

文章目录 引言1. 文本分类-使用场景2. 自定义类别任务3. 贝叶斯算法3.1 预备知识3.2 贝叶斯公式3.3 贝叶斯公式的应用3.4 贝叶斯公式在NLP中的应用3.5 贝叶斯公式-文本分类3.6 代码实现3.7 贝叶斯算法的优缺点 4. 支持向量机4.1 支持向量机-核函数4.2 支持向量机-解决多分类4.3…

go学习之流程控制语句

文章目录 流程控制语句1.顺序控制2.分支控制2.1单分支2.2双分支单分支和双分支的四个题目switch分支结构 3.循环控制for循环控制while 和do...while的实现 4.跳转控制语句breakcontinuegotoreturngotoreturn 流程控制语句 介绍:在程序中,程序运行的流程…