首页 / 专利库 / 人工智能 / 语言代码 / 用于动态代码优化的差异静态分析

用于动态代码优化的差异静态分析

阅读:901发布:2020-05-12

专利汇可以提供用于动态代码优化的差异静态分析专利检索,专利查询,专利分析的服务。并且一种用于为具有动态行为的程序生成优化的本机代码的机制,使用对该程序的静态分析来预测该程序的不同元素在该程序执行时可能被使用的可能性。静态分析在程序执行之前被执行,并利用 置信度 指示符来标记程序的某些元素,置信度指示符用高置信度级别或低置信度级别对元素进行分类。然后,置信度指示符由时间提前的本机编译器使用以生成本机代码并优化代码以用于加快执行和/或较小大小的本机代码。,下面是用于动态代码优化的差异静态分析专利的具体信息内容。

1.一种系统,包括:
至少一个处理器和存储器
第一部件,所述第一部件当由所述至少一个处理器执行时,执行具有至少一个动态特征的程序的静态分析,并且将所述程序的至少一个程序元素与多个置信度指示符中的至少一个置信度指示符相关联,所述多个置信度指示符包括高置信度指示符和低置信度指示符,所述高置信度指示符将程序元素指定为具有在所述程序执行时被使用的高置信度,并且所述低置信度指示符将程序元素指定为具有在所述程序执行时被使用的低置信度;以及第二部件,所述第二部件当由所述至少一个处理器执行时,基于所述至少一个置信度指示符来生成优化的本机代码。
2.根据权利要求1所述的系统,其中所述至少一个程序元素包括类型、方法和字段中的至少一个。
3.根据权利要求1所述的系统,其中所述第二部件生成包括热代码和冷代码的代码布局,其中所述热代码包括与高置信度指示符相关联的一个或多个方法,并且所述冷代码包括与低置信度指示符相关联的一个或多个方法。
4.根据权利要求1所述的系统,
还包括语言编译器,所述语言编译器生成所述程序的中间语言代码
其中所述第一部件执行所述程序的所述中间语言代码的静态分析。
5.根据权利要求1所述的系统,其中动态特征包括反射、后期绑定和通用类型的实例化中的一个或多个。
6.一种方法,包括:
静态地跟踪具有至少一个动态特征的程序的执行的流程,以确定哪些类型和类型成员被使用在所述程序中,其中静态跟踪发现由从根可到达的、用于执行的指令所需的每个依赖关系,并且发现在所述程序中的每个依赖关系的使用;
利用多个置信度指示符中的一个置信度指示符对在所述静态跟踪期间遇到的每种类型和类型成员进行分类,所述多个置信度指示符包括高置信度指示符和低置信度指示符,所述高置信度指示符指示类型和/或类型成员在所述程序执行时被使用的高置信度,并且所述低置信度指示符指示类型和/或类型成员在所述程序执行时被使用的低置信度;以及基于与所述程序的类型和/或类型成员相关联的所述置信度指示符,为所述程序优化本机代码。
7.根据权利要求6所述的方法,其中所述类型和类型成员包括方法和字段。
8.根据权利要求6所述的方法,其中为所述程序优化所述本机代码还包括为与高置信度指示符相关联的一个或多个方法生成本机代码。
9.根据权利要求6所述的方法,其中所述动态特征包括以下项中的至少一项:在运行时创建能够被调用和被访问的类型实例,从组件中定位类型并创建类型的实例,以及在运行时对方法的调用。
10.根据权利要求6所述的方法,还包括:
将所述程序编译成中间语言代码,所述编译生成所述程序的元数据,所述元数据包括针对在所述编译期间已知的所述程序的每种类型和类型成员的一个或多个依赖关系,其中所述静态跟踪从与类型和/或类型成员相关联的所述元数据中发现依赖关系。

说明书全文

用于动态代码优化的差异静态分析

背景技术

[0001] 编译器是将以高级编程语言编写的源代码转化为低级语言的程序,诸如中间级代码(例如字节码、公共语言基础结构(CIL)等)和/或机器代码(即本机代码、目标代码)。时间提前(Ahead-of-Time,AOT)编译器在程序执行之前将程序的源代码转化为机器代码。AOT编译器对程序执行静态分析,这对于在程序执行之前捕获错误以及执行旨在降低程序执行速度的优化非常有用。
[0002] 即时(JIT)编译器在运行时将中间级别代码转化为机器代码。在程序执行期间,语言虚拟机将中间级代码转化为机器代码指令。JIT编译用于支持依赖当前程序状态的编程语言的动态特征,诸如反射、运行时类型检查和后期绑定。动态特征通过在运行时启用对程序的扩展和对类型系统的修改来提供更大的灵活性,但以承担增加程序的执行时间为代价。发明内容
[0003] 提供本发明内容以简化形式介绍概念的选择,这些概念将在下面的具体实施方式中进一步描述。本发明内容既不旨在标识所要求保护的主题的关键特征或必要特征,也不旨在用于限制所要求保护的主题的范围。
[0004] 本文描述的主题涉及支持利用动态特征的、针对程序的时间提前的本机代码的生成的技术、系统、处理和设备。采用静态分析,其预测在程序执行期间使用某些程序元素的可能性,以确保本机代码包含执行程序并支持动态特征所需的所有信息。分析引擎从可能执行程序的已知点静态跟踪程序流,并迭代跟踪可访问指令所需的每个依赖关系的数据流,以便于确定方法、类型和字段是否可能在程序执行时被使用或访问。
[0005] 基于指示当程序执行时可能被使用的方法、类型和字段的确定性的程度的规则,生成置信度指示符并将其与每个方法、标签和字段相关联。置信指示符由本机编译器用来确定是否生成本机代码以支持某些动态特征,并确定要执行哪些优化以便于降低程序的执行速度和/或本机代码的大小。
[0006] 通过阅读以下具体实施方式并查看相关附图,这些以及其他特征和优点将变得显而易见。应当理解,前面的一般描述和下面的详细描述都只是说明性的,并不限制所要求保护的方面。

