一种基于值流分析的Golang程序高效过程间逃逸分析方法

文档序号:30842119发布日期:2022-07-23 00:52阅读:79来源:国知局
一种基于值流分析的Golang程序高效过程间逃逸分析方法
一种基于值流分析的golang程序高效过程间逃逸分析方法
技术领域
1.本发明涉及程序分析的技术领域,尤其涉及一种基于值流分析的golang程序高效过程间逃逸分析方法。


背景技术:

2.随着编程语言的不断发展和完善,程序执行时的性能开始受到越来越多的关注。为了提高程序的性能,经常需要用到优化技术。编译优化是指在程序编译过程中通过一定的方法或策略使系统或程序有关的性能提高的技术。目前很多主流编程语言的编译器中都拥有编译优化功能,一段程序需要经过编译生成可执行文件才能运行在相应的目标机器上。编译过程包含编译前端、编译后端优化和编译后端,提高编译优化的速度可以大大减少程序编译的时间,而逃逸分析技术是内存优化的技术和手段,也是编译器优化技术的一种。内存管理在软件工程中非常重要。例如,云服务运行在有内存使用限制的容器中,存在内存成本超过限制的风险。如今,越来越多的互联网公司开始关注内存管理和优化问题。
3.逃逸分析是指编译器通过分析指针变量的作用范围将原本分配在堆上的内存转移到栈上分配,而栈内存的访问效率要远远大于堆内存且栈上的内存会随着方法的运行结束而自动回收,因此栈式分配可以有效的提升程序的执行效率。由于逃逸分析需要做全局的数据流分析,很耗费时间,且逃逸分析的时间会影响整个编译的时间,那么如何在最短时间内找到更多的逃逸变量,最大程度上优化程序提高程序的执行效率是现阶段仍需要研究的重点。
4.编译器优化技术一直以来备受关注,逃逸分析技术也在各个版本中不断的迭代。现阶段主流编程语言的编译器中都默认开启了逃逸分析,例如java虚拟机hotsopt vm中的jit compiler(just in time compiler即时编译器)在运行时期进行逃逸分析,且在jdk1.8默认开启逃逸分析。c/c++编译器llvm虽然没有默认开启逃逸分析,但是在llvm后端优化的众多pass中也拥有逃逸分析的pass,可以手动开启逃逸分析对c/c++代码进行优化。go程序的编译器golang更是直接依赖逃逸分析技术在编译期来进行变量的内存管理。但是目前的逃逸分析效率依旧低下,尤其是过程间逃逸分析还没有一个很好的解决方案,因此本文结合值流图的思想缩小过程内逃逸分析的规模,利用数据流分析抽象值流图的构建过程,提高值流分析的精度,并结合函数式编程中高阶函数的思想抽象化逃逸变量的分析过程,降低逃逸分析的时间,提高过程间逃逸分析的精度,改善golang程序的执行效率,这对于编译优化技术的改进具有十分重要的意义。


技术实现要素:

