一种字节码指令集精简方法和系统
文献发布时间:2023-06-19 10:32:14
技术领域
本发明涉及虚拟机指令集,具体涉及一种字节码指令集精简方法和系统。
背景技术
虚拟机是由一种被处理器执行的软件应用程序或指令序列产生的抽象计算机,虚拟机可以执行虚拟机支持的指令集,指令集有基于操作数栈和基于寄存器两类指令集,Java Card虚拟机的指令集基于操作数栈,Dalvik虚拟机的指令集基于寄存器。采用现有的Dalvik虚拟机指令集生成的字节码占用存储空间较大,执行性能较佳,而采用Java Card虚拟机的指令集生成的字节码占用存储空间较小,但执行性能一般,因此,为了满足更高的性能需求,亟需设计一种精简指令的方法,用以既可以节省存储空间,又可以提高执行性能,同时适用于上述两类指令集。
发明内容
针对现有技术中存在的缺陷,本发明的目的在于提供一种字节码指令集精简方法和系统,可以精简虚拟机字节码,减少字节码的存储空间,提高字节码的执行性能。
为实现上述目的,本发明采用的技术方案如下:
一种字节码指令集精简方法,适用于基于操作数栈和基于寄存器的指令集,所述精简方法包括以下步骤:
S100、基于不同的引用类型,将常量池划分为对应的多个子常量池;
S200、基于每种引用类型的引用的个数,统计每种引用类型对应的指令出现的次数,按照从高到低的顺序放入对应的子常量池中,其中,每种引用类型对应的指令的常量池索引为每种引用类型对应的子常量池的索引;
S300、基于每种引用类型对应的指令的生成条件,生成对应的单字节常量池索引的指令。
进一步,如上所述的精简方法,所述引用类型包括类的引用、静态方法的引用、虚方法的引用、super方法的引用、静态域的引用、实例域的引用,所述多个子常量池包括:所述类的子常量池、所述静态方法的子常量池、所述虚方法的子常量池、所述super方法的子常量池、所述静态域的子常量池、所述实例域的子常量池。
进一步,如上所述的精简方法,S200包括:
若所述实例域的引用的个数超过256,则统计引用类型的实例域访问指令出现的次数,按照次数从高到低的顺序放入所述实例域的子常量池中,否则直接放入所述实例域的子常量池中;
若所述静态域的引用的个数超过256,则统计包内引用类型的静态域访问指令出现的次数,按照次数从高到低的顺序放入所述静态域的子常量池中,否则直接放入所述静态域的子常量池中;
若所述虚方法的引用的个数超过256,则统计每个虚方法调用指令出现的次数,按照次数从高到低的顺序放入所述虚方法的子常量池中,否则直接放入所述虚方法的子常量池中;
若所述静态方法的引用的个数超过256,则先统计调用库包中的静态方法指令出现的次数,按照次数从高到低的顺序优先放入所述静态方法的子常量池中,然后再统计每个调用包内静态方法指令出现的次数,按照次数从高到低的顺序放入所述静态方法的子常量池中,否则直接放入所述静态方法的子常量池中。
进一步,如上所述的精简方法,所述统计包内引用类型的静态域访问指令出现的次数,按照次数从高到低的顺序放入所述静态域的子常量池中,包括:
统计包内引用类型的静态域访问指令出现的次数,按照次数从高到低的顺序优先放置在所述静态域的子常量池的前端。
进一步,如上所述的精简方法,S300包括:
若一实例域访问指令的常量池索引在一个字节范围内,则生成对应的单字节常量池索引的实例域访问指令;
若一静态域访问指令的常量池索引在一个字节范围内且属于包内引用类型的静态域访问指令,则生成对应的单字节常量池索引的静态域访问指令;
若一虚方法调用指令的常量池索引在一个字节范围内,则生成对应的单字节常量池索引的虚方法调用指令。
进一步,如上所述的精简方法,S300还包括:
基于每个库包静态方法在大量应用中被调用的统计次数,生成常用库包静态方法列表放入配置文件中,其中,所述常用库包静态方法列表中的静态方法的个数在256以内且具有完整Java方法名称;
若一库包静态方法调用指令的常量池索引在一个字节范围内,则查询所述配置文件,确认该库包静态方法调用指令调用的库包静态方法是否存在所述常用库包静态方法列表中;
若确认该库包静态方法存在所述常用库包静态方法列表中,则生成对应的单字节常量池索引的库包静态方法调用指令。
进一步,如上所述的精简方法,所述基于每个库包静态方法在大量应用中被调用的统计次数,生成常用库包静态方法列表放入配置文件中,包括:
将每个库包静态方法被调用的统计次数按照从高到低进行排序,若所有库包静态方法的个数超过256则将前256个库包静态方法放入所述常用库包静态方法列表,若个数在256以内则直接将所有库包静态方法放入所述常用库包静态方法列表。
一种字节码指令集精简系统,适用于基于操作数栈和基于寄存器的指令集,所述精简系统包括:
常量池划分模块,用于基于不同的引用类型,将常量池划分为对应的多个子常量池;
常量池组件生成模块,用于基于每种引用类型的引用的个数,统计每种引用类型对应的指令出现的次数,按照从高到低的顺序放入对应的子常量池中,其中,每种引用类型对应的指令的常量池索引为每种引用类型对应的子常量池的索引;
指令生成模块,用于基于每种引用类型对应的指令的生成条件,生成对应的单字节常量池索引的指令。
进一步,如上所述的精简系统,所述引用类型包括类的引用、静态方法的引用、虚方法的引用、super方法的引用、静态域的引用、实例域的引用,所述多个子常量池包括:所述类的子常量池、所述静态方法的子常量池、所述虚方法的子常量池、所述super方法的子常量池、所述静态域的子常量池、所述实例域的子常量池。
进一步,如上所述的精简系统,所述常量池组件生成模块具体用于:
若所述实例域的引用的个数超过256,则统计每个获取引用类型的实例域访问指令出现的次数,按照次数从高到低的顺序放入所述实例域的子常量池中,否则直接放入所述实例域的子常量池中;
若所述静态域的引用的个数超过256,则统计包内引用类型的静态域访问指令出现的次数,按照次数从高到低的顺序放入所述静态域的子常量池中,否则直接放入所述静态域的子常量池中;
若所述虚方法的引用的个数超过256,则统计每个虚方法调用指令出现的次数,按照次数从高到低的顺序放入所述虚方法的子常量池中,否则直接放入所述虚方法的子常量池中;
若所述静态方法的引用的个数超过256,则先统计调用库包中的静态方法指令出现的次数,按照次数从高到低的顺序优先放入所述静态方法的子常量池中,然后再统计每个调用包内静态方法指令出现的次数,按照次数从高到低的顺序放入所述静态方法的子常量池中,否则直接放入所述静态方法的子常量池中。
本发明的有益效果在于:本发明同时适用基于操作数栈和基于寄存器的虚拟机指令集,生成指令前统计某个方法调用以及访问引用类型的域的指令的频率;将常量池分为多个子常量池,每个子常量池优先放置高频率出现的引用;高频率访问实例域的指令采用单字节常量池索引;高频率访问的虚方法调用指令采用单字节常量池索引;高频率访问静态域的指令采用单字节常量池索引;高频率访问的库包静态方法调用指令采用单字节常量池索引;通过上述设计可以不使用很多操作码的情况下,能有效地减少方法的字节码的大小。
附图说明
图1为本发明实施例中提供的常量池的结构示意图;
图2为本发明实施例中提供的单字节静态域常量池索引的使用方式示意图;
图3为本发明实施例中提供的单字节静态方法常量池索引的使用方式(解析前),库包静态方法调用示意图;
图4为本发明实施例中提供的单字节静态方法常量池索引的使用方式(解析后),库包静态方法调用示意图;
图5为本发明实施例中提供的单字节静态方法常量池索引的另一种使用方式(解析后),包内、库包静态方法调用示意图;
图6为本发明实施例中提供的一种字节码指令集精简方法的流程示意图;
图7为本发明实施例中提供的一种字节码指令集精简系统的结构示意图。
具体实施方式
下面结合说明书附图与具体实施方式对本发明做进一步的详细说明。
名词解释
常量池:虚拟机指令集通过常量池索引访问常量池中存储的符号引用,包括类(接口)、静态域、静态方法、实例域、虚方法、super方法。
包内:字节码生成程序以一个Java包为单位进行转换,本发明所述的包内是指待转换的Java包,Java包导入(import)库包。
库包:可以被其他Java包导入的Java包,Java Card API以Java库方式实现,可以被其他包中类引用。一个包定义的java类(包内)可以调用库包中提供的类的方法。
本发明的方法同时适用于Java Card虚拟机想指令集、Dalvik虚拟机指令集和TGoMOS虚拟机指令集,下文以TGoMOS虚拟机指令集说明本发明的方法。TGoMOS虚拟机指令集,即一种微操作系统字节码的精简指令集,包括六种指令。
第一指令,第一指令由操作码组成,操作码中隐含有第一指令的参数信息;第一指令包括:将操作数和寄存器编号都隐含到操作码中的指令;将寄存器编号隐含到操作码中的指令;将常数操作数隐含到操作码中的指令;将数组成员的成员类型隐含到操作码中的数组成员访问指令;将方法调用的类型和参数隐含到操作码中的指令。
第二指令,第二指令为具有多种指令格式的高频指令;第二指令包括:具有多种操作格式的常用算术操作指令;采用4位寄存器格式的数组成员访问指令;将数组成员的成员类型隐含到操作码中的创建数组指令;基于相等和不相等比较结果,具有多种指令格式的分支指令。
第三指令,第三指令包括基于不同参数个数,具有不同指令格式的指令;第三指令包括:基于不同参数个数,具有不同指令格式的静态方法调用指令;基于不同参数个数,具有不同指令格式的虚方法调用指令;基于不同参数个数,具有不同指令格式的私有实例方法调用指令。
第四指令,第四指令包括常用数据类型的指令和不常用数据类型的指令,常用数据类型的指令具有多种指令格式,不常用数据类型的指令具有一种指令格式;常用数据类型的指令包括short数据类型的指令,不常用数据类型的指令包括int数据类型的指令。
第五指令,第五指令为具有单字节常量池索引的指令;第五指令包括:具有单字节常量池索引的静态方法调用指令;具有单字节常量池索引的虚方法调用指令;具有单字节常量池索引的静态域访问指令;具有单字节常量池索引的实例域访问指令。
第六指令,第六指令为宏指令。第六指令包括:基于静态方法调用指令转换形成的宏指令以及基于多条指令合并形成的宏指令。
第七指令,前六类指令以外的其他指令。
本发明的实现包括以下四个部分。
一、可加载并执行文件格式中常量池组件设计
1、将相同引用类型放在一起,形成6个子常量池。共有6种引用类型:1)类引用;2)静态方法引用;3)虚方法引用;4)super方法引用;5)静态域引用;6)实例域引用。将每种引用类型放在一起形成一个子常量池,具体地,将所有的类引用类型放在一起形成类子常量池,将所有的静态方法引用类型放在一起形成静态方法子常量池,将所有的虚方法引用类型放在一起形成虚方法子常量池,将所有的super方法引用类型放在一起形成super方法子常量池,将所有的静态域引用类型放在一起形成静态域子常量池,将所有的实例域引用类型放在一起形成实例域子常量池。
2、每个子常量池的引用如果超过256,对于特定类型的引用按照使用频率从高到低排序优先放入子常量池中。
3、指令中的常量池索引为对应的子常量池的索引。部分指令使用常量池索引,不同的指令会使用不同类型的常量池索引。比如,实例域访问指令包括实例域子常量池索引操作数,通过实例域子常量池索引可以在实例域子常量池中查询到对应的实例域引用。
相比未区分子常量池的设计,如果整个常量池的大小超过256,特定常量池的索引易超过一个单字节表示的范围,通过拆分为6个子常量池,每个常量池项的索引基本不会超过1字节的范围。
图1示出了一种常量池实现方式,常量池包括6个子常量池,每个子常量池在常量池的顺序没有要求,以及访问子常量池的方法(即记录每个子常量池的偏移和大小的方式)没有要求。
二、指令集设计
TGoMO虚拟机指令集中,一个字节的操作码可以指定指令的操作类型,是否需要操作数以及操作数类型,是否返回操作结果等。其中有一些指令需要访问常量池(比如第五指令),因此指令中会包含对应的常量池索引操作数。指令的常量池索引可以为一个或两个字节的长度,指令中常量池索引的长度取决于两个条件:1)特定引用在对应子常量池中的索引的大小;2)特定引用在常量池解析后需要的字节长度。对于常用的指令如果可以采用单字节索引,可以明显减少方法的字节码的长度,如果单字节的常量池索引的指令使用了N次,相比使用2字节索引的指令会节省N个字节。通过大量应用转换结果的分析,发现下述指令的出现频率相对比较高:
1、引用类型的实例域访问指令;
2、包内中定义的引用类型的静态域访问指令;
3、库包中的静态方法调用指令;
4、虚方法调用指令。
通过前述可加载并执行文件格式中常量池组件的设计,可以保证常用的引用索引不超过一个字节,通过虚拟机采用的其他方法,保证一字节索引可以存储解析后的结果。表1示出了可以采用单字节索引的指令,包括指令的功能以及使用适用条件。
表1
在生成指令之前,需要对索引解析,即将应用安装到虚拟机时的一个处理。具体如下:
1、实例域引用类型
将实例域的子常量池解析为实例域引用的索引,每个类单独从0开始编号。使用实例域引用的单字节常量池索引的条件:该实例域引用的索引的值为单字节表示的范围,即0到255。针对实例域引用的单字节常量池索引可以满足常用的应用场景,1字节可以寻址256个word,boolean、byte、short类型的基本类型各占用一个word,引用类型占用一个word,int类型的基本变量占用2个word。word是虚拟机规范定义的一个抽象存储单元,一个word必须足够大可以容纳下一个byte、short、reference、returnAddress数据类型,二个word可以容纳下一个int类型。
2、静态域引用类型
将静态域引用的索引解析为静态域镜像的偏移。将一个Java包中声明所有类的静态域放在一起,形成静态域镜像。将静态域镜像进行单字节偏移,把引用类型的静态域放到镜像前部,可以使单字节偏移,从而寻址到这些频繁访问的引用类型的静态域。图2示出单字节静态域常量池索引的一种使用方式,序号20表示静态域访问指令中静态域镜像的偏移(静态域子常量池索引解析后替换),序号21表示静态域镜像。
3、虚方法引用
将虚方法引用的索引解析为每个类的虚方法表的索引,虚方法表分为公开(保护)类型虚方法表和包可见的虚方法表。TGoMOS虚拟机指令集的虚方法调用指令,已经明确指定方法的参数个数,不需要从虚方法子常量池索引解析出虚方法调用的参数个数。
4、静态方法引用
TGoMOS虚拟机的可执行文件调用库包的静态方法,这些静态方法为掩膜库包中的静态方法,解析后的结果为静态方法的全局引用表索引。需要将常用的静态方法引用添加到全局引用表的前端(1个字节可以访问的范围),这样就可以将静态方法的子常量池引用解析为单字节的全局引用表索引。
图3示出单字节静态方法常量池索引的一种使用方式(解析前),调用库包的静态方法。序号32表示库包静态方法的子常量池引用的内容,包括package index,可以用于查询到指定的掩膜包信息,包括Export组件;序号35表示指定包的Export组件,通过Classindex以及Method index查询Export组件可以得到方法的字节码位置信息。序号34表示指定包的方法组件,包括指定方法的字节码等内容。
图4示出单字节静态方法常量池索引的一种使用方式(解析后),库包静态方法调用。序号40表示静态方法调用指令中全局引用表的索引(由常量池索引解析后替换)。序号41表示全局引用表的项,包括包的索引以及指定包的方法组件的偏移,字节码转换时需要将常用的静态方法优先放到全局引用表的头部,即索引为0到255的范围。序号42表示静态方法字节码的位置。
图5示出单字节静态方法常量池索引的另外一种使用方式(解析后),包内、库包静态方法调用。序号51表示高频调用包内方法的偏移表,即将常用方法的偏移放入一个表中,常量池解析时,替换为此表的对应方法的索引。序号52表示高频调用库包方法的全局引用表索引表,即将常用方法的全局引用表索引放入一个表中,常量池解析时,替换为此表的对应方法的索引。序号53示范性表示方法组件,序号54示范性表示全局引用表。
通过上述方法可以对出现频率高的指令提供单字节索引的指令版本,比如Invvirtual,getstatic-o,getfield-o,invstatic。对于其他使用频率相对较高的指令,如果不考虑执行性能和对RAM需求的增加,也可以考虑提供单字节索引的指令。对于用频率相对较低的指令,可以不考虑提供单字节索引的指令。通过上述方法可以不使用很多操作码的情况下,有效地减少字节码的大小。
三、转换实现过程
1、生成常量池组件
常量池组件由6个子常量池组成,即类子常量池,静态方法子常量池,虚方法子常量池,super方法子常量池,静态域子常量池,实例域子常量池。
如果实例域的引用的个数超过256,统计每个引用类型实例域的指令出现次数,并按照次数从高到底的顺序放到实例域子常量池中,否则对顺序没有要求。
如果虚方法的引用的个数超过256,统计每个虚方法调用指令的次数,并按照次数从高到底的顺序放到虚方法子常量池中,否则对顺序没有要求。
如果静态域的引用的个数超过256,统计包内引用类型的静态域的指令出现次数,并按照次数从高到底的顺序放到静态域子常量池中,否则对顺序没有要求。
如果静态方法的引用的个数超过256,统计每个库包静态方法调用指令的次数,并按照次数从高到底的顺序放到静态方法子常量池中,否则对顺序没有要求。
通过上述操作,保证下述高频出现的指令其常量池引用的索引值不超过一个字节的范围。高频出现的指令,即获取引用类型的实例域访问指令getfield-o,获取引用类型的静态域访问指令getstatic-o,虚方法调用指令invvirtual,静态方法调用指令invstatic。
2、生成静态域组件
统计每个引用类型的静态域的指令出现的次数,按照次数从高到低的顺序优先放置在静态域区域的前端。
3、生成方法组件
主要指静态方法调用指令,单字节常量池索引的指令仅适用于调用常用的掩膜到虚拟机系统的库包中的静态方法。生成条件:1)需要提供配置文件指定库包中常用的静态方法的列表,个数不能超过256,列表中的每一行包括一个静态方法的完整名称;2)静态方法的常量池索引不超过256;3)生成可执行文件时,生成静态方法调用指令时需要查询此配置文件,如果被调用的方法在此列表中就生成单字节常量池索引的指令。
4、生成访问静态域的指令
单字节常量池索引的指令仅适用于包内引用类型静态域的访问,常量池索引在一个字节可以表示的范围。
5、生成访问实例域的指令
单字节常量池索引指令的生成条件,即获取引用类型的实例域,常量池索引的值不超过1个字节。
6、生成访问虚方法的指令
单字节常量池索引指令的生成条件,即常量池索引的值不超过1个字节。
7、掩膜到设备的库包的生成
需要提供配置文件指定库包中常用的静态方法的列表,个数不能超过256,列表中的每一行包括一个静态方法的完整名称;实现必须将此列表中的全部方法可以通过一个字节的索引可以访问。
四、虚拟机实现
本发明优选采用单字节索引的场合,虚拟机的可执行文件应当实现以下功能:通过单字节索引调用掩膜库包静态方法,通过单字节索引调用包内静态域,通过单字节索引调用虚方法,通过单字节索引调用实例域。
除了上述采用单字节索引的场合,本发明还包括以下采用单字节索引的场合:
1、可执行文件通过单字节索引调用动态下载库包静态方法。同时支持包内、库包静态方法,个数不超过128个方法(需要通过最高位区分包内和库包方法),只支持库包静态方法的可以为256个方法。需要增加多次调用的静态方法的全局引用表索引的表。将常量池解析为静态方法的全局引用表索引的表的索引。通过索引查找到方法的全局引用表索引,通过全局引用表索引获取方法的偏移以及方法所属类所在的包的包索引。
2、可执行文件通过单字节索引调用包内静态方法(包括私有实例方法和
基于上述设计思路,本发明实施例提供一种字节码指令集精简方法,适用于JavaCard指令集、Dalvik指令集和前述的TGoMOS虚拟机指令集。TGoMOS虚拟机指令集的第五指令包括:具有单字节常量池索引的静态方法调用指令;具有单字节常量池索引的虚方法调用指令;具有单字节常量池索引的静态域访问指令;具有单字节常量池索引的实例域访问指令。通过本发明的精简方法可以生成TGoMOS虚拟机指令集的第五指令。
如图6所示,精简方法包括以下步骤:
S100、基于不同的引用类型,将常量池划分为对应的多个子常量池;
引用类型包括类的引用、静态方法的引用、虚方法的引用、super方法的引用、静态域的引用、实例域的引用,多个子常量池包括:类的子常量池、静态方法的子常量池、虚方法的子常量池、super方法的子常量池、静态域的子常量池、实例域的子常量池;
S200、基于每种引用类型的引用的个数,统计每种引用类型对应的指令出现的次数,按照从高到低的顺序放入对应的子常量池中,其中,每种引用类型对应的指令的常量池索引为每种引用类型对应的子常量池的索引;
S200包括:
若实例域的引用的个数超过256,则统计每个获取引用类型的实例域访问指令出现的次数,按照次数从高到低的顺序放入实例域的子常量池中,否则直接放入实例域的子常量池中;
若静态域的引用的个数超过256,则统计每个获取引用类型的静态域访问指令出现的次数,按照次数从高到低的顺序放入静态域的子常量池中,否则直接放入静态域的子常量池中;
具体地,统计每个获取引用类型的静态域访问指令出现的次数,按照次数从高到低的顺序优先放置在静态域的子常量池的前端。
若虚方法的引用的个数超过256,则统计每个虚方法调用指令出现的次数,按照次数从高到低的顺序放入虚方法的子常量池中,否则直接放入虚方法的子常量池中;
若静态方法的引用的个数超过256,则先统计调用库包中的静态方法指令出现的次数,按照次数从高到低的顺序优先放入静态方法的子常量池中,然后再统计每个调用包内静态方法指令出现的次数,按照次数从高到低的顺序放入静态方法的子常量池中,否则直接放入静态方法的子常量池中。
S300、基于每种引用类型对应的指令的生成条件,生成对应的单字节常量池索引的指令。
针对实例域访问指令、静态域访问指令和虚方法调用指令,生成对应的单字节常量池索引的指令,S300包括:
1)若一实例域访问指令的常量池索引在一个字节范围内,则生成对应的单字节常量池索引的实例域访问指令;
2)若一静态域访问指令的常量池索引在一个字节范围内且属于包内引用类型的静态域访问指令,则生成对应的单字节常量池索引的静态域访问指令;
3)若一虚方法调用指令的常量池索引在一个字节范围内,则生成对应的单字节常量池索引的虚方法调用指令。
4)针对静态方法调用指令,生成对应的单字节常量池索引的指令,包括:
4.1)基于每个库包静态方法在大量应用中被调用的统计次数,生成常用库包静态方法列表放入配置文件中,其中,常用库包静态方法列表中的静态方法的个数在256以内且具有完整名称;
具体地,将每个库包静态方法在大量应用中被调用的统计次数按照从高到低进行排序,若所有库包静态方法的个数超过256则将前256个库包静态方法放入常用库包静态方法列表,若个数在256以内则直接将所有库包静态方法放入常用库包静态方法列表。
4.2)若一库包静态方法调用指令的常量池索引在一个字节范围内,则查询配置文件,确认该库包静态方法调用指令对应的库包静态方法是否存在常用库包静态方法列表中;
4.3)若确认该库包静态方法存在常用库包静态方法列表中,则生成对应的单字节常量池索引的库包静态方法调用指令。
本发明同时适用基于操作数栈和基于寄存器的虚拟机指令集,生成指令前统计某个方法调用以及访问引用类型的域的指令的频率,将常量池分为多个子常量池,每个子常量池优先放置高频率出现的引用,高频率访问的静态方法预先放置到引用表的前端,高频率访问的引用类型的静态域预先放置到静态域镜像的前端,高频率访问实例域的指令采用单字节常量池索引,高频率访问的虚方法调用指令采用单字节常量池索引,高频率访问静态域的指令采用单字节常量池索引,高频率访问的静态方法调用指令采用单字节常量池索引,通过上述设计可以不使用很多操作码的情况下,能有效地减少方法的字节码的大小。
为了验证上述技术效果,我们采用典型金融应用的常量池索引,未采用子常量池技术时,常量池共有项333项,有77项的索引超过256范围。采用子常量池技术时,每个子常量池的引用个数都没有超过256,因此子常量池索引可以采用单个字节。如下表2所示的典型金融应用的指令调用情况。
表2
从表2可知,采用单字节索引可以使字节码的大小减少3261个字节。因此,采用本发明的精简方法,能大大精简虚拟机字节码,减少字节码的存储空间,提高字节码的执行性能。
如图7所示,本发明实施例还提供一种字节码指令集精简系统,适用于基于操作数栈和基于寄存器的指令集,精简系统包括:
常量池划分模块100,用于基于不同的引用类型,将常量池划分为对应的多个子常量池;
常量池组件生成模块200,用于基于每种引用类型的引用的个数,统计每种引用类型对应的指令出现的次数,按照从高到低的顺序放入对应的子常量池中,其中,每种引用类型对应的指令的常量池索引为每种引用类型对应的子常量池的索引;
指令生成模块300,用于基于每种引用类型对应的指令的生成条件,生成对应的单字节常量池索引的指令。
引用类型包括类的引用、静态方法的引用、虚方法的引用、super方法的引用、静态域的引用、实例域的引用,多个子常量池包括:类的子常量池、静态方法的子常量池、虚方法的子常量池、super方法的子常量池、静态域的子常量池、实例域的子常量池。
常量池组件生成模块200具体用于:
若实例域的引用的个数超过256,则统计每个获取引用类型的实例域访问指令出现的次数,按照次数从高到低的顺序放入实例域的子常量池中,否则直接放入实例域的子常量池中;
若静态域的引用的个数超过256,则统计每个获取引用类型的静态域访问指令出现的次数,按照次数从高到低的顺序放入静态域的子常量池中,否则直接放入静态域的子常量池中;
若虚方法的引用的个数超过256,则统计每个虚方法调用指令出现的次数,按照次数从高到低的顺序放入虚方法的子常量池中,否则直接放入虚方法的子常量池中;
若静态方法的引用的个数超过256,则先统计调用库包中的静态方法指令出现的次数,按照次数从高到低的顺序优先放入静态方法的子常量池中,然后再统计每个调用包内静态方法指令出现的次数,按照次数从高到低的顺序放入静态方法的子常量池中,否则直接放入静态方法的子常量池中。
指令生成模块300中,针对实例域访问指令、静态域访问指令和虚方法调用指令,生成对应的单字节常量池索引的指令,包括:
1)若一实例域访问指令的常量池索引在一个字节范围内,则生成对应的单字节常量池索引的实例域访问指令;
2)若一静态域访问指令的常量池索引在一个字节范围内且属于包内引用类型的静态域访问指令,则生成对应的单字节常量池索引的静态域访问指令;
3)若一虚方法调用指令的常量池索引在一个字节范围内,则生成对应的单字节常量池索引的虚方法调用指令。
4)针对静态方法调用指令,生成对应的单字节常量池索引的指令,包括:
4.1)基于每个库包静态方法在大量应用中被调用的统计次数,生成常用库包静态方法列表放入配置文件中,其中,常用库包静态方法列表中的静态方法的个数在256以内且具有完整Java方法名称;
具体地,将每个库包静态方法被调用的统计次数按照从高到低进行排序,若所有库包静态方法的个数超过256则将前256个库包静态方法放入常用库包静态方法列表,若个数在256以内则直接将所有库包静态方法放入常用库包静态方法列表。
4.2)若一库包静态方法调用指令的常量池索引在一个字节范围内,则查询配置文件,确认该库包静态方法调用指令对应的库包静态方法是否存在常用库包静态方法列表中;
4.3)若确认该库包静态方法存在常用库包静态方法列表中,则生成对应的单字节常量池索引的库包静态方法调用指令。
显然,本领域的技术人员可以对本发明进行各种改动和变型而不脱离本发明的精神和范围。这样,倘若本发明的这些修改和变型属于本发明权利要求及其同等技术的范围之内,则本发明也意图包含这些改动和变型在内。
- 一种字节码指令集精简方法和系统
- 一种微操作系统字节码精简指令集和资源受限装置