附图说明

[0007] 图1示出了用于动态代码优化的差异静态分析的示例性系统。
[0008] 图2是示出了用于分析程序的中间语言代码以便将中间语言代码与置信度指示符相关联的示例性方法的流程图
[0009] 图3是示出了用于利用置信度指示符生成本机代码的示例性方法的流程图。
[0010] 图4是示出了第一操作环境的框图
[0011] 图5是示出了第二操作环境的框图。

具体实施方式

[0012] 概述
[0013] 所公开的主题涉及一种AOT编译机制,该AOT编译机制静态分析具有动态特征的程序,以预测在程序执行时可能使用该程序的某些元素(例如方法、类型和字段)的可能性。该静态分析用于生成本机代码,该本机代码包含执行程序所需的所有指令和数据。可能使用和不太可能使用的程序的那些元素之间的差异使AOT编译器能够时间提前执行优化,这降低本机代码的大小和/或提高其执行速度。
[0014] 在不执行程序的情况下并且通过执行程序的静态分析来进行预测。静态分析是在程序的执行之前执行的,并使用置信度指示符标记程序的某些元素,置信度指示符用高置信度级别或低置信度级别对元素进行分类。程序的静态分析与简档数据不同,简档数据是通过使用不同输入数据集合多次运行该程序的已安装版本而生成的。
[0015] 高置信度级别指示元素在程序执行期间更可能性被使用的较高可能性,而低置信度指示元素在程序执行时不太可能被使用的较低可能性。高和低置信度指示符由编译器用来确定要为哪些函数生成本机代码,以及如何针对执行速度来优化程序和/或减小机器代码的大小。本机编译器为那些更有可能执行的方法生成代码,而不是依赖运行时引擎在运行时生成本机代码。本机编译器使用置信度指示符来确定时间提前生成本机代码是否可行。本机代码可提高程序的执行速度。
[0016] 置信指示符还用于代码优化。内联是一种优化技术,对于那些经常调用的方法将是实用的。标记为高置信度的方法可能是内联的潜在候选。内联可提高程序的执行速度,因为它消除了实现调用和从调用返回的开销。
[0017] 另外,可以针对执行速度优化本机代码的代码和数据布局。置信度指示符可被本机编译器用来生成代码布局,该代码布局将不同方法的热彼此靠近放置,而冷块彼此靠近放置。可以将热块更早地加载到指令缓存中,从而提高程序的执行速度,而对冷块进行标记以进行延迟加载。附加地,置信度指示符可通过标识比其他数据更频繁使用的数据来优化数据的布局,这改进空间局部性并减少存储器延迟。
[0018] 程序的静态分析由于编程语言的特征而变得复杂,这些特征在运行时期间被执行并且依赖于程序的当前状态。曾经这种动态特征是反射。反射是程序在运行时检查和修改程序的结构和行为的能。反射使程序能够获得有关已加载组件中定义的类型以及其中定义的类型的信息,诸如类、接口和值类型。反射是由运行时环境实现的,并且依赖于语言编译器生成的元数据和运行时环境所需的其他信息。
[0019] 为了限制本机代码的大小,只有可能执行的那些方法才具有生成的AOT本机代码。否则,生成的本机代码的大小将不切实际。附加地,对那些更有可能被执行的方法进行了优化,以便于增加本机代码的大小及其执行速度。
[0020] 本文公开的静态分析不执行程序,而是在程序执行之前静态地分析程序。该分析使用元数据和运行时行为描述来确定程序的执行行为。静态分析跟踪程序的控制流,以达到更有可能被执行的指令,并分析每个可到达指令用于执行所需的所有依赖关系。静态分析关注类型、方法和字段。
[0021] 元数据和运行时行为描述文件提供了程序根上的数据,以促进程序流的静态跟踪。过程间和过程内数据流分析用于找到可从根可到达的每个指令所需的依赖关系以及依赖于依赖关系的依赖关系。规则或试探法用于通过适当的置信度指示符对每种类型、方法和字段进行分类。规则基于众所周知的指令如何被执行的方式。然后使用置信度指示符在生成本机代码中并在执行代码优化中来引导本机AOT编译器。
[0022] 现在将注意力转向在各个方面中实现该技术的方法、系统和设备的讨论。
[0023] 差异静态分析
[0024] 关于.NET框架和面向对象的编程语言,描述了差异静态分析。应当注意,所公开的主题不限于任意特定的运行时环境、操作系统、编程语言或编程基础结构,并且这些相同的概念可以应用于其他框架(例如GUI框架、Java框架等)、编程环境、编程语言和操作系统。
[0025] .NET框架是资源集合,被设计为在 平台或操作系统上运行的应用和Web服务的开发。它被设计为提供跨不同编程语言的语言互操作性。.NET框架依赖于公共语言基础结构(CLI),该公共语言基础结构是使使用不同编程语言编写的程序能够使用公共语言运行时(CLR)在任意操作系统上执行的规范。CLR管理.NET程序的执行并提供运行时服务,诸如即时编译、垃圾回收、存储器管理、异常处理等。
[0026] CLI指定公共类型系统(CTS),其是CLR支持的公共类型和操作的公共集合。CTS定义了CLR如何声明和管理类型。所有类型都是值类型或引用类型。值类型是代表对象实际值的数据类型。引用类型是一种数据类型,其对象由对对象的实际值的引用表示。CTS支持以下类型:类;结构;枚举;接口;以及代表。类定义类型的数据和行为。类型组是名称空间或组件。类型的成员或类型成员包括方法、字段、属性和事件。
[0027] .NET框架中的反射使程序能够获得有关在所加载的组件中定义的类型的信息。组件包含模块、模块包含类型、类型包含成员。通过反射,程序可以确定其他组件中包含的类型、创建类型的实例、将类型绑定到现有对象、调用类型的方法或访问类型的字段和属性。例如反射还至少能够实现以下各项:(1)在运行时可以被调用和访问的类型实例的创建;
(2)来自已加载的组件中的类型的位置并该类型的实例的创建;(3)方法信息(例如名称、返回类型、参数、访问修饰符)的发现、方法的实现细节以及在运行时对特定方法的调用;(4)构造函数的名称、参数、访问修饰符和实现细节的发现,其然后可用于调用特定的构造函数;(5)字段的名称、访问修饰符、实现细节的发现,其然后可用于获取或设置字段值;(6)参数名称的发现、数据类型、输入/输出参数以及参数位置是方法签名。
[0028] 遵循CLI的应用或程序可以利用公共类库(即.NET类库),该类库包括在运行时执行的应用编程接口(API)。特别是,包括反射API的公共类库被包括在System.Reflection命名空间中。反射API在运行时访问组件的类型元数据,以获得对类、结构、基类和接口、嵌套类型、枚举、方法及其参数、属性、索引器、字段、构造函数、事件、属性和名称空间的描述、以及使用此信息来动态修改程序的行为。例如Type.GetMethod(参数)是反射API,其获得参数指定的类型的方法之一。同样,Type.GetType(参数)是获得参数类型的反射API。
[0029] 程序的动态特征可以包括反射、公共对象模型(COM)互操作性等。反射使应用可以即时调用其他函数,其能够实现序列化/反序列化和框架。序列化是将对象的状态转换为字节流,然后再转换回该对象的副本的过程。UI框架是指用于访问应用用户界面的反射API。COM互操作性可实现C#管理代码和非管理代码之间的互操作性。例如COM互操作性实现对动态链接库中实现的非管理函数的C#函数调用。
[0030] AOT编译器被配置为执行静态编译以便于生成仅包括执行程序所需的代码和数据的本机代码。在一个或多个方面,AOT编译器使用运行时指导(directive)文件,该运行时指导文件包含指导或提示,这些指导或提示标识在运行时需要其元数据的程序元素。运行时指导文件包括与类型、类型组或类型成员有关的指导,并且可以指定一个或多个程度和/或策略。程度指示要应用于类型、类型组或类型成员的动作,策略指示如何将程度应用于类型、类型组或类型成员。
[0031] 例如指导可以指定程序的类型T在目标类型环境中是必需类型、可选类型还是禁止的。指导可以指定类型成员M在目标类型环境中是必需的类型成员、可选的还是被禁止的。指导可以指定为类型T启用程度D,或者禁用程度D,在其他情况下,指导可以指定在目标类型环境中为类型成员M启用程度D或为M禁用程度D。
[0032] 指导可以引用以下程度中的一个或多个:激活程度,其指通过反射对类型实例的运行时激活;浏览程度,其通过反射能够实现对类型的运行时自省(introspection);动态程度,其指通过反射进行的运行时访问;运行时序列化程度,其能够实现反射支持基于反射的序列化和/或反序列化;以及静态序列化程度,其支持特定格式(例如XML或JSON)的静态综合序列化。在某些方面,程度值可以与诸如所有必需、必需公共和内部、必需公共、全部、公共内部、公共、包括、自动或排除的程度相关联。
[0033] AOT编译器使用指导来指示在静态编译中使用的以下各项:(a)程度D是否适用于类型T;(b)程度D是否适用于类型成员M;(c)是否需要类型T;(d)是否需要类型成员M。如果不需要类型T或类型成员M,则编译器可以通过省略对T或M的动态支持来减少空间和处理要求。要确定所提交的指导对给定类型T或给定类型成员M的指示,编译器可能会找到应用于T或M的所有指导,应用合成规则以生成合成指导,并且然后从合成指导中确定结果。
[0034] 该策略可用于控制对程序元素的运行时访问以及查询有关程序元素的信息。可以为组件、名称空间和类型指定一个策略集合,为成员指定另一策略集合。例如组件、名称空间和类型的策略可以:(a)控制对构造函数的运行时访问,以能够实现实例的激活;(b)控制查询有关程序元素的信息,但限制对这些程序元素的运行时访问;(c)控制对所有类型成员的运行时访问;以及(d)控制对构造函数、字段和属性的运行时访问,以使类型实例能够被序列化或由第三方库序列化。类型成员的示例性策略可以:(a)控制有关属性、字段、方法或事件元素的查询信息,但限制运行时访问;(b)控制对成员的运行时访问并查询其中包含的类型;以及(c)控制对成员的运行时访问,以使类型实例能够被序列化和反序列化。
[0035] 一方面,运行时指导文件包含软件可分析的描述,该描述可被格式化为XML、JSON、YAML或SDL文件。运行时指导文件是与程序分离的文件,并且指导不与程序的源代码或中间代码交错。
[0036] 现在将注意力转向执行用于动态代码优化的差异静态分析的技术和系统。
[0037] 图1示出了用于使用差异置信度指示符来生成机器代码(即,可执行代码、本机代码等)的示例性系统100的框图。在本文公开的主题的一个方面中,系统100执行:第一编译阶段,用于生成中间语言代码102;静态分析阶段,用于生成中间语言代码104的置信度指示符;以及第二编译阶段,使用置信度指示符106来生成和优化本机代码。
[0038] 系统100利用语言编译器108,该语言编译器108将以编程语言编写的一个或多个源代码文件110转换为组件文件112。语言编译器108基于与编程语言相关联的语法,将以编程语言编写的语句转化为中间语言代码。示例性编程语言包括但不限于Visual Basic、Visual J#、C++、C#、APL、Cobol、Pascal、C、Java等。中间语言代码是程序的与处理器无关的形式,由二进制指令组成。示例性中间语言代码是通用中间语言(CIL),它由.NET框架使用的通用语言基础结构定义,也称为Microsoft中间语言(MSIL)。其他示例性中间语言代码包括Java字节码、Parrot中间表示、技术独立机器接口(TIMI)等。
[0039] 在本公开的一方面中,当语言编译器108编译源代码文件110时,生成中间语言代码和元数据。.NET框架中的组件文件112或组件由清单、元数据和代码文件或模块组成。清单包含有关组件112的信息,诸如其版本号、组件名称、本地环境、安全性信息以及组成组件的文件的名称。代码文件或模块包含中间语言代码。
[0040] 元数据描述了组件的每个模块中的每种类型和成员。例如元数据可以包括组件的描述以及在程序中找到的类型和属性。组件的描述包括组件的标识、导出的类型、组件所依赖的其他组件以及运行组件所需的安全权限。类型的描述包括类型的名称、类型的可见性、类型的基类、实现的接口以及类型成员,诸如方法、字段、属性、事件和嵌套类型。
[0041] 分析引擎116使用组件文件112、运行时描述文件114和规则111的元数据和中间语言代码来分析中间语言代码。规则111引导分析引擎116确定对程序元素的置信度级别的指定。
[0042] 然后,将标记的中间指令118输入到本机编译器120,该本机编译器将中间语言代码编译为优化的本机代码或机器代码122。置信度指示符用于确定AOT代码针对哪种方法生成、是否执行某些优化以及代码和数据布局配置,以用于加快执行速度和/或减小本机代码的大小。
[0043] 尽管图1所示的系统100在某种配置中具有有限数量的元素,但是应当理解,系统100在替代配置中可以包括更多或更少的元素。实施例不限于这种方式。例如系统100可以包括集成开发环境(IDE)(例如Microsoft的 NetBeans、Eclipse、
SharpDevelop、Lazarus等),该集成开发环境为开发人员提供了软件开发工具集合,诸如编译器、源代码编辑器、分析器、调试器、链接器、绑定器等。分析引擎116可以是IDE中提供的工具的一部分。
[0044] 此外,置信度指示符不限于两个置信度指示符,也不限于本文所述的高级和低级置信度指示符。可以有多个置信度指示符,其中每个置信度指示符代表将要执行程序元素的特定确定性程度。另外,可以存在根据标准的变化而变化的滑动标尺。另附加地,分析引擎不限于上述配置。出于预期目的,可以将分析引擎合并入语言编译器和/或AOT编译器中。
[0045] 现在将注意力转向利用本文公开的系统和设备的各种示例性方法的描述。可以参考各种示例性方法进一步描述各方面的操作。可以理解,除非另外指出,否则代表性方法不一定必须以所呈现的顺序或以任意特定顺序执行。此外,可以以串行或并行方式或串行和并行操作的任意组合来执行关于方法描述的各种活动。在一个或多个方面,该方法示出了本文公开的系统和设备的操作。
[0046] 该方法开始于发现极有可能被执行的程序的根。根是执行程序所需的类型或成员。跟踪从这些根可到达的指令,以确定它们是否可能被执行。但是,大多数指令依赖于为了执行指令而需要存在的程序元素。这些依赖程序元素被视为依赖关系。为了确定指令是否可能被执行,需要知道该指令所依赖的所有程序元素是否也可能被使用或执行。
[0047] 可能存在依赖关系的嵌套,其中一个依赖关系依赖于附加的依赖关系,而其他依赖关系进而又依赖于其他依赖关系,依此类推。这就要求以递归或迭代的方式跟踪原始依赖关系,以找到从中其流经的所有相关依赖关系。通过将每个找到的依赖关系放在各自的队列中来执行此递归跟踪,以便可以跟踪找到的依赖关系以用于依赖于它的任意其他依赖关系。当确定依赖关系不再具有任意其他依赖关系时,将应用规则集合来确定该依赖关系是以高置信度还是低置信度被执行。然后将依赖关系及其分类(即高置信度/低置信度)存储在表中。
[0048] 在表中跟踪依赖关系及其分类,以便消除重复的处理。在某些情况下,程序中的指令可能依赖于相同的依赖关系,诸如在多个指令调用相同方法的情况下。该方法是依赖关系,一旦将其初始地分类为高置信度或低置信度,就将其放置在表中。以这种方式,当再次遇到依赖关系时,该过程不需要确定其分类,而是该过程可以在表中搜索其分类。
[0049] 可以使用一种或多种不同的方案来找到依赖关系。元数据包含对方法、类型和字段的依赖关系。例如元数据公开了在另一种方法中使用了哪些方法、在方法调用中使用的参数的类型、等等。由于这些依赖关系是语言编译器从先前的编译中获悉的,因此它们在元数据中被列出,并在本文中称为静态依赖关系。在某些情况下,元数据中的依赖关系可以引用元数据中具有依赖关系的其他类型、字段或方法,并且这些依赖关系可以引用具有附加依赖关系的元数据、等等。该过程搜索元数据以找到所有这些依赖关系。
[0050] 在某些情况下,不能从元数据确定所有依赖关系。由于这个原因,使用数据流分析(例如过程间、过程内)来跟踪依赖关系,以搜索依赖关系的所有用途,并通过这种跟踪可以发现附加依赖关系。过程间流分析是具有中间函数或方法调用的数据流分析。过程内流分析是函数或方法内的数据流分析。通过元数据找不到但通过数据流分析发现的依赖关系称为动态依赖关系。依赖关系可以被跟踪到在众所周知的函数中的使用,也可以被跟踪到接收器。接收器是具有已知行为的函数或指令序列。众所周知的函数的示例可以是反射API或运行时环境提供的其他方法调用中的任意一个。
[0051] 规则用于确定哪个处理队列(即,低置信度队列、高置信度队列)用于放置依赖关系,并且随后,一旦发现所有其相关的依赖关系,哪种分类与该依赖关系相关联。高置信度队列包含很可能使用的那些依赖关系,而低置信度队列包含不太可能使用的那些依赖关系。在一方面,该技术在低置信度队列上的依赖关系之前处理来自高置信度队列的依赖关系,以便在不遗漏所需指令的方面上犯错误。该技术考虑了两个队列中的依赖关系,以便于确保在高置信度规则未发现所有需要的依赖关系的情况下考虑所有依赖关系。
[0052] 高置信度规则用于确定方法、类型或字段是否被分类为高置信度,而低置信度规则用于确定方法、类型或字段是否被分类为低置信度。示例性高置信度规则包括以下一项或多项:(1)将调用已被分类为高置信度的方法的方法被标记为高置信度;(2)具有以下父方法(即基类)的方法,该父方法已被标记为高置信度,并该方法使用高置信度规则被分类为高置信度;(3)直接引用高置信度类型或字段的方法;(4)已经被分类为高置信度并且可以被跟踪回接收器或众所周知的函数(例如反射API)的方法的依赖关系;以及(5)从高置信度根可到达的方法调用。
[0053] 低置信度规则包括以下各项:将不是.NET框架一部分(即不是.NET运行时环境或类型环境的一部分)的每个类型和成员视为低置信度。例如运行时指导文件包含默认指导,<组件名称=“*应用*”动态=”需要全部”/>,该指导描述不是平台运行时和类型环境一部分的每个类型和成员都应为被认为是根。在某些情况下,这些类型和成员可能不会执行,并且根据此原因,这些类型和成员被归类为低置信度。
[0054] 图2示出了用于静态分析中间代码以生成置信度指示符的示例性方法200的流程图。转到图1和图2,分析引擎116接收中间语言代码202和元数据204、运行时行为描述114以及规则集合206。
[0055] 分析引擎116通过发现程序的根开始(框206)。程序的根指示程序的起源,程序中的所有路径都从该源流出。这些路径包括控制流路径和数据流路径。根被分类为两个集合:高置信度根210;低置信度根212。高置信度根210包括那些在程序执行时更可能需要的程序元素,而低置信度根212反映那些在程序执行时不太可能需要的程序元素。
[0056] 一方面,高置信度根210包括程序的初始入口点(即main())、System.Object类、运行时环境支持的类型环境的类型、以及在运行时指导文件中被指定为必需的某些程序元素。System.Object类是所有其他类的基类,并且因此,其方法对于所有其他类进行操作而言都是必需的。同样,运行时环境支持的类型对于程序的执行是必需的,它们可能被包含在各种名称空间中。
[0057] 运行时行为描述文件114包含指导,该指导指示程序的执行是否需要特定类型或类型成员。这些特定的程序元素被视为高置信度根。例如指导<类型名称=”SomeType”动态=“需要全部”/>指示类型SomeType及其所有成员都是根,这是由于指示“需要全部”的使用。指导<组件名称=“*应用*”动态=”需要全部”/>指示需要不是.NET框架或运行时环境的每个类型和类型成员。但是,由于此指导是默认指导,因此,不是.NET框架或 运行时环境的部分的那些类型和类型成员可能不太可能运行,并且因此,它们被认为是低置信度根。
[0058] 分析引擎116读取元数据204和运行时行为描述114,以生成高置信度根210集合和低置信度根212集合(框208)。元数据204包含程序的初始入口点、System.Object命名空间中包含的方法以及类型环境的类型。运行时行为描述114包括指示附加高置信度根210和低置信度根212的指导。
[0059] 分析引擎116跟踪高置信度根210集合中的每个根到从根可到达的每个指令。对于每个指令,分析引擎116发现为了执行该指令而需要存在的依赖关系(框214)。分析引擎116检查静态依赖关系(框216)和动态依赖关系(框218)。静态依赖关系是语言编译器在编译时发现的依赖关系,而动态依赖关系是使用控制和/或数据流技术通过迭代跟踪发现的依赖关系。为了找到静态依赖关系,分析引擎116在元数据204中检查与指令中使用的任意类型、方法或字段相关联的依赖关系(框218)。如果依赖关系已经在表中,则分析引擎116不需要分类依赖关系(框218)。如果依赖关系不在表中,则基于规则的应用将依赖关系放置在高置信度队列或低置信度队列中(框218)。
[0060] 接下来,分析引擎116检查为了使指令运行所需的动态依赖关系(框220)。依赖关系被跟踪到接收器或众所周知的函数(框220)。如果在跟踪期间遇到的新依赖关系未在表中找到,则基于规则的应用,将其放置在高置信度队列或低置信度队列中(框220)。当跟踪到达接收器或众所周知的函数时,将依赖关系与基于规则的应用的相关联的分类一起被放置于表中(框220)。对于从高置信度和低置信度根可到达的每个指令,重复这些步骤216-220。
[0061] 接下来,对队列中的每个项目进行处理,以发现附加的静态和动态依赖关系,这些依赖关系是从根中追踪可到达指令时找不到的。高置信度队列中的每个项目被首先处理以发现附加静态依赖关系,并且然后被跟踪以找到附加动态依赖关系。如框218所示执行对静态依赖关系的发现,并且如框220所示执行对动态依赖关系的发现。在这些附加搜索之后,将规则应用于项目以将项目分类为高置信度或低置信度。然后将该项目及其分类存储在表中。重复该过程,直到高置信度队列中没有更多项目为止(框224)。
[0062] 然后,处理低置信度队列中的项目(框226)。针对附加静态依赖关系和附加动态依赖关系检查低置信度队列中的每个项目。如框218所示执行对静态依赖关系的发现,并且如框220所示执行对动态依赖关系的发现。在完成这些附加搜索之后,基于规则的应用,将该项目分类为高置信度或低置信度,并且将该项目及其分类存储在表中(框224)。
[0063] 当两个置信度队列都已被处理时,则输出具有置信度指示符的中间代码(框226)。一方面,中间语言代码用置信度指示符注释。在其他方面,中间语言代码和置信度标签在单独的文件中或在同一文件的单独部分中。应当注意,本文公开的方面不限于特定配置。
[0064] 图3示出了在本机代码的生成中利用置信度指示符的示例性方法300的流程图。参照图1和图3,本机编译器120接收标记的中间语言代码118,并启动各种过程以将程序转换成优化的本机代码。最初,本机编译器120基于置信度指示符确定要为哪些函数生成本机代码(框304)。例如本机编译器120可以确定是否应为通用类型的实例生成本机代码,或者允许运行时环境为通用类型的实例化生成代码(框304)。对于高置信度的实例,本机代码是优选的,因为它增加了执行速度(框304)。对于低置信度实例,运行时环境将在需要时生成代码(框304)。
[0065] 另外,本机编译器基于置信度指示符确定对方法执行哪些优化(框304)。例如对标记为高置信度的方法进行分析以用于内联。内联是代码优化,其中替换了方法的主体以代替对方法的调用。内联消除了进行调用的开销(即,在进行调用时将变量推入堆栈)和返回方法的开销(即,将变量弹出堆栈)。另外,本机编译器消除了没有被标记为低置信度或高置信度的不必要的代码(框304)。未标记代码的减少减少了应用的大小。
[0066] 然后,将中间语言代码(即,MSIL、CIL)编译为机器相关的中间语言(MDIL)307(框306)。MDIL基于目标体系结构的汇编语言。在此编译阶段,将执行众所周知的代码优化中的任意一个,诸如但不限于,分支消除、循环折叠、指令合并、常数折叠、常数传播、无效代码消除、整数除法优化、表达式简化、循环融合、内联、不变表达式消除、强度降低、循环展开等(框306)。
[0067] 接下来,绑定器将MDIL 307转换为用于目标体系结构的本机代码(框308)。绑定器还使用与标记的程序元素相关联的置信度指示符来确定机器指令的代码和数据布局(框308)。绑定器可以生成代码布局,该代码布局可优化目标体系结构的指令高速缓存的使用,以便于减少指令高速缓存的访问延迟。绑定器可以将指令从控制流程图的基本块映射到将热块与冷块分离的虚拟地址空间。热块是频繁使用的一部分代码,而冷块是较少频繁使用的一部分代码。置信度指示符可用于指示方法是被视为热块还是冷块。标记为高置信度的那些方法被视为热块,而标记为低置信度的这些方法则被视为冷块。绑定器可以生成代码布局,该代码布局将不同方法的热块彼此靠近放置,并且将冷块彼此靠近放置。通过这种方式,可以将热块加载到指令高速缓存中,从而提高程序的执行速度。可以标记冷块以用于延迟加载。延迟加载是指直到某个方法或对象被使用时才加载该方法或对象。
[0068] 此外,绑定器可以使用置信度指示符来优化数据的布局,以便改善空间局部性并减少存储器延迟(框308)。置信度指示符可用于区分热数据和冷数据。热数据是使用频率较高的数据,诸如标记为高置信度的类型和字段,冷数据是较不频繁使用的数据,诸如标记为低置信度的类型和字段。
[0069] 在绑定器处理完成时,输出本机或机器代码310(例如*.dll或*.exe)(框308)。
[0070] 应当注意,本机编译器的描述和在本机编译中使用的步骤是示例性的,并且本主题不限于上述本机编译器的配置和过程。例如本机编译可以在优化阶段使用配置文件数据作为代码优化的其他信息源。绑定器的色可以由本机编译器的代码生成器代替。
[0071] 技术效果
[0072] 本文公开的主题的各方面涉及为以具有动态特征或行为的编程语言编写的程序生成本机代码的技术问题。编程语言的动态特征是在运行时更改程序行为的特征。为了时间提前生成本机代码,采用静态分析来预测某些程序元素在程序执行中被使用的可能性,以便于确保本机代码包含执行程序所需的所有信息,特别是支持动态特征。
[0073] 与解决该问题相关的技术特征包括生成置信度指示符的分析引擎,以及使用置信度指示符生成和优化本机代码的本机编译器。分析引擎从可能执行程序的已知点静态跟踪程序流,并迭代跟踪可访问指令所需的每个依赖关系的数据流,以便于确定方法、类型和字段是否很可能在程序执行时使用或访问。置信度指示符用于标识程序执行时可能使用的方法、类型和字段的确定性程度。置信度指示符由本机编译器用来确定是否为某些方法和类型生成本机代码,以及执行哪些优化以降低程序的执行速度和本机代码的大小。
[0074] 示范性操作环境
[0075] 现在将注意力转向示例性操作环境的讨论。转到图4,这些方面可以利用至少一个计算设备402被应用于第一操作环境400。计算设备402可以是任意类型的电子设备,诸如但不限于,移动设备、个人数字助理、移动计算设备、智能电话、蜂窝电话、手持式计算机、服务器、服务器阵列或服务器场、Web服务器、网络服务器、刀片服务器、Internet服务器、工作站、小型机计算机、大型机、超级计算机、网络设备、Web设备、分布式计算系统、多处理器系统或其组合。可以在可以访问远程或本机存储设备的网络环境、分布式环境、多处理器环境或独立计算设备中配置操作环境400。
[0076] 计算设备402可以包括一个或多个处理器404、通信接口406、一个或多个存储设备408、一个或多个输入设备410、一个或多个输出设备412以及存储器414。处理器404可以是任意市售的或定制的处理器,并且可以包括双微处理器和多处理器体系结构。通信接口406促进计算设备402与其他设备之间的有线或无线通信。存储设备408可以是不包含传播信号的计算机可读介质,诸如通过载波传输的调制数据信号。存储设备408的示例包括但不限于RAM、ROM、EEPROM、闪存或其他存储技术、CD-ROM、数字多功能盘(DVD)或其他光学存储、磁带盒、磁带、磁盘存储,所有这些均不包含传播信号,诸如通过载波传输的调制数据信号。计算设备402中可以有多个存储设备408。输入设备410可以包括键盘鼠标、笔、语音输入设备、触摸输入设备等、以及它们的任意组合。输出设备414可以包括显示器、扬声器、打印机等、以及它们的任意组合。
[0077] 存储器412可以是可以存储可执行过程、应用和数据的任意非暂时性计算机可读存储介质。该计算机可读存储介质不涉及传播的信号,诸如通过载波传输的调制数据信号。它可以是任意类型的非暂时性存储器设备(例如随机存取存储器只读存储器等)、磁存储、易失性存储、非易失性存储、光学存储、DVD、CD、软盘驱动器等,其不涉及传播的信号,诸如通过载波传输的调制数据信号。存储器412还可包括与传播的信号不相关的一个或多个外部存储设备或位于远处的存储设备,诸如通过载波传输的调制数据信号。
[0078] 存储器412可以包含指令、部件和数据。部件是执行特定功能的软件程序,并且在其他方面也称为模块、程序和/或应用。存储器412可以包括操作系统420、一个或多个源代码文件422、包括元数据426和中间代码428的组件文件424、语言编译器430、本机编译器432、分析引擎434、标记的中间代码436、机器代码440、运行时行为描述文件442、规则文件
444以及其他应用和数据446。
[0079] 转向图5,这些方面可以应用于包括服务502的第二操作环境500,该云服务502为从客户端机器504与云服务502交互的用户提供按需编译服务的交付。在该操作环境中,云服务502可以体现为具有一组物理计算机的数据中心,这些物理计算机经由网络与一个或多个客户端计算机进行通信。替代地,云服务可以被配置为硬件(例如计算资源、网络资源、存储资源)和软件资源的池,其被配置为提供、创建和管理虚拟机及其操作系统以提供按需编译服务。云服务502可以是一个或多个计算设备506,每个计算设备包括一个或多个处理器508、存储器510和网络接口512。存储器510可以存储如上所述的分析引擎514和本机编译器516。
[0080] 由云服务502提供的编译服务可以是但不限于分析用于AOT编译的任意程序,包括以任意支持动态特征的编程语言编写的程序。在云服务502的一方面,客户端机器504可以向云服务502提交组件文件520和运行时行为描述文件522,并且响应于接收到这些文件,云服务502生成被传输回客户端机器504的本机代码524。替代地,云服务502可以包括语言编译器(未示出),该语言编译器将源代码文件编译为输入到分析引擎的中间语言代码。云服务502可以包括用于存储源代码文件的源代码存储库(未示出)、用于开发源代码文件的集成开发环境以及执行编译服务所需的其他工具。
[0081] 云服务502通过网络517与一个或多个客户端计算机504交互,其用户请求云服务502的编译服务。网络517可以是任意类型的通信介质,例如但不限于局域网、广域网,并且可以利用任意类型的通信协议(即有线或无线)。云服务502的计算设备506和客户端机器
504可以包括移动设备、个人数字助理、移动计算设备、智能电话、蜂窝电话、手持计算机、服务器、服务器阵列或服务器场、Web服务器、网络服务器、刀片服务器、Internet服务器、工作站、小型计算机、大型计算机、超级计算机、网络设备、Web设备、分布式计算系统、多处理器系统、或其组合。
[0082] 客户端机器504可以包括至少一个处理器526、存储器528和网络接口530,该网络接口530能够实现如上所述在云服务502与客户端机器504之间进行通信。一方面,客户端机器504的存储器528可以存储一个或多个源代码文件532、组件文件534、运行时行为文件536、本机代码538以及一种或多种语言编译器540。
[0083] 根据本文描述的主题的各方面,一种计算机系统可以包括一个或多个处理器以及连接到一个或多个处理器的存储器。该系统包括第一部件和第二部件。第一部件执行具有至少一个动态特征的程序的静态分析,以将多个置信度指示符中的至少一个与程序中的至少一个程序元素相关联。多个置信度指示符包括高置信度指示符和低置信度指示符。高置信度指示符将程序元素指定为具有在程序执行时使用的高置信度,而低置信度指示符将程序元素指定为具有在程序执行时使用的低置信度。第二个部件基于置信度指示符生成本机代码。
[0084] 程序元素包括面向对象的编程语言的类型、方法或字段中的至少一个。在一些方面,当通用类型与高置信度指示符相关联时,第二部件生成用于通用类型的实例化的本机代码,并且内联用高置信度指示符指定的方法。在其他方面,第二部件生成包括热代码和冷代码的代码布局,其中热代码包括与高置信度指示符相关联的一个或多个方法,而冷代码包括与低置信度指示符相关联的一个或多个方法。该系统可以包括语言编译器,该语言编译器生成程序的中间语言代码。第一部件使用中间语言代码来执行静态分析。动态特征包括反射、后期绑定和通用类型的实例化中的一项或多项。
[0085] 设备可以包括至少一个处理器和被连接到至少一个处理器的存储器。所述至少一个处理器被配置为对具有至少一个动态特征的程序执行静态分析,诸如但不限于反射。至少一个处理器将程序中的每种类型、方法和字段与多个置信度指示符中的至少一个相关联。多个置信度指示符包括高置信度指示符和低置信度指示符,其中高置信度指示符指示类型、方法或字段在程序执行时具有被使用的高置信度,而低置信度指示符指示类型、方法和字段在程序执行时具有被使用的低置信度。程序的静态分析跟踪从根可到达的每个指令,以发现由从根可到达的指令所需要的每个依赖类型、方法或字段,并且发现程序中每个依赖类型、方法和字段的使用。至少一个处理器将多个置信度指示符中的相应一个与跟踪中发现的每种方法、类型和字段相关联,并基于相关联的置信度指示符为程序生成优化的本机代码。
[0086] 对程序的中间语言代码表示执行静态分析。根包括进入程序的至少一个入口点、由与该程序相关联的类型环境所支持的类型和/或指示该程序执行所需的类型和类型成员的运行时指导。静态分析使用过程间和/或过程内数据流分析来发现依赖方法、类型和字段的使用。
[0087] 一种使用诸如上述系统和设备的系统和设备的方法,可以包括操作,诸如静态跟踪具有至少一个动态特征的程序的执行流程以确定在程序中哪些类型和类型成员被使用。静态跟踪发现从根可到达的指令用于执行所需的每个依赖关系,并发现程序中、每个依赖关系的使用。另外,该方法利用多个置信度指示符之一对在静态跟踪期间遇到的每种类型和类型成员进行分类。在一个或多个方面,多个置信度指示符包括高置信度指示符和低置信度指示符,其中高置信度指示符指示在程序执行时使用类型和/或类型成员的高置信度,并且低置信度指示符指示在程序执行时使用类型和/或类型成员的低置信度。该方法基于与程序的类型和/或类型成员相关联的置信度指示符来为程序优化本机代码。
[0088] 类型和类型成员包括方法和字段。程序的根包括程序入口点、由与程序相关联的运行时支持的类型、以及指示程序的必要程序元素的运行时指导中的至少一个。该方法通过跟踪到接收器的每个依赖关系,使用多个置信度指示符之一对跟踪期间遇到的每种类型和类型成员进行分类,并应用一个或多个规则来确定将哪个置信度指示符与依赖关系相关联。接收器是定义的方法或具有已知行为的一系列动作。该方法通过为与高置信度指示符相关联的那些方法生成本机代码来优化本机代码。该方法包括将程序编译成中间语言代码,并为该程序生成元数据,该元数据包括针对在编译期间已知的每种类型和类型成员的一个或多个依赖关系。静态跟踪从与类型和类型成员关联的元数据中发现依赖关系。静态分析使用过程间和/或过程内数据流分析来发现依赖关系的使用。
[0089] 尽管已经以特定于结构特征和/或方法动作的语言描述了主题,但是应该理解,所附权利要求书中定义的主题不必限于上述特定特征或动作。相反,上述特定特征和动作被公开为实现权利要求的示例形式。
高效检索全球专利

专利汇是专利免费检索,专利查询,专利分析-国家发明专利查询检索分析平台,是提供专利分析,专利查询,专利检索等数据服务功能的知识产权数据服务商。

我们的产品包含105个国家的1.26亿组数据,免费查、免费专利分析。

申请试用

分析报告

专利汇分析报告产品可以对行业情报数据进行梳理分析,涉及维度包括行业专利基本状况分析、地域分析、技术分析、发明人分析、申请人分析、专利权人分析、失效分析、核心专利分析、法律分析、研发重点分析、企业专利处境分析、技术处境分析、专利寿命分析、企业定位分析、引证分析等超过60个分析角度,系统通过AI智能系统对图表进行解读,只需1分钟,一键生成行业专利分析报告。

申请试用

QQ群二维码
意见反馈