5.本部分的目的在于概述本发明的实施例的一些方面以及简要介绍一些较佳实施例。在本部分以及本技术的说明书摘要和发明名称中可能会做些简化或省略以避免使本部分、说明书摘要和发明名称的目的模糊,而这种简化或省略不能用于限制本发明的范围。
6.鉴于上述现有基于值流分析的golang程序高效过程间逃逸分析方法存在的问题,
提出了本发明。
7.因此,本发明目的是提供一种基于值流分析的golang程序高效过程间逃逸分析方法。
8.为解决上述技术问题,本发明提供如下技术方案:一种基于值流分析的golang程序高效过程间逃逸分析方法,包括,
9.对golang程序进行预处理,得到基于静态单赋值形式的中间代码表示,创建过程间函数调用图和过程内控制流图;
10.将函数调用图做逆拓扑排序,建立待分析函数序列,并对待分析函数进行是否涉及过程间调用判别;
11.根据判别的不同分别计算目标函数的逃逸变量;
12.基于函数调用图分析程序内的所有函数的逃逸变量,将所有分析函数的esc进行合并得到最终的逃逸变量值的集合。
13.作为本发明所述基于值流分析的golang程序高效过程间逃逸分析方法的一种优选方案,其中:在判断待分析函数不涉及过程间调用后,搜集与golang语言逃逸规则相关的变量。
14.作为本发明所述基于值流分析的golang程序高效过程间逃逸分析方法的一种优选方案,其中:利用逆向数据流分析技术遍历程序控制流图,访问仅与指定变量v(t)相关的语句集合{s|s∈sl,l=1,2,3,...},其中s表示程序语句,l表示语句s对应的行号,sl表示所有程序语句的集合,t表示相关逃逸规则,v(t)表示与逃逸规则t相对应的变量,并按照遍历顺序传递语句s(v)的分析结果。
15.作为本发明所述基于值流分析的golang程序高效过程间逃逸分析方法的一种优选方案,其中:根据golang程序中不同语句s(v)的定义构建数据流方程,依据建立的数据流方程计算语句s(v)的约束关系,基于不同语句s(v)的数据流方程对目标函数作逆向数据流迭代分析,获取目标函数的ppre,其中ppre表示分析上一条语句得到的约束集,初始状态下利用ppre计算目标函数的逃逸变量。
16.作为本发明所述基于值流分析的golang程序高效过程间逃逸分析方法的一种优选方案,其中:基于已经搜集到的对应的指针变量,设变量为v(r),r表示目标变量对应的逃逸区域,搜集目标函数h(....)内所有的局部变量和内存分配信息,设定变量以及内存初始逃逸状态均为未逃逸状态。
17.作为本发明所述基于值流分析的golang程序高效过程间逃逸分析方法的一种优选方案,其中:设f(x,y,r)为语句s(v)的约束函数,其中x表示语句s(v)中与v(t)相关的变量,y表示语句s(v)中与v(t)无关的变量,r表示接收到的上一条语句s(v)的分析结果,之后在构建不同语句s(v)对应的约束关系抽取方程。
18.作为本发明所述基于值流分析的golang程序高效过程间逃逸分析方法的一种优选方案,其中:基于各类语句s(v)的约束函数,利用逆向数据流迭代分析技术对目标函数h(...)进行数据流迭代分析,设变量state表示迭代分析过程中语句s(v)的约束集是否发生改变,state初始值为true,若一趟迭代分析结束之后,语句s(v)的约束集没有发生任何变化,则state=false,并停止迭代;若任意s(v)的约束集在迭代分析过程中发生了变化,则state=true,当一趟迭代分析结束之后state=false,则停止迭代分析,并称此时各语句s
(v)的约束集达到了不动值;
19.若一趟迭代分析结束之后state=true,则继续进行下一轮迭代分析直到state=false即停止迭代分析,然后利用迭代计算获得的最终的ppre值,建立函数对语句s(v)的约束集ppre进行求解,并建立函数计算目标函数的逃逸变量,并根据目标函数是否包含参数类型变量进行判断。
20.作为本发明所述基于值流分析的golang程序高效过程间逃逸分析方法的一种优选方案,其中:在搜集与golang语言逃逸规则相关的变量后,添加对函数调用区域内的相关变量的搜集,并标记函数调用点处的ppre,取出被调用函数的逃逸分析结果,将ppre代入逃逸分析结果内进行计算,捕获调用函数内的逃逸变量。
21.本发明的有益效果:
22.1、基于ssa的代码中间表示进行golang程序的逃逸分析,可扩展性高,方便后续做代码数据流分析;
23.2、利用值流分析技术缩小过程内逃逸分析的规模,去除冗余代码的分析过程,结合数据流迭代分析技术提高值流分析的精度;
24.3、基于上述值流分析的结果,利用函数式编程中高阶函数的特性,在函数调用点直接进行逃逸变量的计算,避免构造庞大的过程间关系图,大大提高了过程间逃逸分析的效率。
附图说明
25.为了更清楚地说明本发明实施例的技术方案,下面将对实施例描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动性的前提下,还可以根据这些附图获得其它的附图。其中:
26.图1为本发明基于值流分析的golang程序高效过程间逃逸分析方法的整体结构示意图。
具体实施方式
27.为使本发明的上述目的、特征和优点能够更加明显易懂,下面结合说明书附图对本发明的具体实施方式做详细的说明。
28.在下面的描述中阐述了很多具体细节以便于充分理解本发明,但是本发明还可以采用其他不同于在此描述的其它方式来实施,本领域技术人员可以在不违背本发明内涵的情况下做类似推广,因此本发明不受下面公开的具体实施例的限制。
29.其次,此处所称的“一个实施例”或“实施例”是指可包含于本发明至少一个实现方式中的特定特征、结构或特性。在本说明书中不同地方出现的“在一个实施例中”并非均指同一个实施例,也不是单独的或选择性的与其他实施例互相排斥的实施例。
30.再其次,本发明结合示意图进行详细描述,在详述本发明实施例时,为便于说明,表示器件结构的剖面图会不依一般比例作局部放大,而且所述示意图只是示例,其在此不应限制本发明保护的范围。此外,在实际制作中应包含长度、宽度及深度的三维空间尺寸。
31.实施例1
32.参照图1,本发明公开了一种基于值流分析的golang程序高效过程间逃逸分析方法,包括如下步骤:
33.首先基于待分析的golang程序的函数调用图(call graph)对函数进行逃逸分析,该过程又分为过程内逃逸分析和过程间逃逸分析。
34.而上述步骤又包括,将golang源文件作为输入,对golang程序进行预处理,得到基于ssa(static single assignment静态单赋值)形式的中间代码表示,创建过程间函数调用图(callgraph)和过程内控制流图(control flow graph);将函数调用图(call graph)作逆拓扑排序,得到待分析的函数序列;若待分析的函数序列不为空时,从待分析的函数序列中取出函数进行逃逸分析,并对待分析函数进行是否涉及过程间调用判别。
35.在判别时,将对于待分析函数是否涉及过程间调用时而进入不同步骤,此处分为:步骤(一)和步骤(二)。
36.步骤(一)当待分析函数不涉及过程间调用时,其步骤为:首先搜集与golang语言逃逸规则相关的变量,而在此步骤中,搜集上述中间代码表示中的return区域(对应return指令语句)、global区域(对应global关键字)、makeslice区域(对应makeslice指令语句)、makechan区域(对应makechan指令语句)、makemap区域(对应makemap指令)所对应的指针变量。
37.然后基于已搜集到的对应的指针变量,设变量为v(r),r表示目标变量对应的逃逸区域,比如通过return指令搜索到的指针变量即表示为v(return);由global关键字修饰的指针变量即表示为v(global)。
38.而后搜集目标函数h(....)内所有的局部变量和内存分配信息,设定变量以及内存初始逃逸状态均为未逃逸状态,(其中的搜集内存分配信息是指对内存分配语句处信息的搜集)。内存分配语句主要为new类型和make类型语句,形如v=new(...)或者v=make(...)(其中v为自由变量),设ml(t)表示内存信息,t为分配内存语句类型,l为该分配内存语句对应的行号,若语句为new类型语句,则ml(t)=ml(new),表示通过new语句分配的内存;若语句为make类型语句,则ml(t)=ml(make),表示通过make语句分配的内存。
39.再利用逆向数据流分析技术遍历程序控制流图(control flow graph),访问仅与指定变量v(t)相关的语句集合{s|s∈sl,l=1,2,3,...}(其中s表示程序语句,l表示语句s对应的行号,sl表示所有程序语句的集合,t表示相关逃逸规则,v(t)表示与逃逸规则t相对应的变量),并按照遍历顺序传递语句s(v)的分析结果(设s(v)表示仅与指定变量v相关的语句);此步骤中提及的数据流分析是一种收集计算机程序中不同点处可能的值的集合信息的技术,逆向数据流分析即沿着程序正常执行路径的反方向来收集不同程序点处的值的信息。
40.对此步骤内部分相关语句进行解释:假设语句l1:m=n、语句l2:q=t、语句l3:v=q,其中m,n,q,t,v均为自由指针变量且变量q为待分析的目标变量,则语句l2和l3被称为相关语句,语句l1被称为不相关语句。
41.然后根据golang程序中不同语句s(v)的定义建立约束关系抽取方程,并对目标函数作数据流迭代分析,获取最终的ppre(此步骤中的逆向数据流迭代分析是一种数据流分析框架,通过在迭代分析的过程中不断更新程序点的数据流信息,从而得到更精确的分析结果);具体过程为:基于上述各类语句s(v)的约束函数,利用逆向数据流迭代分析技术对
目标函数h(...)进行数据流迭代分析,设变量state表示迭代分析过程中语句s(v)的约束集是否发生改变,state初始值为true,若一趟迭代分析结束之后,语句s(v)的约束集没有发生任何变化,则state=false,并停止迭代;若任意s(v)的约束集在迭代分析过程中发生了变化,则state=true。当一趟迭代分析结束之后state=false,则停止迭代分析,并称此时各语句s(v)的约束集达到了不动值。若一趟迭代分析结束之后state=true,则继续进行下一轮迭代分析直到state=false即停止迭代分析。
42.最后通过上述迭代计算获得最终的ppre值,设函数γ(z)对语句s(v)的约束集ppre进行求解,设pesc=γ(ppre),设函数escape(fn,p)来计算目标函数的逃逸变量,其中fn为目标函数,p为求解后的约束集。设目标函数逃逸分析结果以escfn表示,则其中escv表示获得的逃逸分析结果包含一个具体的值,表示获得的逃逸分析结果包含一个具体的函数,若escv或不存在,则用nil表示。
43.若fn中不包含参数类型变量,即esch=escape(h(),pesc),则计算pesc中v所指向的所有变量的集合,若pesc={v

mem(q)},则esc={q,nil};若pesc={v

newmem(v)/make\mem(v)},则escv={new(t(v))/make(t(v))};若pesc={v

mem(q),v

mem(z),v

newmem(v),...},newmem(v)/makemem(v),...},则escv={(q,z,new(t(v))/make(t(v)),...),nil}(其中函数t(var)为取出对应的变量var的类型)。
44.若fn中包含参数类型变量,即escape(h(a,b,c,...),pesc),且a,b,c,...pesc(表示pesc中不包含任何参数变量),则escv的计算结果同(2-502)一样。
45.若fn中包含参数类型变量,即escape(h(a,b,c,...),pesc),且pesc中包含一个或多个参数类型变量,假设pesc中包含的参数变量为a和b。若pesc={v

a,v

b},则此时
46.由于目标函数中无法确定最终的a,b,c,...的值,所以无法获得最终的逃逸变量计算结果,因此此处利用函数式编程中高阶函数的特性将目标函数h(a,b,c,...)的逃逸分析计算结果以携带参数a,b的函数形式返回,即函数(p(a),p(b));若ppre={v

mem(a),v

mem(b)},则mem(b)},则其中p(a),p(b)表示与变量a,b相关的约束集。
47.上述步骤中所述的使用函数γ(z)对语句s(v)的约束集进行求解的规则为:
[0048][0049]
其中α,β表示指针类型变量;δ,η既可以表示指针类型变量,也可以表示mem(v)、newmem(v)、makemem(v)。
[0050]
步骤(二)而若判断后待分析的函数涉及过程间调用时,其步骤为:
[0051]
首先依旧搜集与golang语言逃逸规则相关的变量并重复往下执行,添加对函数调用区域内的相关变量的搜集,并标记函数调用点处的ppre。
[0052]
此步骤的具体过程是:假设函数g(...)为上述被分析函数h(a,b,c,...)的调用函数,则函数g(...)的逃逸分析结果用escg表示,然后依旧搜集与golang语言逃逸规则相关
的变量并重复往下执行,并在其中添加对call类型指令对应的参数型指针变量的搜集,若语句s(v)为callfunc类型语句x=h(m,n,o,...)、h(m,n,o,...)或go h(m,n,o,..),则标记此处的ppre(v)值,设为ppre__h(v),执行完上述的迭代分析之后获得最终的ppre__h(v)值;利用函数γ(z)对ppre__h(v)进行求解,设结果为pesc_h。
[0053]
而后取出被调用函数的逃逸分析结果将ppre代入内进行计算,捕获调用函数内的逃逸变量;此步骤的具体过程是:再次定位到函数g(...)内的callfunc类型语句处,以x=h(m,n,o,...)为例,取出函数h(a,b,c,...)的逃逸分析结果,即函数h的部分,为了在下列计算中和通用的逃逸分析结果表示区分开来,设取出的函数h的部分为将pesc_h(m),pesc_h(n)分别代入(p(a),p(b))中,计算函数g(...)的逃逸变量。
[0054]
若g(...)不携带参数,则若g(...)携带参数,并且(pesc_h(m),pesc_h(n))的计算过程中包含参数类型变量,则
[0055]
在进行上述的判别后,根据判别的不同分别计算目标函数的逃逸变量,并整理逃逸变量。
[0056]
基于函数调用图按上述步骤对golang程序中的每一个函数作逃逸分析,设esc($file_name)为该golang程序的逃逸变量表示,则按上述描述esc($file_name)=esch_v∪escg_v∪...,其中$file_name表示golang程序的文件名称,esch_v、escg_v分别表示esch和escg中escv部分,实现对所有分析函数的esc的合并。
[0057]
本发明基于ssa的代码中间表示进行golang程序的逃逸分析;
[0058]
在本实施例中,对传统经典逃逸分析方法和改进逃逸分析方法进行对比(表1)。
[0059]
传统经典逃逸分析方法:基于连通图的逃逸分析方法。
[0060]
改进逃逸分析方法:基于值流分析的高效逃逸分析方法。
[0061]
代价系数:系数越低,效率越高;
[0062][0063][0064]
表1逃逸分析数据对比分析
[0065]
在对比分析后可以直观的看到在改进后的逃逸分析方法在分析时间上更短,并且
捕获的逃逸变量个数更多。利用值流分析技术缩小过程内逃逸分析的规模,去除冗余代码的分析过程,结合数据流迭代分析技术提高值流分析的精度;基于上述值流分析的结果,利用函数式编程中高阶函数的特性,在函数调用点直接进行逃逸变量的计算,避免构造庞大的过程间关系图,大大提高了过程间逃逸分析的效率。
[0066]
重要的是,应注意,在多个不同示例性实施方案中示出的本技术的构造和布置仅是例示性的。尽管在此公开内容中仅详细描述了几个实施方案,但参阅此公开内容的人员应容易理解,在实质上不偏离该申请中所描述的主题的新颖教导和优点的前提下,许多改型是可能的(例如,各种元件的尺寸、尺度、结构、形状和比例、以及参数值(例如,温度、压力等)、安装布置、材料的使用、颜色、定向的变化等)。例如,示出为整体成形的元件可以由多个部分或元件构成,元件的位置可被倒置或以其它方式改变,并且分立元件的性质或数目或位置可被更改或改变。因此,所有这样的改型旨在被包含在本发明的范围内。可以根据替代的实施方案改变或重新排序任何过程或方法步骤的次序或顺序。在权利要求中,任何“装置加功能”的条款都旨在覆盖在本文中所描述的执行所述功能的结构,且不仅是结构等同而且还是等同结构。在不背离本发明的范围的前提下,可以在示例性实施方案的设计、运行状况和布置中做出其他替换、改型、改变和省略。因此,本发明不限制于特定的实施方案,而是扩展至仍落在所附的权利要求书的范围内的多种改型。
[0067]
此外,为了提供示例性实施方案的简练描述,可以不描述实际实施方案的所有特征(即,与当前考虑的执行本发明的最佳模式不相关的那些特征,或于实现本发明不相关的那些特征)。
[0068]
应理解的是,在任何实际实施方式的开发过程中,如在任何工程或设计项目中,可做出大量的具体实施方式决定。这样的开发努力可能是复杂的且耗时的,但对于那些得益于此公开内容的普通技术人员来说,不需要过多实验,所述开发努力将是一个设计、制造和生产的常规工作。
[0069]
应说明的是,以上实施例仅用以说明本发明的技术方案而非限制,尽管参照较佳实施例对本发明进行了详细说明,本领域的普通技术人员应当理解,可以对本发明的技术方案进行修改或者等同替换,而不脱离本发明技术方案的精神和范围,其均应涵盖在本发明的权利要求范围当中。
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1