CN115495084A - 程序运行方法、装置以及相关设备 - Google Patents
程序运行方法、装置以及相关设备 Download PDFInfo
- Publication number
- CN115495084A CN115495084A CN202110673129.9A CN202110673129A CN115495084A CN 115495084 A CN115495084 A CN 115495084A CN 202110673129 A CN202110673129 A CN 202110673129A CN 115495084 A CN115495084 A CN 115495084A
- Authority
- CN
- China
- Prior art keywords
- function
- functions
- computer device
- stack frame
- proxy
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
- 238000000034 method Methods 0.000 title claims abstract description 72
- 230000006870 function Effects 0.000 claims abstract description 895
- 238000004590 computer program Methods 0.000 claims description 6
- 238000010586 diagram Methods 0.000 description 23
- 230000008569 process Effects 0.000 description 11
- 230000009471 action Effects 0.000 description 3
- 230000003068 static effect Effects 0.000 description 3
- 101100219321 Oryza sativa subsp. japonica CYP85A1 gene Proteins 0.000 description 2
- 230000008859 change Effects 0.000 description 2
- 239000003795 chemical substances by application Substances 0.000 description 2
- 230000009191 jumping Effects 0.000 description 2
- 238000005457 optimization Methods 0.000 description 2
- 238000003491 array Methods 0.000 description 1
- 238000001514 detection method Methods 0.000 description 1
- 239000000835 fiber Substances 0.000 description 1
- 238000004549 pulsed laser deposition Methods 0.000 description 1
- ZLIBICFPKPWGIZ-UHFFFAOYSA-N pyrimethanil Chemical compound CC1=CC(C)=NC(NC=2C=CC=CC=2)=N1 ZLIBICFPKPWGIZ-UHFFFAOYSA-N 0.000 description 1
- 239000010979 ruby Substances 0.000 description 1
- 229910001750 ruby Inorganic materials 0.000 description 1
- 238000006467 substitution reaction Methods 0.000 description 1
- 230000001360 synchronised effect Effects 0.000 description 1
- 230000001960 triggered effect Effects 0.000 description 1
- 239000002699 waste material Substances 0.000 description 1
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
- G06F8/44—Encoding
- G06F8/443—Optimisation
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
Landscapes
- Engineering & Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Software Systems (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Executing Machine-Instructions (AREA)
Abstract
本申请公开一种程序运行方法,应用于解释器。方法包括:通过第一代理栈帧解释执行N1个函数。N1为大于1的整数。其中,函数A是N1个函数中最后一个被解释执行的函数。函数A最多与N1个函数中的X1-1个函数组成调用链。X1为等于长度阈值的整数。长度阈值为第一代理栈帧所能解释执行的函数的调用链的长度的最大值。最大值大于1。通过第二代理栈帧解释执行N2个函数。N2个函数包括函数A调用的函数B。N2为大于0的整数。在本申请中,可以通过设置长度阈值来设置一个代理栈帧所能解释执行的函数的调用链的长度,从而增加灵活性。
Description
技术领域
本申请涉及解释器,尤其涉及一种程序运行方法、装置以及相关设备。
背景技术
解释器(Interpreter)是一种计算机程序,能够解释执行高级语言函数。解释器对高级语言函数的堆栈管理形式有Stackful格式。在Stackful格式中,解释器建立多个栈帧集合。栈帧集合包括内部函数栈帧和一个代理栈帧。内部函数栈帧用于解释执行解释器内部函数。解释器通过多个栈帧集合解释执行多个高级语言函数。
在实际应用中,Stackful格式的堆栈管理形式不够灵活。
发明内容
本申请提供了一种程序运行方法、装置以及相关设备。在本申请中,可以通过设置长度阈值来设置一个代理栈帧所能解释执行的函数的调用链的长度,从而增加灵活性。
本申请第一方面提供了一种程序运行方法。程序运行方法的执行主体可以是计算机设备,或计算机设备中的处理器,或计算机设备中的软件程序。软件程序可以是解释器,调试调优工具等。下面将以执行主体为计算机设备为例,对程序运行方法进行描述。程序运行方法包括以下步骤:计算机设备建立第一栈帧集合。第一栈帧集合包括第一代理栈帧和内部函数栈帧。计算机设备通过第一代理栈帧解释执行N1个函数,N1为大于1的整数。函数A是N1个函数中最后一个被解释执行的函数。函数A最多与N1个函数中的X1-1个函数组成调用链。X1为等于长度阈值的整数。长度阈值为第一代理栈帧所能解释执行的函数的调用链的长度的最大值,最大值大于1。例如,N1个函数包括函数A、函数T1、函数T2和函数T3。示例1,若函数T1调用函数T2(简写为T1-T2),函数T2调用函数T3(简写为T2-T3),函数T3调用函数A(简写为T3-A),则函数A与函数T1,函数T2、函数T3组成调用链T1-T2-T3-A。此时,N1为4,X1为4。示例2,若函数T1调用函数T2(简写为T1-T2),函数T2调用函数T3(简写为T2-T3),函数T3执行完成后返回函数T2,函数T2调用函数A(简写为T2-A),则函数A与函数T1、函数T2组成调用链T1-T2-A。此时,N1为4,X1为3。计算机设备通过第二代理栈帧解释执行N2个函数。N2个函数包括函数A调用的函数B。N2为大于0的整数。
在本申请中,可以通过设置长度阈值来设置一个代理栈帧所能解释执行的函数的调用链的长度,从而增加灵活性。
并且,本申请中的方案还具有以下优势:
首先,源代码和解释器内部函数形成堆栈。在Stackful格式的堆栈中,解释器内部函数重复执行,增加了堆栈溢出的风险。在本申请中,通过一个栈帧集合解释执行多个函数,可以减少解释器内部函数的执行次数,降低堆栈溢出的风险。具体地,在Stackful格式中,计算机设备通过多个栈帧集合解释执行多个函数。例如,源代码包括函数A调用函数B的信息。在Stackful格式中,计算机设备通过两个栈帧集合解释执行函数A和函数B。此时,计算机设备执行了两次解释器内部函数。在本申请中,计算机设备通过一个栈帧集合解释执行函数A和函数B。此时,计算机设备执行了一次解释器内部函数。因此,本申请可以减少解释器内部函数的执行次数,从而降低堆栈溢出的风险。
其次,在另一种堆栈管理形式,Stackless格式中,一个代理栈帧对应源代码中的所有的函数。源代码中所有的函数对应一个栈帧集合。例如,源代码包括函数A调用函数B的信息。计算机设备通过一个代理栈帧解释执行函数A和函数B。当源代码中函数的数量不确定时,代理栈帧分配的栈内存大小无法确定。因此,函数的部分数据必须保存在堆内存中,例如PC地址。并且,外部调优工具难以读取堆内存中的数据。因此Stackless格式不利于调试调优。在本申请中,第一代理栈帧所能解释执行的函数的调用链的长度的最大值为长度阈值。因此,通过设定长度阈值,有利于确定代理栈帧分配的栈内存大小,方便调试调优。
最后,本申请中的计算机设备以X1来衡量第一代理栈帧所能解释执行的函数数量。相比于计算机设备以N1来衡量第一代理栈帧所能解释执行的函数数量,可以进一步减少内部函数的执行次数,降低堆栈溢出的风险。
在第一方面的一种可选方式中,第一代理栈帧包括第一长度字段。第一长度字段记录有函数A与X1-1个函数组成的调用链的长度X1。在实际应用中,在第一代理栈帧中,N1的值随着第一代理栈帧解释执行的函数的数量逐步增加。在N1确定的情况下,X1的值的变化取决于源代码,例如在发生函数调用时,X1+1,发生函数返回时,X1-1。因此,相比于N1,确定X1的值较为困难。为此,本申请增加第一长度字段。第一长度字段用于实时记录X1的值。计算机设备根据第一长度字段中的值确定是否新建代理栈帧,提高新建代理栈帧的效率,进而提高程序运行效率。
在第一方面的一种可选方式中,第一长度字段位于第一代理栈帧的栈内存空间。其中,第一长度字段中的值X1除了可以用于和长度阈值对比,确定是否新建代理栈帧,还可以用于调试调优。因此,将第一长度字段记录在栈内存空间,方便调试调优。
在第一方面的一种可选方式中,第一代理栈帧的栈内存空间包括第一地址字段。第一地址字段包括X1个函数的程序计数器(Program Counter,PC)地址。每个函数对应一个PC地址。X1个函数的组成为函数A和X1-1个函数。在Stackless格式中,代理栈帧解释执行的函数的数量不确定,必须将PC地址放入堆内存。在本申请中,第一代理栈帧所能解释执行的函数的调用链的长度的最大值为长度阈值。因此,本申请可以将PC地址放入栈内存,方便调试调优。
在第一方面的一种可选方式中,在第一地址字段中,X1个函数的PC地址的排列顺序指示X1个函数的调用关系。其中,计算机设备可以在读取PC地址的同时,确定XI个函数的调用关系,提高调试调优的效率。
在第一方面的一种可选方式中,函数C是N2个函数中最后一个被解释执行的函数。函数C最多与N2个函数中的X2-1个函数组成的调用链。第二代理栈帧的栈内存空间包括第二地址字段。第二地址字段包括X2个函数的PC地址。X2个函数的组成为函数C和X2-1个函数。程序运行方法还包括以下步骤:计算机设备获取目标调用链。目标调用链包括第一调用链和第二调用链。第一调用链是X1个函数的PC地址在第一地址字段中的排列顺序。第二调用链是X2个函数的PC地址在第二地址字段中的排列顺序。目标调用链包括函数A调用函数B的信息。其中,通过第一地址字段和第二地址字段,计算机设备可以还原源代码的调用关系,即得到目标调用链。因此,本申请方便调试调优。
在第一方面的一种可选方式中,第一地址字段的内存大小为Z比特。其中,Z=M×P,M为长度阈值,单个PC地址的内存大小为P比特。其中,本申请为第一地址字段分配固定大小的存储空间。相比于计算机设备为第一地址字段分配随N1变化的存储空间,本申请可以节约存储空间。具体地,在实际应用中,当X1等于长度阈值时,N1的值取决于源代码。因此,N1的值不确定,既N1可能大于长度阈值。此时,计算机设备需要为第一地址字段分配随N1个PC地址的存储空间。当计算机设备为第一地址字段分配固定大小的存储空间时,计算机设备可以删除第一调用链以外的函数的PC地址。例如,在示例2中,在函数T3返回函数T2,函数T2调用函数A后,函数A的PC地址会覆盖函数T3的PC地址。此时,计算机设备只需要为第一地址空间分配M个PC地址的存储空间。因此,通过分配固定大小的存储空间,可以节约存储空间。
在第一方面的一种可选方式中,在通过第一代理栈帧解释执行N1个函数之后,程序运行方法还包括:计算机设备基于函数B,建立第二代理栈帧。其中,“基于”可以理解为函数B与第二代理栈帧相关。具体的实现可以是,在通过第一代理栈帧解释执行函数A的过程中,遇到调用函数B的函数调用指令,则计算机设备建立第二代理栈帧。也就是可以理解为,建立第二代理栈帧是由调用函数B的函数调用指令触发的,这是函数B与第二代理栈帧相关的表现。或者,从另一个角度说,第二代理栈帧中包括函数B,这是函数B与第二代理栈帧相关的表现。在实际应用中,计算机设备也可以提前建立多个代理栈帧。在遇到调用函数B的函数调用指令后,计算机设备将函数B的相关数据填入已经建好的代理栈帧。其中,在确定需要解释执行函数B后才建立第二代理栈帧,可以避免资源的浪费。应理解,函数调用指令属于函数A的指令。在计算机设备建立第二代理栈帧的过程中,函数B并未被计算机设备执行。计算机设备通过新建立的第二代理栈帧解释执行函数B。并且,此时计算机设备可能只是执行了函数A中的部分指令。在函数B返回函数A后,计算机设备继续执行函数A中的剩余指令。
在第一方面的一种可选方式中,在根据X1个PC地址在第一字段中的排列顺序建立X1个函数的第一调用链之前,程序运行方法还包括:计算机设备获取第一长度字段中记录的X1。计算机设备根据X1和P获取第一地址字段中X1×P比特的内容。X1×P比特的内容包括X1个PC地址。其中,计算机设备为第一地址字段分配了固定大小的存储空间。但是,在实际应用中,X1的值可以随当前函数的变化而变化。即在某个时刻,X1可能小于长度阈值。此时,若计算机设备根据第一地址字段中M×P比特的内容得到第一调用链,则可能得到错误的数据。因此,通过第一长度字段读取第一地址字段中X1×P比特的内容,可以提高获取的数据的准确性,从而提高调试调优的准确性。
在第一方面的一种可选方式中,第二代理栈帧所能解释执行的函数的调用链的长度的最大值为长度阈值。其中,通过设置相同的长度阈值,可以提高计算机设备确定是否新建栈帧集合的效率,进而提高计算机设备的运行效率。
在第一方面的一种可选方式中,程序运行方法还包括:当函数B返回函数A时,计算机设备销毁第二代理栈帧。具体地,当计算机设备只通过第二代理栈帧解释执行了函数B时,在解释执行完函数B后,函数B会返回函数A。当计算机设备通过第二代理栈帧解释执行了多个函数时,函数B调用的函数会返回至函数B,然后函数B返回函数A。例如多个函数包括函数B、函数C和函数D。函数B调用函数C,函数C调用函数D。在计算机设备解释执行完函数D后,函数D返回函数C。在计算机设备解释执行完函数C后,函数C返回函数B。在计算机设备解释执行完函数B后,函数B返回函数A。其中,通过销毁第二代理栈帧,可以节约计算机设备的存储空间。
在第一方面的一种可选方式中,长度阈值的范围为10至20。其中,当长度阈值过大时,一个代理栈帧需要消耗过大的栈内存空间,例如地址字段。当长度阈值过小时,计算机设备可能重复新建第二代理栈帧,降低程序运行效率。为此,本申请限定长度阈值的范围为10至20。此时,计算机设备可以在保证程序运行效率的基础上,降低一个代理栈帧消耗的栈内存空间。
在第一方面的一种可选方式中,程序运行方法还包括:计算机设备根据第一代理栈帧的基地址和第一偏移量获取第一地址字段的地址。计算机设备根据第二代理栈帧的基地址和第二偏移量获取第二地址字段的地址。第一偏移量等于第二偏移量。其中,通过设置相同的偏移量,可以提高调试调优工具获取PC地址的效率。
本申请第二方面提供了一种程序运行装置。程序运行装置包括第一解释执行模块、建立模块和第二解释执行模块。其中,第一解释执行模块用于通过第一代理栈帧解释执行N1个函数。其中,函数A是N1个函数中最后一个被解释执行的函数。函数A最多与N1个函数中的X1-1个函数组成调用链。X1为等于长度阈值的整数。长度阈值为第一代理栈帧所能解释执行的函数的调用链的长度的最大值。最大值大于1。第二解释执行模块用于通过第二代理栈帧解释执行N2个函数。N2个函数包括函数A调用的函数B。N2为大于0的整数。
在第二方面的一种可选方式中,第一代理栈帧包括第一长度字段。第一长度字段记录有函数A与X1-1个函数组成的调用链的长度X1。
在第二方面的一种可选方式中,第一长度字段位于第一代理栈帧的栈内存空间。
在第二方面的一种可选方式中,第一代理栈帧的栈内存空间包括第一地址字段。第一地址字段包括X1个函数的X1个PC地址,X1个函数包括函数A和X1-1个函数。
在第二方面的一种可选方式中,在第一地址字段中,X1个函数的PC地址的排列顺序指示X1个函数的调用关系。
在第二方面的一种可选方式中,函数C是N2个函数中最后一个被解释执行的函数。函数C最多与N2个函数中的X2-1个函数组成调用链。第二代理栈帧的栈内存空间包括第二地址字段。第二地址字段包括X2个函数的PC地址。X2个函数的组成为函数C和X2-1个函数。程序运行装置还包括获取模块。获取模块用于获取目标调用链。目标调用链包括第一调用链和第二调用链。第一调用链是X1个函数的PC地址在第一地址字段中的排列顺序。第二调用链是X2个函数的PC地址在第二地址字段中的排列顺序。其中,目标调用链包括函数A调用函数B的信息。
在第二方面的一种可选方式中,第一地址字段的内存大小为Z比特。其中,Z=M×P。M为长度阈值。单个PC地址的内存大小为P比特。
在第二方面的一种可选方式中,获取模块还用于获取第一长度字段中记录的X1。获取模块还用于根据X1和P获取第一地址字段中X1×P比特的内容。X1×P比特的内容包括X1个PC地址。
在第二方面的一种可选方式中,程序运行装置还包括建立模块。建立模块用于基于函数B,建立第二代理栈帧。
在第二方面的一种可选方式中,第二代理栈帧所能解释执行的函数的调用链的长度的最大值为长度阈值。
在第二方面的一种可选方式中,长度阈值的范围为10至20。
本申请第三方面提供了一种计算机设备。计算机设备包括处理器和存储器。存储器中存储有指令。处理器用于运行指令,使得处理器通过第一代理栈帧解释执行N1个函数。其中,函数A是N1个函数中最后一个被解释执行的函数。函数A最多与N1个函数中的X1-1个函数组成调用链。X1为等于长度阈值的整数。长度阈值为第一代理栈帧所能解释执行的函数的调用链的长度的最大值。最大值大于1。处理器还用于通过第二代理栈帧解释执行N2个函数。N2个函数包括函数A调用的函数B。N2为大于0的整数。
在第三方面的一种可选方式中,第一代理栈帧包括第一长度字段。第一长度字段记录有函数A与X1-1个函数组成的调用链的长度X1。
在第三方面的一种可选方式中,第一长度字段位于第一代理栈帧的栈内存空间。
在第三方面的一种可选方式中,第一代理栈帧的栈内存空间包括第一地址字段。第一地址字段包括X1个函数的程序计数器PC地址。X1个函数的组成为函数A和X1-1个函数。
在第三方面的一种可选方式中,在第一地址字段中,X1个函数的PC地址的排列顺序指示X1个函数的调用关系。
在第三方面的一种可选方式中,函数C是N2个函数中最后一个被解释执行的函数。函数C最多与N2个函数中的X2-1个函数组成调用链。第二代理栈帧的栈内存空间包括第二地址字段。第二地址字段包括X2个函数的PC地址。X2个函数的组成为函数C和X2-1个函数。处理器还用于获取目标调用链。目标调用链包括第一调用链和第二调用链,第一调用链是X1个函数的PC地址在第一地址字段中的排列顺序。第二调用链是X2个函数的PC地址在第二地址字段中的排列顺序。其中,目标调用链包括函数A调用函数B的信息。
在第三方面的一种可选方式中,第一地址字段的内存大小为Z比特;其中,Z=M×P,M为长度阈值,单个PC地址的内存大小为P比特。
在第三方面的一种可选方式中,处理器还用于基于函数B,建立第二代理栈帧。
在第三方面的一种可选方式中,第二代理栈帧所能解释执行的函数的调用链的长度的最大值与长度阈值相等。
在第三方面的一种可选方式中,长度阈值的范围为10至20。
本申请第四方面提供了一种计算机存储介质,其特征在于,所述计算机存储介质中存储有指令,所述指令在计算机设备上执行时,使得所述计算机设备执行如第一方面或第一方面任意一种实施方式所述的方法。
本申请第五方面提供了一种计算机程序产品,其特征在于,所述计算机程序产品在计算机设备上执行时,使得所述计算机设备执行如第一方面或第一方面任意一种实施方式所述的方法。
附图说明
图1为本申请中提供的源代码的第一个结构示意图;
图2为Stackful格式的堆栈的结构示意图;
图3为Stackless格式的堆栈的结构示意图;
图4为本申请中提供的堆栈的第一个结构示意图;
图5为本申请中提供的程序运行方法的流程示意图;
图6为本申请中提供的源代码的第二个结构示意图;
图7为本申请中提供的调用链的一个结构示意图;
图8为本申请中提供的栈帧集合的一个结构示意图;
图9为本申请中提供的源代码的第三个结构示意图;
图10为本申请中提供的堆栈的第二个结构示意图;
图11为本申请中提供的程序运行装置的结构示意图;
图12为本申请中提供的计算机设备的结构示意图。
具体实施方式
本申请提供了一种程序运行方法、装置以及相关设备,通过在一个栈帧集合解释执行多个函数,可以减少解释器内部函数的执行次数,降低堆栈溢出的风险。应理解,本申请中使用的“第一”、“第二”等仅用于区分描述的目的,而不能理解为指示或暗示相对重要性,也不能理解为指示或暗示顺序。另外,为了简明和清楚,本申请多个附图中重复参考编号和/或字母。重复并不表明各种实施例和/或配置之间存在严格的限定关系。为了方便理解本申请中的技术方案,下面对本申请中出现的一些专业术语进行描述。
计算机语言的执行方式主要包括解释执行和编译执行。在编译执行过程中,计算机设备会先将源代码编译成目标程序。目标程序一般是机器码。然后计算机设备执行目标程序。在解释执行过程中,计算机设备边解释边执行源代码。在解释执行的过程中,不生成目标程序。
解释器(Interpreter)又称为直译器,是一种计算机程序。解释器用于在解释执行高级语言函数。解释器的种类有Perl解释器、Python解释器、JVM(Java Virtual Machine)、Art(Android runtime)等。
高级语言函数也称为解释执行函数,是指采用高级语言描述的函数代码。本申请中的高级语言是指除了机器码以外的任意语言。例如字节码、Java、JavaScript、Swift、Python、Ruby、Scala、BASIC、JAVA、C、C++、python等。在本申请中,机器码描述的函数代码也称为编译执行函数、编译函数或静态化函数,例如Native函数。例如,在Java语言中,Native函数是JNI中的C/C++函数。在本申请中,未表明是编译函数的函数都为高级语言函数。例如,函数T101为高级语言函数。编译函数1为编译函数。
栈帧(Stack Frame)是一种数据结构。栈帧可以存储函数的局部变量表、操作数栈、动态连接、方法返回地址、或额外的附加信息等。在程序运行过程中,每一次函数的调用,计算机设备都会在堆栈上维护一个栈帧。
栈帧集合包括代理栈帧和内部函数栈帧。代理栈帧用于维护高级语言函数的数据结构,即计算机设备通过代理栈帧解释执行高级语言函数。内部函数栈帧用于维护解释器内部函数的数据结构。解释器内部函数也称为内部函数。内部函数是在代理栈帧执行之前,一些必要的处理函数。例如程序逻辑如何运行到代理栈帧的内部函数,代理栈帧创建前初始化相关的一些内部函数。
计算机设备对高级语言函数的堆栈管理形式有Stackful格式和Stackless格式。在Stackful格式中,计算机设备为多个高级语言函数建立多个栈帧集合。多个栈帧集合和多个高级语言函数一一对应。在Stackless格式中,计算机设备为多个高级语言函数建立一个栈帧集合。计算机设备通过一个栈帧集合中的代理栈帧运行多个高级语言函数。下面结合具体的源代码对Stackful格式、Stackless格式的堆栈进行描述。
图1为本申请中提供的源代码的第一个结构示意图。如图1所示,源代码101包括多个高级语言函数。多个高级语言函数包括函数T1、函数T2、…、函数T(M-1)、函数A、函数B、…。M为大于1的整数。多个高级语言函数的调用关系如图1中的箭头所示。具体地,根据图1可知,函数T1调用函数T2、函数T(M-1)调用函数A、函数A调用函数B。
在Stackful格式中,计算机设备为源代码中的多个高级语言函数建立多个栈帧集合。具体地,图2为Stackful格式的堆栈的结构示意图。如图2所示,堆栈包括栈帧集合201、栈帧集合202和栈帧集合203。堆栈的运行方向如图2中的箭头所示。其中,栈帧集合201中的代理栈帧T1用于维护函数T1的数据结构,或者说计算机设备通过代理栈帧T1解释执行函数T1。类似的,栈帧集合202中的代理栈帧A用于维护函数A的数据结构。栈帧集合203中的代理栈帧B用于维护函数B的数据结构。应理解,在图2,通过“…”隐含了一些栈帧集合。图2中栈帧集合的数量和图1中的高级语言函数的数量相等,并且多个栈帧集合和多个高级语言函数一一对应。
在Stackless格式中,计算机设备为源代码中的多个高级语言函数建立一个栈帧集合。具体地,图3为Stackless格式的堆栈的结构示意图。如图3所示,堆栈的运行方向如图3中的箭头所示。堆栈包括栈帧集合301。栈帧集合301包括内部函数栈帧和代理栈帧。代理栈帧用于维护函数T1、函数T2、…、函数T(M-1)、函数A、函数B的数据结构,即计算机设备通过一个代理栈帧运行了图1中的所有高级语言函数。
根据图2可知,在Stackful格式的堆栈中,内部函数重复执行,增加了堆栈溢出的风险。根据图3可知,计算机设备通过一个代理栈帧解释执行的高级语言函数的数量取决于源代码中高级语言函数的数量。并且,代理栈帧分配的栈内存大小与代理栈帧解释执行的高级语言函数的数量相关。在源代码不确定的情况下,无法确定计算机设备通过一个代理栈帧解释执行的高级语言函数的数量,即无法确定代理栈帧分配的栈内存大小。因此,高级语言函数的部分数据必须保存在堆内存中,例如PC地址。并且,外部调优工具难以读取堆内存中的数据。因此Stackless格式不利于调试调优。
为此,本申请提供了一种程序运行方法。在程序运行方法中,计算机设备通过第一代理栈帧解释执行N1个高级语言函数。N1为大于1的整数。其中,函数A是N1个高级语言函数中最后一个被解释执行的高级语言函数。函数A最多与N1个高级语言函数中的X1-1个函数组成调用链。X1为大于1的整数。在X1大于或等于长度阈值时,若函数A调用函数B,函数B为高级语言函数,则计算机设备建立第二代理栈帧。长度阈值为第一代理栈帧所能解释执行的高级语言函数的调用链的长度的最大值。计算机设备通过第二代理栈帧解释执行函数B。
计算机设备通过程序运行方法运行图1中的源代码,可以得到另一种格式的堆栈。在另一种格式的堆栈中,计算机设备为多个高级语言函数建立少于高级语言函数的数量的栈帧集合。具体地,图4为本申请中提供的堆栈的第一个结构示意图。如图4所示,堆栈的运行方向如图4中的箭头所示。堆栈包括栈帧集合401和栈帧集合402。栈帧集合401包括内部函数栈帧和代理栈帧1(也称为第一代理栈帧)。计算机设备通过代理栈帧1解释执行M个高级语言函数。例如,M个高级语言函数包括函数T1、函数T2、…、函数T(M-1)和函数A。栈帧集合402包括内部函数栈帧和代理栈帧2(也称为第二代理栈帧)。计算机设备通过代理栈帧2解释执行一个或多个高级语言函数。一个或多个高级语言函数包括函数B。当M等于2时,图1中的源代码至少包括三个高级语言函数。三个高级语言函数分别是函数T1、函数A和函数B。此时,在图4中,堆栈包括2个栈帧集合。因此,在本申请中,栈帧集合的数量少于高级语言函数的数量。
本申请中一个栈帧集合解释执行多个高级语言函数。因此,本申请可以减少解释器内部函数的执行次数,降低堆栈溢出的风险。并且,第一代理栈帧所能解释执行的高级语言函数的调用链的长度的最大值为长度阈值M。因此,通过设定长度阈值M,有利于确定代理栈帧分配的栈内存大小,方便调试调优。
上面对采用本申请中的程序运行方法得到的堆栈结构进行了示例性的描述。本申请中,程序运行方法的执行主体可以是计算机设备,或计算机设备中的处理器,或计算机设备中的软件程序。软件程序可以是解释器,调试调优工具等。在本申请中,将以执行主体为计算机设备为例对程序运行方法进行描述。图5为本申请中提供的程序运行方法的流程示意图。如图5所示,本申请中的程序运行方法包括以下步骤。
在步骤501中,计算机设备开始运行程序。程序也称为源代码。
在步骤502中,计算机设备新建代理栈帧。计算机设备新建代理栈帧也可以理解为计算机设备新建栈帧集合。计算机设备后续通过新建的代理栈帧解释执行程序中的一个高级语言函数。一个高级语言函数为当前函数。
在步骤503中,计算机设备初始化X。例如计算机设备设置X等于1。
在步骤504中,计算机设备获取当前函数的当前指令。计算机设备按照当前函数中的指令顺序解释执行当前函数。计算机设备获取将要解释执行的指令。
在步骤505中,计算机设备确定当前指令是否为函数调用指令。若当前指令是函数调用指令,则执行步骤506。若当前指令不是函数调用指令,则执行步骤509。函数调用指令可以是invoke-static或invoke-direct等。例如invoke-static{v2},A(int)表示通过静态方法调用函数A。invoke-direct{v0},B()表示通过非静态方法调用调用函数B。
在步骤506中,计算机设备将被调用的函数作为当前函数。当前指令为函数调用指令时,函数调用指令中有被调用函数的函数ID。计算机设备通过函数ID找到被调用的函数。
在步骤507中,计算机设备将X+1。
在步骤508中,计算机设备确定X是否大于M。若X大于M,则执行步骤502。若X小于或等于M,则执行步骤504。
在步骤509中,计算机设备确定当前指令是否为函数返回指令。若当前指令是函数调用指令,则执行步骤513。若当前指令不是函数调用指令,则执行步骤510。
在步骤510中,计算机设备执行当前指令。当前指令可以是move、const、return、算术逻辑运算、跳转、函数调用等指令。
在步骤511中,计算机设备确定程序是否结束。若程序结束,则执行步骤517。若程序未结束,则执行步骤512。
在步骤512中,计算机设备移动程序代码计算器,将当前指令的下一条指令作为当前指令。
在步骤513中,计算机设备将X-1。
在步骤514中,计算机设备确定X是否小于1。若X小于1,则执行步骤515。若X大于或等于1,则执行步骤516。
在步骤515中,计算机设备跳转到前一个代理栈帧。计算机设备设置X=M。
在步骤516中,计算机设备将返回的函数作为当前函数。返回的函数一般是调用当前函数的函数。
在步骤517中,计算机设备停止运行程序。
应理解,图5中所示的程序运行方法的流程图只是一个示例。在实际运用中,本领域技术人员可以根据需要对流程进行适应性的改变。例如,在步骤503中,计算机设备初始化X,将X设置为0。此时,在步骤508中,计算机设备确定X是否等于M。若X等于M,则执行步骤502。若X不等于M,则执行步骤504。
上面对本申请中的程序运行方法的流程进行了描述。图6为本申请中提供的源代码的第二个结构示意图。如图6所示,源代码包括函数T1、函数C1、函数C2、函数T2、…、函数T(M-1)、函数C3、函数A、函数B、…。计算机设备按照从上到下,从左到右的顺序执行源代码。具体地,计算机设备先执行函数T1。函数T1调用函数C1。计算机设备执行函数C1。函数C1调用函数C2。计算机设备执行函数C2。在函数C2返回至函数C1,函数C1返回至函数T1后,函数T1调用函数T2,函数T2调用函数下一函数,后面的执行顺序可以以此类推。下面结合图6中的源代码,对本申请中的程序运行方法进行描述。当计算机设备根据图5中的程序运行方法执行图6中的源代码时,程序运行方法包括以下步骤。
在步骤501中,计算机设备开始运行程序。程序为图6中的源代码。假设M等于10。
在步骤502中,计算机设备建立第一代理栈帧。计算机设备将函数T1作为当前函数。
在步骤503中,计算机设备设置X等于1。
在步骤504中,计算机设备获取函数T1的第一个指令。计算机设备将函数T1的第一个指令作为当前指令。为了方便描述,假设图6中的每个高级语言函数只包括函数调用指令和/或函数返回指令。函数T1的第一个指令为函数调用指令。函数调用指令调用函数C1。
在步骤505中,计算机设备确定当前指令是函数调用指令,执行步骤506。
在步骤506中,计算机设备将函数C1作为当前函数。
在步骤507中,计算机设备将X+1。此时,X等于2。
在步骤508中,由于M等于10,计算机设备确定X不大于M,执行步骤504。
在步骤504中,计算机设备获取函数C1的第一个指令。计算机设备将函数C1的第一个指令作为当前指令。函数C1的第一个指令为函数调用指令。函数调用指令调用函数C2。
在步骤505中,计算机设备确定当前指令是函数调用指令,执行步骤506。
在步骤506中,计算机设备将函数C2作为当前函数。
在步骤507中,计算机设备将X+1。此时,X等于3。
在步骤508中,计算机设备确定X不大于M,执行步骤504。
在步骤504中,计算机设备获取函数C2的第一个指令。计算机设备将函数C2的第一个指令作为当前指令。函数C2的第一个指令为函数返回指令。
在步骤505中,计算机设备确定当前指令不是函数调用指令,执行步骤509。
在步骤509中,计算机设备确定当前指令是函数返回指令,执行步骤513。
在步骤513中,计算机设备将X-1。此时,X等于2。
在步骤514中,计算机设备确定X大于或等于0,执行步骤516。
在步骤516中,计算机设备将函数C1作为当前函数。
在步骤504中,计算机设备获取函数C1的第二个指令。计算机设备将函数C1的第二个指令作为当前指令。函数C1的第二个指令为函数返回指令。
在步骤505中,计算机设备确定当前指令不是函数调用指令,执行步骤509。
在步骤509中,计算机设备确定当前指令是函数返回指令,执行步骤513。
在步骤513中,计算机设备将X-1。此时,X等于1。
在步骤514中,计算机设备确定X大于或等于1,执行步骤516。
在步骤516中,计算机设备将函数T1作为当前函数。
在步骤504中,计算机设备获取函数T1的第二个指令。计算机设备将函数T1的第二个指令作为当前指令。函数T1的第二个指令为函数调用指令。函数调用指令调用函数T2。
在步骤505中,计算机设备确定当前指令是函数调用指令,执行步骤506。
在步骤506中,计算机设备将函数T2作为当前函数。
在步骤507中,计算机设备将X+1。此时,X等于2。
在步骤508中,计算机设备确定X不大于M,执行步骤504。
在步骤504中,计算机设备获取函数T2的第一个指令。计算机设备将函数T2的第一个指令作为当前指令。函数T2的第一个指令为函数调用指令。函数调用指令调用函数T3。
迭代的执行步骤504至步骤508,直到计算机设备将函数T(M-1)作为当前函数,即计算机设备将函数T9作为当前函数。此时,X等于9。
在步骤508中,计算机设备确定X不大于M,执行步骤504。
在步骤504中,计算机设备获取函数T9的第一个指令。计算机设备将函数T9的第一个指令作为当前指令。函数T9的第一个指令为函数调用指令。函数调用指令调用函数A。
在步骤505中,计算机设备确定当前指令是函数调用指令,执行步骤506。
在步骤506中,计算机设备将函数A作为当前函数。
在步骤507中,计算机设备将X+1。此时,X等于10。
在步骤508中,计算机设备确定X不大于M,执行步骤504。
在步骤504中,计算机设备获取函数A的第一个指令。计算机设备将函数A的第一个指令作为当前指令。函数A的第一个指令为函数调用指令。函数调用指令调用函数C3。
在步骤505中,计算机设备确定当前指令是函数调用指令,执行步骤506。
在步骤506中,计算机设备将函数C3作为当前函数。
在步骤507中,计算机设备将X+1。此时,X等于11。
在步骤508中,计算机设备确定X大于M,执行步骤502。
在步骤502中,计算机设备建立第二代理栈帧。
在步骤503中,计算机设备设置X等于1。
在步骤504中,计算机设备获取函数C3的第一个指令。计算机设备将函数C3的第一个指令作为当前指令。函数C3的第一个指令为函数返回指令。
在步骤505中,计算机设备确定当前指令不是函数调用指令,执行步骤509。
在步骤509中,计算机设备确定当前指令是函数返回指令,执行步骤513。
在步骤513中,计算机设备将X-1。此时,X等于0。
在步骤514中,计算机设备确定X小于1,执行步骤515。
在步骤515中,计算机设备跳转到第一代理栈帧。计算机设备销毁第二代理栈帧。计算机设备设置X等于10。
在步骤516中,计算机设备将函数A作为当前函数。
在步骤504中,计算机设备获取函数A的第二个指令。计算机设备将函数A的第二个指令作为当前指令。函数A的第二个指令为函数调用指令。函数调用指令调用函数B。应理解,此时,函数B并未被计算机设备执行。在后续的步骤504中,计算机设备才开始执行函数B。
在步骤505中,计算机设备确定当前指令是函数调用指令,执行步骤506。
在步骤506中,计算机设备将函数B作为当前函数。
在步骤507中,计算机设备将X+1。此时,X等于11。
在步骤508中,计算机设备确定X大于M,执行步骤502。
在步骤502中,计算机设备建立第二代理栈帧。
在步骤503中,计算机设备设置X等于1。
在步骤504中,计算机设备获取函数B的第一个指令。计算机设备将函数B的第一个指令作为当前指令。函数B的第一个指令为函数调用指令。计算机设备根据函数调用指令继续执行步骤505。
应理解,前面只是以图6中的源代码为例,对本申请中的程序运行方法进行描述。在实际应用中,程序运行方法还可以运行其他的源代码,例如图1中的源代码。
在本申请中,N为代理栈帧总的解释执行的高级语言函数的数量。对于不同的代理栈帧,可以有不同的N。为了方便描述,将第一代理栈帧总的解释执行的高级语言函数的数量称为N1,将第二代理栈帧总的解释执行的高级语言函数的数量称为N2。应理解,N1中可以包括重复的函数,重复的函数单独计数一次。例如源代码包括函数A调用函数B,函数B调用函数C,函数C调用函数B时,N1为4。类似地,X为代理栈帧中最后一个被解释执行的函数与N个高级语言函数组成的调用链的最大长度。X1为第一代理栈帧中最后一个被解释执行的函数与N1个高级语言函数组成的调用链的最大长度。X2为第二代理栈帧中最后一个被解释执行的函数与N2个高级语言函数组成的调用链的最大长度。在实际应用中,X1和N1可能不同,X1和N1也可能相同。例如在图1的源代码中,对于任意的当前函数,X1和N1相同。例如在图6的源代码中,当前函数为函数C1时,X1和N1相同;当前函数为函数T2时,X1和N1不相同。
在本申请的程序运行方法中,若当前指令为函数返回指令,则计算机设备会将X-1。在实际应用中,计算机设备在遇到异常时,计算机设备为了处理异常,也可能发生函数返回的情况。此时,计算机设备根据函数返回的层数,相应的将X减去层数。例如,当前函数为函数C2时,程序发生异常。计算机设备从函数C2返回至函数T1处理异常。此时,函数返回的层数为2。计算机设备将X1减去2。在将X减去层数后,若X的值小于1,则计算机设备销毁当前代理栈帧。例如,当前函数为函数B时,程序发生异常。计算机设备从函数B返回至函数T2处理异常。此时,函数返回的层数为M-1。当M为10时,M-1的值为9。计算机设备将X2减去9,得到X2等于负8。X2的值小于1,计算机设备销毁第二代理栈帧,返回第一代理栈帧。在返回第一代理栈帧后,计算机设备将X1减去剩余的层数。剩余的层数为第一代理栈帧中的最后一个被解释执行的函数返回至处理异常的函数的层数。在本示例中,剩余的层数为函数A返回至函数T2的层数。剩余的层数为8。计算机设备将X1减去8,得到X1等于2。
在本申请的程序运行方法中,随着函数的调用链的长度增加,X的值不断增加。在实际应用中,源代码可能包括编译函数,即高级语言函数可能会调用编译函数,此时,X的值不变。例如,在图6中,在当前函数为函数B时,X2等于1。在函数B调用编译函数1时,X2的值不变。计算机设备建立编译函数栈帧,通过编译函数栈帧执行编译函数1。此时,计算机设备通过第二代理栈帧解释执行的高级语言函数的数量为1,既N2等于1,X2等于1。
在其实实施例中,当长度阈值M过大时,一个代理栈帧需要消耗过大的栈内存空间,例如地址字段。当长度阈值M过小时,计算机设备可能重复新建第二代理栈帧,降低程序运行效率。例如,当采用本申请中的程序运行方法执行图6中的源代码时,若M等于10,则在计算机设备解释执行函数A以前,计算机设备不需要建立第二代理栈帧。若M等于2,则在计算机设备需要建立两次第二代理栈帧。具体地,在计算机设备解释执行函数C2前,计算机设备需要新建第二代理栈帧,通过第二代理栈帧解释执行函数C2。在函数C2返回函数C1后,计算机设备销毁第二代理栈帧。在函数T2调用函数A时,计算机设备需要新建第二代理栈帧,通过第二代理栈帧解释执行函数A。因此,本申请限定长度阈值的范围为10至20。此时,计算机设备可以在保证程序运行效率的基础上,降低一个代理栈帧消耗的栈内存空间。
在本申请中,在某一时刻,当前代理栈帧总的解释执行了N个高级语言函数。当前函数为N个高级语言函数中最后一个被解释执行的高级语言函数。X为当前函数与N个高级语言函数组成的最长的调用链的长度,即当前函数最多与N个高级语言函数中的X-1高级语言函数组成调用链。例如,在当前代理栈帧为第一代理栈帧。当前函数为函数C1时,N1等于2,N1个高级语言函数包括函数T1和函数C1。函数C1最多与函数T1组成调用链,X1为2。当前函数为函数A时,N1等于12,N1个高级语言函数包括函数T1、函数T2、…、函数T9、函数A和函数C1、函数C2。函数A最多与函数T1、函数T2、…、函数T9组成调用链,X1为10。
在本申请的程序运行方法中,计算机设备以X来衡量代理栈帧所能解释执行的函数数量。相比于计算机设备以N来衡量代理栈帧所能解释执行的函数数量,可以进一步减少内部函数的执行次数,降低堆栈溢出的风险。例如,在M等于10的情况下,当计算机设备以X1来衡量第一代理栈帧所能解释执行的函数数量时,计算机设备在跳转到函数C3时新建代理栈帧。此时,第一代理栈帧总的解释执行了12个高级语言函数。12个高级语言函数包括函数T1、函数T2、…、函数T9、函数A和函数C1、函数C2。在M相同的情况下,当计算机设备以N1来衡量第一代理栈帧所能解释执行的函数数量时,计算机设备在跳转到函数T9时新建代理栈帧。此时,第一代理栈帧总的解释执行了10个高级语言函数。10个高级语言函数包括函数T1、函数T2、…、函数T8和函数C1、函数C2。因此,计算机设备可以通过一个代理栈帧解释执行更多的高级语言函数,从而减少内部函数的执行次数。
根据前面的描述可知,N的值随着代理栈帧解释执行的函数的数量逐步增加,而X的值的变化取决于源代码。因此,X和N的值可能不同。计算机设备不能简单的根据N的值得到X的值。为此,计算机设备可以维护长度字段。长度字段中记录有X的值。例如计算机设备可以维护第一长度字段。第一长度字段中记录有X1的值。当计算机设备在执行步骤503、步骤513、或步骤507时,计算机设备实时更新X1的值。当计算机设备在执行步骤508或步骤514时,计算机设备从第一长度字段中读取X1的值,根据X1的值进行相应处理。为了方便调试调优,计算机设备可以在第一代理栈帧的栈内存空间中分配第一长度字段。应理解,计算机设备还可以在第一代理栈帧的堆内存,或其它内存空间中分配第一长度字段。调试调优包括数据读取和调优过程。数据读取是指计算机设备通过调试调优工具读取堆栈信息。调试调优工具Simpleperf,Debugger等。下面以堆栈信息为PC地址为例,对调试调优的过程进行相应描述。
首先,计算机设备维护一个第一地址字段。第一地址字段位于第一代理栈帧的栈内存空间。第一地址字段的内存大小为Z比特。其中,Z=M×P,M为长度阈值。单个PC地址的内存大小为P比特。第一地址字段包括M个PC地址字段。每个PC地址字段可以记录一个PC地址。当M等于10时,M个PC地址字段包括地址字段1、地址字段2、…、地址字段10。第一地址字段中记录有X1个函数的X1个PC地址。X1个函数包括当前函数和X1-1个函数。例如,以图6为例,在当前函数为函数C1时,X1个函数包括函数C1和函数T1。X1个PC地址包括函数C1和函数T1的PC地址。在当前函数为函数A时,X1个函数包括函数T1、函数T2、…、函数T9和函数A。X1个PC包括函数T1、函数T2、…、函数T9和函数A的PC地址。应理解,当前函数只能属于当前代理栈帧解释执行的函数。当计算机设备新建第二代理栈帧后,对于第一代理栈帧而言,当前函数也可以理解为X1个函数中最后一个被执行的函数。
根据前面的描述可知,N1可能大于X1。当X1等于M时,N1可能会大于M。而第一地址字段中最多记录M个PC地址。为此,计算机设备可以删除X1个函数以外的函数的PC地址。例如,在当前函数为函数T2时,X1个函数包括函数T1、函数T2。此时,计算机设备通过第一代理栈帧总的解释执行了N1个高级语言函数。N1个高级语言函数包括函数T1、函数T2和函数C1、函数C2。计算机设备可以删除第一地址字段中函数C1和函数C2的PC地址。
然后,计算机设备读取第一地址字段中的X1个PC地址,根据X1个PC地址在第一地址字段中的排列顺序建立X1个函数的第一调用链。具体地,在第一设备读取到X1个PC地址后,第一设备可以进一步根据X1个PC地址读取到X1个函数的函数名。根据X1个PC地址在第一地址字段中的排列顺序建立X1个函数的第一调用链。X1个PC地址的排列顺序可以和X1个函数的调用链顺序相同。此时,当前函数为函数C1时,第一调用链包括:函数T1调用函数C1。当前函数为函数A时,第一调用链包括:函数T1调用函数T2、函数T2调用函数T3、…、函数T9调用函数A。
类似地,计算机设备可以维护一个第二地址字段。第二地址字段中记录有X2个函数的X2个PC地址。X2个函数包括函数C和X2-1个函数。函数C是N2个高级语言函数中最后一个被解释执行的函数。函数C最多与N2个高级语言函数中的X2-1个函数组成调用链。例如,在图6中,在函数C为函数B时,X2等于1。X2个函数包括函数B。X2个PC包括函数B的PC地址。计算机设备读取第二地址字段中的X2个PC地址,根据X2个PC地址在第二地址字段中的排列顺序建立X2个函数的第二调用链。
在计算机设备建立第二代理栈帧后,计算机设备可以获取第一调用链和第二调用链。通过连接第一调用链和第二调用链,计算机设备可以得到目标调用链。图7为本申请中提供的调用链的一个结构示意图。如图7所示,目标调用链包括第一调用链701和第二调用链。第一调用链701包括函数T1调用函数T2、函数T2调用函数T3、…、函数T9调用函数A。第二调用链702包括函数B,或还包括函数B调用其他函数的信息。目标调用链包括体现函数A调用函数B的信息。
最后,计算机设备根据调用链进行调试调优。在实际应用中,计算机设备可以随着程序的运行实时获取不同时刻的调用链。将不同时刻的调用链进行叠加,得到类似图4中的火焰图。通过分析火焰图,可以对程序进行调试调优。例如,在图4中,Z为时间。函数运行的时间与函数在Z轴上长度成正比。通过分析函数运行的时间,可以对相应的函数进行调试调优。
前面以PC地址为例,对程序的调试调优进行了描述。类似地,堆栈信息还可以是其他的内容。例如,堆栈信息是函数的代码量大小。具体地,计算机设备维护一个第一代码字段。第一代码字段位于第一代理栈帧的栈内存空间。第一代码字段中记录有X1个函数的X1个代码量。X1个函数和X1个代码量一一对应。X1个函数包括当前函数和X1-1个函数。例如,以图6为例,在当前函数为函数C1时,X1个函数包括函数C1和函数T1。X1个代码量包括函数C1和函数T1的代码量大小。计算机设备读取第一字段中的X1个代码量,根据X1个代码量确定X1个函数的代码量大小。之后,计算机设备根据X1个代码量对程序进行调试调优。例如,计算机设备确定代码量小于目标阈值的目标函数。计算机设备对目标函数进行内联优化或函数编译。函数编译是指将目标函数编译为机器码。
在其他实施例中,代码字段还包括X个函数名。X个函数名和X个代码量一一对应。X个函数名和X个函数一一对应。此时,计算机设备通过读取代码字段,便可以确定目标函数,从而提高计算机设备通过代码字段进行调试调优的效率。
随着源代码包括的高级语言函数的数量的增加,计算机设备可以新建更多的代理栈帧。每个代理栈帧都可以对应一个地址字段和/或一个代码字段。进一步地,计算机设备还可以同时利用地址字段和代码字段对程序进行调试调优。具体地,在计算机设备通过代码字段中的内容确定目标函数后,计算机设备还可以根据地址字段得到源代码的调用关系。根据源代码的调用关系确定目标函数被解释执行的次数。例如,当函数C1为目标函数,函数C1和函数A为相同的函数时,计算机设备在运行图6中的程序的过程中,计算机设备运行了两次目标函数。计算机设备对被解释执行的次数大于一定阈值的目标函数进行内联优化或函数编译。
根据前面的描述可知,一个地址字段包括M×P比特的内存大小。一个地址字段最多可以记录M个PC地址。在实际应用中,一个地址字段可能记录小于M个的PC地址。例如,在图6的源代码的调用关系中,计算机设备只解释执行到函数C2。此时,在第一地址字段中,计算机设备只记录了函数T1、函数C1和函数C2的PC地址。例如,在图6的源代码的调用关系中,函数B不调用其他函数。此时,在第二代理栈帧中,计算机设备只记录了函数B的PC地址。当地址字段记录的PC地址的数量小于M时,若地址字段中剩余的空间中的数据未清零,则计算机设备可能得到错误的PC地址。例如,一个地址字段只记录了3个PC地址。但是计算机设备读取地址字段的M×P比特的内容后,得到了10个PC地址。计算机设备可能根据错误的PC地址得到错误的调用链。为此,计算机设备可以根据长度字段读取地址字段中的内容,避免读取错误的PC地址。下面以第一代理栈帧为例,对此进行描述。
第一长度字段中记录有X1。计算机设备获取第一长度字段中记录的X1。计算机设备的存储空间中记录有单个PC地址的内存大小P。在计算机设备获取第一地址字段的地址后,计算机设备读取第一地址字段中X1×P比特的内容。例如,计算机设备读取第一地址字段中前X1×P比特的内容。此时,计算机设备通过长度字段中的内容,可以获取到准确的PC地址,从而提高调试调优的准确性。
上面对计算机设备根据长度字段读取地址字段中的内容的方法进行了描述。应理解,在实际应用中,计算机设备也可以根据长度字段读取代码字段中的内容。下面以第一代理栈帧为例,对此进行描述。第一长度字段中记录有X1。计算机设备获取第一长度字段中记录的X1。计算机设备的存储空间中记录有单个代码量大小的内存大小P1。在计算机设备获取第一代码字段的地址后,计算机设备读取第一代码字段中X1×P1比特的内容。例如,计算机设备读取第一代码字段中前X1×P1比特的内容。此时,计算机设备通过长度字段中的内容,可以获取到准确的代码量大小,从而提高调试调优的准确性。
根据前述图4的描述可知,栈帧集合包括内部函数栈帧和代理栈帧。在实际应用中,一个栈帧集合可以包括多个内部函数栈帧。下面以AArch64芯片中的栈帧集合为例,对栈帧集合的结构进行描述。具体地,图8为本申请中提供的栈帧集合的一个结构示意图。如图8所示,栈帧集合801包括内部函数栈帧1、内部函数栈帧2、内部函数栈帧3和代理栈帧。每个栈帧包括链接寄存器LR和栈基址寄存器FP。LR用于在函数调用时的存储返回地址。FP指向栈帧的栈底地址。图中的箭头由栈底指向栈顶。代理栈帧中开辟了M×P个比特的地址字段。根据前述的描述可知,计算机设备可以读取地址字段中的X1个PC地址。在计算机设备读取X1个PC地址之前,计算机设备需要获取地址字段的地址。具体地,计算机设备可以通过调试调优工具读取DWARF CFI指令标记的代理栈帧的栈底地址。计算机设备中存储有偏移量。计算机设备根据偏移量和栈底地址得到地址字段的地址。类似的,代理栈帧也可以开辟有长度字段。计算机设备通过地址字段的栈底地址和地址字段的内存大小可以得到地址字段的栈顶地址。当长度字段和地址字段相邻时,计算机设备可以通过地址字段的栈顶地址得到长度字段的地址。应理解,在图8中,代理栈帧的栈内存空间中还可以包括代码字段。
在其他实施例中,计算机设备的堆栈中包括多个栈帧集合。在不同的栈帧集合中,地址字段和代理栈帧的基地址(也称为栈底地址)存在相同的偏移量。例如,多个栈帧集合包括第一代理栈帧和第二代理栈帧。计算机设备根据第一代理栈帧的基地址和第一偏移量获取第一地址字段的地址。计算机设备根据第二代理栈帧的基地址和第二偏移量获取第二地址字段的地址。第一偏移量等于第二偏移量。其中,通过设置相同的偏移量,可以提高调试调优工具获取PC地址的效率。
在前面的实施例中,源代码只包括高级语言函数。在实际应用中,源代码还可以包括编译函数。图9为本申请中提供的源代码的第三个结构示意图。如图9所示,源代码901包括函数集合1和函数集合2。函数集合1包括函数T1、函数T2、…、函数T9、函数A和函数B。函数集合1可以参考前述图1和/或图6中的源代码。函数集合2包括编译函数1、函数T101、函数T102、…、函数T107和编译函数2。源代码901的运行方向如图中的箭头所示。
当计算机设备运行到编译函数时,计算机设备建立编译函数栈帧,通过编译函数栈帧执行编译函数。例如,图10为本申请中提供的堆栈的第二个结构示意图。如图10所示,堆栈包括栈帧集合1001、栈帧集合1002、编译函数栈帧1003、栈帧集合1004和编译函数栈帧1005。计算机设备通过栈帧集合1001中的代理栈帧1解释执行函数集合1中的函数T1、函数T2、…、函数T9和函数A。当函数A调用函数B时,计算机设备通过栈帧集合1002中的代理栈帧2解释执行函数集合1中的函数B。当函数B调用编译函数1时,计算机设备建立编译函数栈帧1003,通过编译函数栈帧1003执行编译函数1。在编译函数1调用函数T101时,计算机设备建立栈帧集合1004。计算机设备通过栈帧集合1004中的代理栈帧3解释执行函数集合2中的函数T101、函数T102、…、函数T107。当函数函数T107调用编译函数2时,计算机设备建立编译函数栈帧1005,通过编译函数栈帧1005执行编译函数2。在本实施例中,假设M等于10。
根据前面的描述可知,在调试调优过程中,计算机设备可以读取代理栈帧中的PC地址,获取高级语言函数的调用链。当堆栈既包括代理栈帧,也包括编译函数栈帧时,计算机设备可以通过调试调优工具确定堆栈中的每个代理栈帧的栈底地址,再获取代理栈帧的PC地址。例如,计算机设备通过调试调优工具读取DWARF CFI指令标记的图10中每个代理栈帧的栈底地址。然后根据前面的描述,通过代理栈帧的栈底地址和偏移量读取PC地址。
前面对本申请中的程序运行方法进行描述,下面对本申请中的程序运行装置进行描述。图11为本申请中提供的程序运行装置的结构示意图。如图11所示,程序运行装置1100包括第一解释执行模块1101和第二解释执行模块1102。第一解释执行模块1101用于通过第一代理栈帧解释执行N1个高级语言函数。其中,函数A是N1个函数中最后一个被解释执行的函数。函数A最多与N1个函数中的X1-1个函数组成调用链。X1为等于长度阈值的整数。长度阈值为第一代理栈帧所能解释执行的函数的调用链的长度的最大值。最大值大于1。第二解释执行模块1102用于通过第二代理栈帧解释执行N2个函数。N2个函数包括函数A调用的函数B。N2为大于0的整数。
在其他实施例中,程序运行装置还可以包括获取模块、连接模块等。程序运行装置中的模块具体用于执行图5对应的实施例中的计算机设备可以执行的全部或部分操作。
上面对本申请中的程序运行装置进行描述,下面对本申请实施例中的计算机设备进行描述。图12为本申请中提供的计算机设备的结构示意图。本申请中的计算机设备可以是台式电脑,笔记本,智能手机等。如图12所示,程序运行设备1200包括处理器1201和存储器1203。
其中,处理器1201可以是中央处理器(central processing unit,CPU),网络处理器(network processor,NP)或者CPU和NP的组合。处理器1201还可以进一步包括硬件芯片或其他通用处理器。上述硬件芯片可以是专用集成电路(application specificintegrated circuit,ASIC),可编程逻辑器件(programmable logic device,PLD)或其组合。上述PLD可以是复杂可编程逻辑器件(complex programmable logic device,CPLD),现场可编程逻辑门阵列(field-programmable gate array,FPGA),通用阵列逻辑(genericarray logic,GAL)及其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件等或其任意组合。通用处理器可以是微处理器或者该处理器也可以是任何常规的处理器等。
存储器1203可以是易失性存储器或非易失性存储器,或可包括易失性和非易失性存储器两者。其中,非易失性存储器可以是只读存储器(Read-Only Memory,ROM)、可编程只读存储器(Programmable ROM,PROM)、可擦除可编程只读存储器(Erasable PROM,EPROM)、电可擦除可编程只读存储器(Electrically EPROM,EEPROM)或闪存。易失性存储器可以是随机存取存储器(Random Access Memory,RAM),其用作外部高速缓存。通过示例性但不是限制性说明,许多形式的RAM可用,例如静态随机存取存储器(Static RAM,SRAM)、动态随机存取存储器(Dynamic RAM,DRAM)、同步动态随机存取存储器(Synchronous DRAM,SDRAM)等。
存储器1203中存储有指令。处理器1201用于运行指令,使得处理器处理器1201通过第一代理栈帧解释执行N1个高级语言函数。其中,函数A是N1个函数中最后一个被解释执行的函数。函数A最多与N1个函数中的X1-1个函数组成调用链。X1为等于长度阈值的整数。长度阈值为第一代理栈帧所能解释执行的函数的调用链的长度的最大值。最大值大于1。处理器处理器1201还用于通过第二代理栈帧解释执行N2个函数。N2个函数包括函数A调用的函数B。N2为大于0的整数。在其他实施例中,计算机设备还包括收发器1202。收发器1202可以是光纤收发器,无线射频模块等。
在其他实施例中,存储器1203中存储有可供处理器1201执行的计算机程序。当处理器1201读取并执行计算机程序时,可以执行上述图5中死锁检测方法的全部或部分操作。
本申请还提供一种数字处理芯片。该数字处理芯片中集成了用于实现上述处理器1201的功能的电路和一个或者多个接口。当该数字处理芯片中集成了存储器时,该数字处理芯片可以完成前述实施例中的任意一个或多个实施例的方法步骤。当该数字处理芯片中未集成存储器时,可以通过接口与外置的存储器连接。该数字处理芯片根据外置的存储器中存储的程序代码来实现上述图5中的程序运行方法。
以上,仅为本申请的具体实施方式,但本申请的保护范围并不局限于此,任何熟悉本技术领域的技术人员在本申请揭露的技术范围内,可轻易想到变化或替换,都应涵盖在本申请的保护范围之内。
Claims (22)
1.一种程序运行方法,其特征在于,包括:
通过第一代理栈帧解释执行N1个函数,N1为大于1的整数;
其中,函数A是所述N1个函数中最后一个被解释执行的函数,所述函数A最多与所述N1个函数中的X1-1个函数组成调用链,X1为等于长度阈值的整数,所述长度阈值为所述第一代理栈帧所能解释执行的函数的调用链的长度的最大值,所述最大值大于1;
通过第二代理栈帧解释执行N2个函数,所述N2个函数包括所述函数A调用的函数B,N2为大于0的整数。
2.根据权利要求1所述的方法,其特征在于,所述第一代理栈帧包括第一长度字段,所述第一长度字段记录有所述函数A与所述X1-1个函数组成的调用链的长度X1。
3.根据权利要求2所述的方法,其特征在于,所述第一长度字段位于所述第一代理栈帧的栈内存空间。
4.根据权利要求2或3所述的方法,其特征在于,所述第一代理栈帧的栈内存空间包括第一地址字段,所述第一地址字段包括X1个函数的程序计数器PC地址,所述X1个函数的组成为所述函数A和所述X1-1个函数。
5.根据权利要求4所述的方法,其特征在于,在所述第一地址字段中,所述X1个函数的PC地址的排列顺序指示所述X1个函数的调用关系。
6.根据权利要求5所述的方法,其特征在于,函数C是所述N2个函数中最后一个被解释执行的函数,所述函数C最多与所述N2个函数中的X2-1个函数组成调用链,所述第二代理栈帧的栈内存空间包括第二地址字段,所述第二地址字段包括X2个函数的PC地址,所述X2个函数的组成为所述函数C和所述X2-1个函数;
所述方法还包括:
获取目标调用链,所述目标调用链包括第一调用链和第二调用链,所述第一调用链是所述X1个函数的PC地址在所述第一地址字段中的排列顺序,所述第二调用链是所述X2个函数的PC地址在所述第二地址字段中的排列顺序;
其中,所述目标调用链包括所述函数A调用所述函数B的信息。
7.根据权利要求4至6中任意一项所述的方法,其特征在于,所述第一地址字段的内存大小为Z比特;
其中,Z=M×P,M为所述长度阈值,单个PC地址的内存大小为P比特。
8.根据权利要求1至7任意一项所述的方法,其特征在于,在通过第一代理栈帧解释执行N1个函数之后,所述方法还包括:
基于所述函数B,建立所述第二代理栈帧。
9.根据权利要求1至8任意一项所述的方法,其特征在于,所述第二代理栈帧所能解释执行的函数的调用链的长度的最大值与所述长度阈值相等。
10.根据权利要求1至9任意一项所述的方法,其特征在于,所述长度阈值的范围为10至20。
11.一种计算机设备,其特征在于,包括:处理器和存储器;
其中,所述存储器中存储有指令;
所述处理器用于运行所述指令,使得所述处理器通过第一代理栈帧解释执行N1个函数,N1为大于1的整数;
其中,函数A是所述N1个函数中最后一个被解释执行的函数,所述函数A最多与所述N1个函数中的X1-1个函数组成调用链,X1为等于长度阈值的整数,所述长度阈值为所述第一代理栈帧所能解释执行的函数的调用链的长度的最大值,所述最大值大于1;
所述处理器还用于通过第二代理栈帧解释执行N2个函数,所述N2个函数包括所述函数A调用的函数B,N2为大于0的整数。
12.根据权利要求11所述的计算机设备,其特征在于,所述第一代理栈帧包括第一长度字段,所述第一长度字段记录有所述函数A与所述X1-1个函数组成的调用链的长度X1。
13.根据权利要求12所述的计算机设备,其特征在于,所述第一长度字段位于所述第一代理栈帧的栈内存空间。
14.根据权利要求12或13所述的计算机设备,其特征在于,所述第一代理栈帧的栈内存空间包括第一地址字段,所述第一地址字段包括X1个函数的程序计数器PC地址,所述X1个函数的组成为所述函数A和所述X1-1个函数。
15.根据权利要求14所述的计算机设备,其特征在于,在所述第一地址字段中,所述X1个函数的PC地址的排列顺序指示所述X1个函数的调用关系。
16.根据权利要求15所述的计算机设备,其特征在于,函数C是所述N2个函数中最后一个被解释执行的函数,所述函数C最多与所述N2个函数中的X2-1个函数组成调用链,所述第二代理栈帧的栈内存空间包括第二地址字段,所述第二地址字段包括X2个函数的PC地址,所述X2个函数的组成为所述函数C和所述X2-1个函数;
所述处理器还用于获取目标调用链,所述目标调用链包括第一调用链和第二调用链,所述第一调用链是所述X1个函数的PC地址在所述第一地址字段中的排列顺序,所述第二调用链是所述X2个函数的PC地址在所述第二地址字段中的排列顺序;
其中,所述目标调用链包括所述函数A调用所述函数B的信息。
17.根据权利要求14至16中任意一项所述的计算机设备,其特征在于,所述第一地址字段的内存大小为Z比特;
其中,Z=M×P,M为所述长度阈值,单个PC地址的内存大小为P比特。
18.根据权利要求11至17任意一项所述的计算机设备,其特征在于,
所述处理器还用于基于所述函数B,建立所述第二代理栈帧。
19.根据权利要求11至18任意一项所述的计算机设备,其特征在于,所述第二代理栈帧所能解释执行的函数的调用链的长度的最大值与所述长度阈值相等。
20.根据权利要求11至19任意一项所述的计算机设备,其特征在于,所述长度阈值的范围为10至20。
21.一种计算机存储介质,其特征在于,所述计算机存储介质中存储有指令,所述指令在计算机设备上执行时,使得所述计算机设备执行如前述权利要求1至10中任意一项所述的方法。
22.一种计算机程序产品,其特征在于,所述计算机程序产品在计算机设备上执行时,使得所述计算机设备执行如前述权利要求1至10中任意一项所述的方法。
Priority Applications (2)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202110673129.9A CN115495084A (zh) | 2021-06-17 | 2021-06-17 | 程序运行方法、装置以及相关设备 |
PCT/CN2022/097823 WO2022262633A1 (zh) | 2021-06-17 | 2022-06-09 | 程序运行方法、装置以及相关设备 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202110673129.9A CN115495084A (zh) | 2021-06-17 | 2021-06-17 | 程序运行方法、装置以及相关设备 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN115495084A true CN115495084A (zh) | 2022-12-20 |
Family
ID=84464943
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202110673129.9A Pending CN115495084A (zh) | 2021-06-17 | 2021-06-17 | 程序运行方法、装置以及相关设备 |
Country Status (2)
Country | Link |
---|---|
CN (1) | CN115495084A (zh) |
WO (1) | WO2022262633A1 (zh) |
Family Cites Families (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN102262537B (zh) * | 2011-07-21 | 2014-10-29 | 复旦大学 | 一种工作于混合模式执行引擎中的异常处理方法 |
CA2809516C (en) * | 2013-03-13 | 2016-11-08 | Khalid Nawaf Alharbi | Preventing stack buffer overflow attacks |
CN103559123B (zh) * | 2013-10-24 | 2016-02-10 | 烽火通信科技股份有限公司 | 基于VxWorks操作系统的函数调用栈分析方法及装置 |
-
2021
- 2021-06-17 CN CN202110673129.9A patent/CN115495084A/zh active Pending
-
2022
- 2022-06-09 WO PCT/CN2022/097823 patent/WO2022262633A1/zh active Application Filing
Also Published As
Publication number | Publication date |
---|---|
WO2022262633A1 (zh) | 2022-12-22 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US7107579B2 (en) | Preserving program context when adding probe routine calls for program instrumentation | |
CN111752571B (zh) | 程序升级方法、装置、设备及存储介质 | |
US7725883B1 (en) | Program interpreter | |
US7694288B2 (en) | Static single assignment form pattern matcher | |
US6381738B1 (en) | Method for optimizing creation and destruction of objects in computer programs | |
Ismail et al. | Quantitative overhead analysis for python | |
JPH0695310B2 (ja) | コード最適化方法 | |
US8056061B2 (en) | Data processing device and method using predesignated register | |
CN107122216B (zh) | 一种嵌入式实时操作系统动态加载方法 | |
US6425124B1 (en) | Resource allocation device for reducing the size and run time of a machine language program | |
CN115017058B (zh) | 一种内核模块的测试方法、装置、电子设备及存储介质 | |
CN109460237A (zh) | 代码的编译方法及装置 | |
CN108241516B (zh) | 嵌入式系统程序加载方法、装置、计算机设备和存储介质 | |
CN104965687A (zh) | 基于指令集生成的大数据处理方法及装置 | |
CN113094252A (zh) | 测试用例生成方法、装置、计算机设备及存储介质 | |
US7111283B2 (en) | Program history in a computer programming language | |
US20090222803A1 (en) | Efficient call sequence restoration method | |
CN115495084A (zh) | 程序运行方法、装置以及相关设备 | |
Emmelmann | Code selection by regularly controlled term rewriting | |
Krylov et al. | The evolution of garbage collection in v8: google's javascript engine | |
EP3867788A1 (en) | System and method for generation and execution of elastic sheet-defined functions and arrays | |
US20070016744A1 (en) | Memory management in a portable data carrier | |
CN104572482A (zh) | 一种过程变量的存储方法及装置 | |
Mazur et al. | Practical aspects for a working compile time garbage collection system for Mercury | |
CN109947476B (zh) | 一种运行时栈空间的统计方法及系统 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination |