具体实施方式
下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员所获得的所有其他实施例,都属于本申请保护的范围。
本申请的核心构思在于,提出了一种系统的提前编译方法和装置。如图1所示,在该提前编译方法和装置中,可以在编译阶段的步骤1001中在提前编译阶段将动态编程语言编译后生成的字节码、相关符号表及常量池等编译数据链接到动态编程语言系统的内存管理单元上,由内存管理单元进行管理。在步骤S1002链接至内存管理单元之后,在步骤S1003中这些编译数据可以在内存管理单元的管理分配下按照指定格式写入提前编译文件。在执行程序的阶段,上述提前编译文件在步骤S2001中被直接加载到内存管理单元中运行,从而节省了编译的时间,加快了动态编程语言执行前加载速度,减小了执行动态编程语言的内存占用量。
第一实施例
本申请第一实施例提出一种系统的提前编译方法。图2所示为本申请第一实施例的提前编译方法的步骤流程图。本申请实施例的系统例如可以是动态编程语言系统,是指运行该动态语言的运行环境。如图2所示,所述系统的提前编译方法包括可以如下步骤:
S101,根据源程序生成编译数据;
在这一步骤中,执行主体,例如服务器、客户端等各种电子装置,可以调用系统的已有的编译器中的源程序处理程序,例如词法解析、语法分析、字节码生成组件等,对源程序进行编译词法解析、语法解析,生成动态语言系统可以直接运行的字节码和/或本地代码,以及相关的常量池和符号表,这些字节码、常量池和符号表可以称为源程序经过编译后生成的“编译数据”,即编译数据可以包括字节码、常量池和符号表。
在上述编译数据中,字节码(Byte-code)是一种经过编译器预处理过的二进制文件,其包含执行程序,并由一序列操作码/数据对组成。符号表是一种数据结构,其为每一个变量名字创建一个记录条目,记录的字段就是名字的各个属性,该数据结构允许编译器迅速查找到每个变量名字的记录条目,并向记录条目中快速存放变量的属性、存储位置等编译数据,并获取记录中的上述编译数据。常量池中包含代码中所定义的各种基本类型(如int、long等等)和对象型(如String及数组)的常量值,还包含一些以文本形式出现的符号引用,比如:类和接口的全限定名、字段的名称和描述符、方法的名称和描述符等。
S102,将所述编译数据链接至内存管理单元;
在这一步骤中,系统该可以将编译数据链接至内存管理单元,由内存管理单元进行管理。其中,“链接”可以指指将编译器生成的一个或多个目标文件(object files)组合成一个可执行文件、库文件或者另一个目标文件的过程。
当这些编译数据存储在存储空间时,步骤S102具体可以包括将这些字节码和符号表、常量池等编译数据所在的存储空间链接至内存管理单元。
内存管理单元例如是系统堆,是指由动态语言系统下属的内存管理系统所管理的内存区域。内存管理单元用于实现动态语言系统自动内存分配,动态编程语言的内存分配和释放是通过从内存管理单元申请和退还内存实现的。
将存储空间“链接”至内存管理单元,例如是将创建的存储空间对应的虚拟地址加入到内存管理单元中,由内存管理单元对该存储空间进行管理。在实现上,可以将编译数据移动至动态编程语言系统的存储空间中,并链接至内存管理单元。
动态编程语言系统的存储空间的单位例如是“存储页”,在这一步骤中,可以将上述编译数据移动至存储页内,将存储页中的编译数据作为一个整体链接至内存管理单元上。在一可选实施例中,这些存储页可以为连续的存储页,例如为临时创建的存储页,这些存储页的格式与所述动态编程语言系统的存储页格式相匹配,例如格式一致。将编译数据移动到连续的存储页可以节省空间,以在将编译数据写入提前编译文件时节省存储空间。
这一步骤中,将编译数据链接到内存管理单元上,可以是将编译数据所在的存储页的连续或不连续的页地址链接到内存管理单元上。当包含上述编译数据的页地址被链接到内存管理单元上后,这些页方能被内存管理单元管理,包括执行读取、遍历等操作,以顺利执行后续的加载过程。
S103,依据所述链接至内存管理单元中的编译数据生成提前编译文件;
在这一步骤中,系统可以依据链接至内存管理单元中的编译数据生成提前编译文件。具体地,如果编译数据是存储在存储空间中,而存储空间的地址已在步骤S102中链接至内存管理单元,则在步骤S103中,这些编译数据便可以由动态编程语言系统来进行管理。在这一步骤中,动态编程语言系统可以对编程数据的存储空间进行扫描,获取指定的内容写入提前编译文件。
在一具体实施例中,可以按照指定格式,例如提前编译文件的格式,从存储空间中的编译数据中提取所述指定格式中的各项目对应的项目内容,并将各项目内容写入提前编译文件,从而生成满足指定格式的提前编译文件。
上述指定格式可以是系统原先定义的或者由开发人员定义的。在本申请一实施例中,指定格式包括的项目例如可以包括:文件头、程序字节码地址表、公用对象地址表、提前编译对象页面地址表和提前编译对象页表等至少其一;上述文件头例如可以包括:源程序数量、公用对象数量、编译数据占用的存储空间信息,例如占用的页面数。程序字节码地址表用于存储编译数据中的字节码地址;公用对象地址表用于存储编译数据对应的公用对象的地址;提前编译文件地址表用于存储所述提前编译文件的地址;提前编译对象页表用于存储所述提前编译文件对应的对象的地址。
在这一步骤中,执行主体可以遍历上述编译数据的存储空间,按照提前编译文件头格式构造文件头结构,写入文件。然后依次写入程序字节码地址表、公用对象地址表、提前编译文件地址表、提前编译对象地址表。最后写入存储空间的所有页面内容,从而依据编译数据生成提前编译文件。
S104,将所述提前编译文件加载至所述内存管理单元;
在一实施例中,根据提前编译文件的格式可知,提前编译文件的核心内容包括多个可以直接映射到动态编程语言系统的系统内存的存储页。
在一实施例中,将所述提前编译文件加载至所述系统堆内存管理单元的步骤可以通过如下方式实现:
读入文件头并映射到系统空间;根据所述文件头中对应的源程序数量、公用对象数量和编译数据占用的存储空间信息,将所述提前编译文件映射至动态编程语言系统的系统存储空间;以及将映射至所述内存空间的提前编译文件加载到所述内存管理单元。
在读入文件头并映射到系统空间的步骤中,可以读取文件头,并将文件头映射到系统内存的进程空间;从而可以由动态编程语言系统快速访问文件头这一项目所对应的项目内容。之后,可以利用文件头的结构,将提前编译文件中的存储页面中的存储内容依次映射到系统内存的进程空间,并链接到内存管理单元中,即将这些页面对应的地址加入内存管理单元中,以在动态语言系统访问这些页面中的地址时,可以像正常的动态语言系统访问自己生成的内容一样。
由上述可知,本申请第一实施例提出的系统的提前编译方法至少具有如下技术效果:
本申请实施例提供的提前编译方法在避免占用大量系统内存进行序列化和反序列化的前提下实现了动态编程语言的提前编译。与现有的动态类型语言提前编译方法相比,本申请将编译数据链接所在的存储空间链接至内存管理单元后,对编译数据进行处理生成提前编译文件,再将提前编译文件加载到内存管理单元,在每次执行源程序时提前编译文件已存在于内存管理单元,不需要再生成提前编译文件,即,本申请不需要在每次执行程序时执行读入字节码、译码、反序列化、重构对象的步骤,减少了系统内存占用量,提高了程序响应速度。
第二实施例
本申请第二实施例提出一种提前编译方法。图3所示为本申请第二实施例的提前编译方法的步骤流程图。如图3所示,本申请实施例的提前编译方法如下步骤:
S201,根据源程序生成编译数据;
S202,将所述编译数据链接至内存管理单元;
S203,依据链接至内存管理单元中的编译数据生成提前编译文件;
S204,将所述提前编译文件加载至所述内存管理单元;
S205,初始化系统;
S206,运行所述源程序。
上述步骤S201至步骤S204与上一实施例的步骤S101至步骤S104相同或相似,在此不再赘述。本实施例重点说明与上一实施例的不同之处。
在本申请系统的提前编译方法的实施例中,还包括步骤S205和步骤S206。在将编译数据写入提前编译文件之后,可以初始化系统并于进行源程序。步骤S205的初始化系统是将系统环境初始化至可以运行源程序的程度,例如释放不需要的变量、为动态编程系统分配系统空间等;在初始化之后可以运行源程序。由于根据源程序所生成的编译数据对应的提前编译文件已存在于内存管理单元中,在步骤S206运行源程序的步骤中,源程序可以直接运行,不需要执行读入字节码、译码、反序列化、重构对象的步骤,减少了系统内存占用量。
在本申请系统的提前编译方法的一实施例中,步骤S202即将所述编译数据链接至内存管理单元的步骤具体可以包括:将所述编译数据所在的存储空间链接至内存管理单元。
在该步骤中,可以进一步对这些编译数据进行标识上述的编译数据(即与提前编译相关的内容,包括上一步骤中的字节码、符号表和常量池),利用现有移动垃圾回收(Moving Garbage Collection)算法的移动对象机制,将上述编译数据移动到新创建的存储空间内,然后将该存储空间链接到系统堆内存管理单元上。此后,可以启动垃圾回收功能,将未被标识的对象占用的内存回收到系统。
在可选实施例中,还可以利用基于分代的垃圾回收(Generational GarbageCollection)算法优化链接方法,只扫描上述编译数据所在的存储区域,以及与编译数据相关的区域,实现减少扫描区域的目的。具体地,可以利用垃圾回收算法快速标识不再活跃的内存区域。一旦标识了这些区域,就可以将它们重新用于新对象的创建或者由操作系统收回管理。
由于动态编程语言系统中大多数对象创建后不久就销毁,只有少数对象存活时间比较长,所以动态语言系统实现了基于分代的垃圾回收算法。在垃圾回收算法中可以将系统堆内存管理单元划分为新生代和老年代两个空间。新生代是指该空间内的动态对象在发生一次垃圾回收算法就不再存活,所分配的内存空间被释放掉;一般对象创建时是在新生代分配。老年代是指该空间内的对象一般会继续存活下去,一般是经历了一次垃圾回收后从新生代移动而来的。
动态编程语言经过编译生成的对象编译数据一般在新生代创建。经过一定时间后,如果对象还存活,就将它移动到老年代。从而在对象编译数据频繁创建和销毁的新生代上需要运行垃圾回收算法的次数也比老年代会频繁。由于堆空间的划分,在子空间内的标识对象的速度明显快于需要扫描整个堆空间。为了快速分配和回收子空间内的内存,将每个子空间划分为若干区域。每个区域为一块地址连续的内存空间,每个区域的大小可以相同或者不同,其最小单位为操作系统的页单位大小。从而可以将一个或多个区域快速保存到文件,也可以将按该区域结构组织的文件内容快速加载(例如利用类unix的mmap机制)到系统并链接到堆内存管理单元中。
如图4所示,所述步骤S202,即将所述编译数据的存储空间链接至内存管理单元的步骤,例如可以包括如下子步骤:
S2021,获取编译数据中的根节点对象;
一个动态语言程序编译成字节码形式后,该程序的入口对象即为根节点对象。根节点对象为具有父子关系的对象树的根节点,在这一步骤中,可以设置根节点对象集合,将程序的所有入口对象加入根节点集合中。
S2022,确定根节点对象对应的子节点对象;
在这一步骤中,可以从根节点对象出发,找到与该根节点对象有引用关系的所有子节点对象。
举例来说,实际操作中年可以利用垃圾回收算法的标识(mark)算法,对根节点对象集合中每个对象,标识能从该根节点对象访问的子节点对象,即根节点对象对应的每一个可达对象,并将每个被标识的可达对象所在的存储地址(例如所在的存储页的页地址)保存到数据结构marked_regions中。在这一步骤中,每遍历一个可达对象时,就可以将它所在的页地址保存到数据结构marked_regions中。
S2023,将所述根节点对象和所述子节点对象移动至存储空间中;
在这一步骤中,可以通过遍历上述数据结构marked_regions的存储页的方式,将所标识的子节点对象进行移动,移动到存储空间aot_target_space,在移动之后当前页已无标记对象,则可以选择释放当前页。存储空间可以是当下创建并用来存放提前编译相关对象的空间。这一存储空间可以是新分配的空间,也可以是原有的空间。
在遍历marked_regions中页时,利用垃圾回收算法的移动垃圾回收算法中的移动对象机制,将当前遍历页中所有被标识的可达对象移动到新分配的内存区域aot_target_regions中。
由上述可知,子步骤S2023具体可以包括如下分步骤:
S2023a,标识根节点对象对应的子节点对象;
S2023b,将标识后的子节点对象移动到所述存储空间的连续地址内。
在步骤S2023a或步骤S2023b之后,该子步骤S2023还可以包括:
S2023c,回收未标识的存储空间。
在本申请系统的提前编译方法的一实施例中,所述步骤S2023,即将所述子节点对象移动至存储空间中的步骤之后,所述方法还包括:
S2024,记录所述子节点对象移动前的地址和移动后的地址;
S2025,根据移动前的存储地址和移动后的存储地址更新该存储空间内的对象引用关系。
在子步骤S2024中,由于对象和对象之间可能存在引用和被引用的关系,因此在移动对象时,可以记录所述子节点对象移动前的地址和移动后的地址,如果一个对象A的地址发生变更,则意味着引用该对象A的对象B所引用的地址(即对象A的地址)发生变更。记录对象移动前和移动后的地址,并在对象A的地址发生变更后改变对象B所引用的地址,可以保证这些对象未移动前的引用关系在移动后还能保持一致。在一实施例中,在一个存储页内的对象移动完后,可以更新该页内的对象引用关系。在所有对象都移动到存储空间后,可以再根据保存有引用关系的有序结构,更新不同页内的对象引用关系。
在子步骤S2025中,利用前一步记录的地址,更新存储空间aot_target_regions中的所有对象引用,确保其所有对象引用有效。更新地址薄记中的地址引用关系能够使所有对象的引用关系有序、不混乱。
在本申请系统的提前编译方法的一实施例中,所述步骤S2025,即根据移动前的存储地址和移动后的存储地址更新该存储空间内的对象引用的步骤之后,可以执行上述子步骤S2026:
S2026,将所述存储空间链接到内存管理单元;
在这一步骤中,可以将存储空间aot_target_space中的存储页合并,再链接到内存管理单元。作为一个可选的实施例,合并页可以将存储页中占用的空间整合,而将没有利用的大部分空间释放,在写入文件时,相对于不合并页的方式,合并页的方式不会过多地占用磁盘空间。
在本申请系统的提前编译方法的一实施例中,如图5所示,所述步骤S203,即依据存储单元中的编译数据和指定格式生成提前编译文件的步骤可以包括如下子步骤:
S2031,获取提前编译文件的指定格式所包括的至少一个项目;
S2032,从所述编译数据中查找所述项目对应的项目内容,并写入所述提前编译文件。
指定格式的项目例如可以包括:文件头、程序字节码地址表、公用对象地址表、提前编译对象页面地址表和提前编译对象页表;其中,文件头例如可以包括:源程序数量、公用对象数量、编译数据占用的存储空间信息。此外,文件头例如还可以包括魔术数字、版本号、校验和。
例如,程序字节码地址表的内容为程序字节码的地址,根据该地址可以访问程序字节码;公用对象地址表的内容为动态编程语言系统的公用对象的地址,根据该地址可以访问各公用对象;提前编译对象页面地址表的内容为提前编译对象在页中的地址,提前编译对象页表的内容为提前编译对象所在的页的地址。
文件头中记载的源程序数量为提前编译的源程序的数据量;公用对象数量为动态编程语言系统的公用对象的数目;编译数据占用的存储空间信息例如为存储空间中提前编译对象所占的存储页的总数。
文件头中包括的版本号例如用来确定文件版本,魔术数字为预设的数字,用来简单校验任意文件是否为提前编译文件;校验和是在生成提前编译文件的时候将提前编译文件内的所有地址经过计算得到的一串数字,可以用来验证提前编译文件是否经过篡改。
在这一步骤中,遍历aot_target_regions中的内存区域,按照提前编译文件头格式,构造文件头结构,写入文件。然后依次写入程序字节码地址表、公用对象地址表、提前编译对象页面地址表。最后写入内存区域aot_target_regions所有页面内容。从而实现加载提前编译文件。
在本申请系统的提前编译方法的一实施例中,如图6所示,所述步骤S204即将所述提前编译文件加载至所述内存管理单元的步骤包括如下子步骤:
S2041,将所述文件头映射至系统的系统存储空间;
在这一步骤中,执行主体首先可以读入文件头,并将文件头映射到当前系统的进程空间,从而可以快速访问文件头的内容。在具体操作中,每一存储页有一个开始地址和存储页的容量数据,映射时将开始地址和页的容量数据作为参数,调用操作系统的映射机制将该页映射到操作系统环境中。
在本申请系统的提前编译方法的一实施例中,所述步骤S204即将所述提前编译文件加载至所述内存管理单元的步骤还包括:
S2042,利用所述文件头的内容,验证文件正确性。
在这一步骤中,可以利用文件头包含的内容,验证文件的版本和正确性。例如,首先可以验证魔术数字是否和预设的一致,然后将提前编译文件内的所有地址使用同样的规则计算得到一串数字,和校验和比较是否相等,如果相等就认为加载的提前编译文件是完整、安全的。
在本申请系统的提前编译方法的一实施例中,所述步骤S204即将所述提前编译文件加载至所述内存管理单元的步骤还包括:
S2043,禁止内存管理单元上内存分配申请。
在这一步骤中,为将提前编译文件中的所有页面映射并链接到内存管理单元上准备一个干净环境,可以利用动态语言系统的垃圾回收机制提供的禁止内存分配的功能,禁止内存管理单元上的内存分配申请。
在本申请系统的提前编译方法的一实施例中,所述步骤S204即将所述提前编译文件加载至所述内存管理单元的步骤还可以包括如下子步骤:
S2044,获取提前编译文件中与所述文件头中的源程序数量、公用对象数量、编译数据占用的存储空间信息对应的目标信息,并将该目标信息映射至系统存储空间;
在步骤S2044中,可以利用文件头的结构,将提前编译文件中的所有页内容依次映射到内存空间。
S2045,将映射至所述系统存储空间的目标信息加载到所述内存管理单元;
在步骤S2045中,可以将目标信息从系统存储空间映射到内存管理单元中,由内存管理单元进行管控。
在本申请系统的提前编译方法的一实施例中,所述步骤S204即将所述提前编译文件加载至所述内存管理单元的步骤还可以包括如下子步骤:
S2046,对比动态编程语言系统的系统符号表与提前编译文件的符号表;
S2047,当所述系统符号表与所述提前编译文件的符号表存在相同符号时将相同符号在系统符号表中的地址替换为所述提前编译文件的符号表中的地址。
在这一步骤中,处理可能存在的提前编译文件的符号表和系统符号表冲突,也就是合并重复的符号表项。消除重复的符号表项可能导致的系统正确性问题。其具体的实现过程例如可以为:提前编译文件的符号表中记录了所有的符号,依次将记录的每个符号作为关键词,去系统的符号表里查找,如果找到了就会返回一个地址,然后用当前作为去替换找到的地址。如果没有找到,就将当前作为关键词的地址插入到符号表中。这样可以让提前编译文件mmap的地址范围的写时拷贝(copy on write,COW)尽量少。
在将编译数据写入提前编译文件之后,可以初始化系统并于进行源程序。步骤S205的初始化系统是将系统环境初始化至可以运行源程序的程度,例如释放不需要的变量、为动态编程系统分配系统空间等;如图7所示,步骤S206运行原程序的步骤可以包括如下子步骤:
S2061,根据所述提前编译文件建立检索数据结构,所述检索数据结构包括动态语言程序名称和对应的字节码地址;
S2062,在该检索数据结构中查找是否存在目标动态语言程序名称;
S2063,当该检索数据结构中存在该目标动态语言程序名称时,获取该目标动态语言程序名称对应的字节码地址;
S2064,根据该字节码地址加载字节码。
在步骤S206的各子步骤中,由于源程序的编译数据,包括字节码、符号和常量池已经通过提前编译文件加载到内存管理单元,在这一步骤中可以将提前编译文件中动态语言程序名称和对应的字节码地址建立一个便于查找的数据结构(例如映射)aot_scripts中。
运行过程中,当需要执行某个文件时,首先在aot_scripts中查询该文件是否在提前编译文件中已经生成了编译数据。如果没有查询到,继续按照系统原有流程执行读入源程序、词法解释、语法分析、生成字节码等动作;如果查询到,直接返回该文件对应的字节码地址。
在提前编译文件的运行源程序子系统中,都会查询到对应源程序的字节码地址。然后利用操作系统的内存管理机制将该地址对应的页面加载进系统,这样的处理省去了原有系统的读入源程序、词法解析、语法分析、字节码生成等过程。如果某个源程序在执行过程中没有用到,那么该文件对应的页不会被操作系统加载进当前进程空间。也就是只有真正被访问到的地址才被实际加载到操作系统的存储管理子系统中。从而减少了系统内存占用。
综上所述,本实施例提出的系统的提前编译方法至少具有如下优点:
本申请实施例提供的方法,利用动态类型语言系统自身提供的机制,实现了一种适用于动态类型语言系统的提前编译方法。与现有的动态类型语言提前编译方法相比,本申请将提前编译文件加载到内存管理单元后,就可以直接运行,在程序运行时不需要再执行读入源代码文件、解释、生成字节码等动作;也不需要读入字节码、译码、反序列化、重构对象。本申请提供的方法具有系统开销小,程序响应速度快等优点。
除此之外,本实施例提出的系统的提前编译方法至少还包括如下优点:
本申请实施例提供的方法中,通过动态编程语言自身的解释器和垃圾回收机制,利用特有的加载方式,在程序执行时通过内存映射机制将提前编译文件映射到动态类型语言系统并链接到内存管理单元中,跳过读入源程序、词法解析、语法分析、生成字节码等步骤,不需要重新构造对象和恢复堆等动作,从而加快程序的执行速度。基于特有的加载方式,可以做到按需页加载,减少内存占用,提高程序响应速度。
此外,本申请采用定制的垃圾回收机制为了精简提前编译文件,提高程序加载速度,利用现有的移动垃圾回收算法,实现了定制的提前编译垃圾回收算法。以当前程序生成的字节码,符号表和常量池为根节点对象开始遍历内存管理单元,将无关对象回收到自动存储管理系统。然后将编译数据移动到堆的连续地址空间,随后将这一连续地址空间的内容写入文件。确保提前编译文件中的对象没有冗余。
再者,在本申请提出的方案中,为了顺利将提前编译文件映射到系统并链接到堆中,本申请优选实施例中可以对指定格式进行了定制,例如包含文件头、程序字节码地址列表、公用对象地址列表、提前编译对象页面地址列表、提前编译对象页列表等,其中文件头可以包括魔术数字、版本号、源程序数量、公用对象数量、提前编译文件占用页面数、校验和等,采用上述的格式,利用提前编译文件可以直接恢复程序的字节码,符号表和常量池,将这些相关的对象链接到内存管理单元中,完全省去了反序列化的过程,耗时最少,内存占用最低,可以应用在系统程序和应用程序中。
以上所描述的装置实施例仅仅是示意性的,其中所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部模块来实现本实施例方案的目的。本领域普通技术人员在不付出创造性的劳动的情况下,即可以理解并实施。
本申请的各个部件实施例可以以硬件实现,或者以在一个或者多个处理器上运行的软件模块实现,或者以它们的组合实现。本领域的技术人员应当理解,可以在实践中使用微处理器或者数字信号处理器(DSP)来实现根据本申请实施例的服务器中的一些或者全部部件的一些或者全部功能。本申请还可以实现为用于执行这里所描述的方法的一部分或者全部的设备或者装置程序(例如,计算机程序和计算机程序产品)。这样的实现本申请的程序可以存储在计算机可读介质上,或者可以具有一个或者多个信号的形式。这样的信号可以从因特网网站上下载得到,或者在载体信号上提供,或者以任何其他形式提供。
例如,图8示出了可以实现根据本申请的语音处理方法的服务器,例如应用服务器。该服务器传统上包括处理器310和以存储器320形式的计算机程序产品或者计算机可读介质。存储器320可以是诸如闪存、EEPROM(电可擦除可编程只读存储器)、EPROM、硬盘或者ROM之类的电子存储器。存储器320具有用于执行上述方法中的任何方法步骤的程序代码331的存储空间330。例如,用于程序代码的存储空间330可以包括分别用于实现上面的方法中的各种步骤的各个程序代码331。这些程序代码可以从一个或者多个计算机程序产品中读出或者写入到这一个或者多个计算机程序产品中。这些计算机程序产品包括诸如硬盘,紧致盘(CD)、存储卡或者软盘之类的程序代码载体。这样的计算机程序产品通常为如参考图9所述的便携式或者固定存储单元。该存储单元可以具有与图8的服务器中的存储器320类似布置的存储段、存储空间等。程序代码可以例如以适当形式进行压缩。通常,存储单元包括计算机可读代码331’,即可以由例如诸如310之类的处理器读取的代码,这些代码当由服务器运行时,导致该服务器执行上面所描述的方法中的各个步骤。
因此,本申请第三实施例提出一种电子装置,该电子装置包括:
进一步地,本申请第四实施例提出一种电子装置,该电子装置包括:
存储器,用于存储计算机可读程序;
处理器,当所述处理器读取所述存储器中的计算机可读程序时,所述电子装置执行如下操作:
根据源程序生成编译数据;
将所述编译数据链接至内存管理单元;
将所述链接至内存管理单元的编译数据写入提前编译文件;
将所述提前编译文件加载至所述内存管理单元。
本实施例提出的电子装置至少具有如下优点:
本申请实施例提供的电子装置,利用动态类型语言系统自身提供的机制,实现了一种适用于动态类型语言系统的提前编译方法。与现有的动态类型语言提前编译方法相比,本申请将提前编译文件加载到内存管理单元后,就可以直接运行,在程序运行时不需要再执行读入源代码文件、解释、生成字节码等动作;也不需要读入字节码、译码、反序列化、重构对象。本申请提供的方法具有系统开销小,程序响应速度快等优点。
进一步地,本申请第四实施例提出一种电子装置,该电子装置包括:
存储器,用于存储计算机可读程序;
处理器,当所述处理器读取所述存储器中的计算机可读程序时,所述电子装置执行如下操作:
根据源程序生成编译数据;
将所述编译数据链接至内存管理单元;
将所述链接至内存管理单元的编译数据写入提前编译文件;
将所述提前编译文件加载至所述内存管理单元。
在本申请电子装置的一实施例中,所述将所述编译数据链接至内存管理单元的步骤包括:
将所述编译数据所在的存储空间链接至内存管理单元;
所述依据所述链接至内存管理单元中的编译数据生成提前编译文件的步骤包括:
依据存储空间的编译数据和指定格式生成提前编译文件。
在本申请电子装置的一实施例中,所述依据存储空间中的编译数据和指定格式生成提前编译文件的步骤包括:
获取提前编译文件的指定格式所包括的至少一个项目;
从所述编译数据中查找所述项目对应的项目内容,并写入所述提前编译文件。
在本申请电子装置的一实施例中,所述项目包括如下至少其中之一:
文件头、程序字节码地址表、公用对象地址表、提前编译对象页面地址表、提前编译对象页表;
其中所述文件头包括源程序数量、公用对象数量和编译数据占用的存储空间信息。
在本申请电子装置的一实施例中,将所述提前编译文件加载至所述内存管理单元的步骤包括:
将所述文件头映射至系统的系统存储空间;
获取提前编译文件中与所述文件头中的源程序数量、公用对象数量、编译数据占用的存储空间信息对应的目标信息,并将该目标信息映射至系统存储空间;以及
将映射至所述系统存储空间的目标信息加载到所述内存管理单元。
在本申请电子装置的一实施例中,将所述提前编译文件加载至所述内存管理单元的步骤还包括:
禁止内存管理单元的内存分配申请。
在本申请电子装置的一实施例中,所述将所述提前编译文件加载至所述内存管理单元的步骤还包括:
对比动态编程语言系统的系统符号表与提前编译文件的符号表;
当所述系统符号表与所述提前编译文件的符号表存在相同符号时,将相同符号在系统符号表中的地址替换为所述提前编译文件的符号表中的地址。
在本申请电子装置的一实施例中,在将所述提前编译文件加载至所述内存管理单元的步骤之后,所述方法还包括:
初始化系统;以及
运行所述源程序。
在本申请电子装置的一实施例中,所述运行源程序的步骤包括:
根据所述提前编译文件建立检索数据结构,所述检索数据结构包括动态语言程序名称和对应的字节码地址;
在该检索数据结构中查找是否存在目标动态语言程序名称;
当该检索数据结构中存在该目标动态语言程序名称时,获取该目标动态语言程序名称对应的字节码地址;
根据该字节码地址加载字节码。
在本申请电子装置的一实施例中,将所述编译数据所在的存储空间链接至内存管理单元的步骤包括:
获取编译数据中的根节点对象;
确定根节点对象对应的子节点对象;
将所述根节点对象和所述子节点对象移动至所述存储空间中;
将所述存储空间链接到所述内存管理单元。
在本申请电子装置的一实施例中,所述存储空间包括存储页,所述存储页的格式与所述动态编程语言系统的系统存储空间的格式匹配。
在本申请电子装置的一实施例中,将所述根节点对象和所述子节点对象移动至所述存储空间中的步骤之后,所述方法还包括:
记录所述根节点对象和所述子节点对象移动前的存储地址和移动后的存储地址;以及
根据移动前的存储地址和移动后的存储地址更新所述存储空间内的对象引用关系。
在本申请电子装置的一实施例中,将所述根节点对象和所述子节点对象移动至所述存储空间中的步骤包括:
标识根节点对象对应的子节点对象;
将标识后的子节点对象移动到所述存储空间的连续地址内。
在本申请电子装置的一实施例中,在标识根节点对象对应的子节点对象的步骤之后,还包括:
回收未标识的存储空间。
综上所述,本实施例提出的电子装置至少具有如下优点:
本申请实施例提供的电子装置,利用动态类型语言系统自身提供的机制,实现了一种适用于动态类型语言系统的提前编译方法。与现有的动态类型语言提前编译方法相比,本申请将提前编译文件加载到内存管理单元后,就可以直接运行,在程序运行时不需要再执行读入源代码文件、解释、生成字节码等动作;也不需要读入字节码、译码、反序列化、重构对象。本申请提供的方法具有系统开销小,程序响应速度快等优点。
除此之外,本实施例提出的电子装置至少还包括如下优点:
此外,本申请采用定制的垃圾回收机制为了精简提前编译文件,提高程序加载速度,利用现有的移动GC算法,实现了定制的提前编译垃圾回收算法。以当前程序生成的字节码,符号表和常量池为根节点对象开始遍历内存管理单元,将无关对象回收到自动存储管理系统。然后将提前编译相关对象移动到堆的连续地址空间,随后将这一连续地址空间的内容写入文件(我们称之为提前编译文件)。确保提前编译文件中的对象没有冗余。
再者,在本申请提出的方案中,为了顺利将提前编译文件映射到系统并链接到堆中,本申请优选实施例中对指定格式进行了定制,例如指定格式中的项目包括文件头、程序字节码地址列表、公用对象地址列表、提前编译对象页面地址列表和提前编译对象页列表;文件头例如包括魔术数字、版本号、源程序数量、公用对象数量、所有提前编译对象占用页面数、校验和等。采用上述的格式,利用提前编译文件可以直接恢复程序的字节码、符号表和常量池,将所有相关的对象链接到堆中,完全省去了反序列化的过程,耗时最少,内存占用最低,程序访问局部性好,可以应用在系统程序和应用程序中。
本申请实施例还提出一种系统的提前编译装置,如图10所示,该提前编译装置包括:
编译数据生成模块501,用于根据源程序生成编译数据;
编译数据链接模块502,用于将所述编译数据链接至内存管理单元;
提前编译文件生成模块503,用于依据所述链接至内存管理单元中的编译数据生成提前编译文件;
加载模块504,用于将所述提前编译文件加载至所述内存管理单元。
本实施例提出的提前编译装置至少具有如下优点:
本申请实施例提供的装置,利用动态类型语言系统自身提供的机制,实现了一种适用于动态类型语言系统的提前编译方法。与现有的动态类型语言提前编译方法相比,本申请将提前编译文件加载到内存管理单元后,就可以直接运行,在程序运行时不需要再执行读入源代码文件、解释、生成字节码等动作;也不需要读入字节码、译码、反序列化、重构对象。本申请提供的方法具有系统开销小,程序响应速度快等优点。
本申请实施例还提出一种系统的提前编译装置,如图11所示,该提前编译装置包括:
编译数据生成模块601,用于根据源程序生成编译数据;
编译数据链接模块602,用于将所述编译数据链接至内存管理单元;
提前编译文件生成模块603,用于依据所述链接至内存管理单元中的编译数据生成提前编译文件;
加载模块604,用于将所述提前编译文件加载至所述内存管理单元。
在本申请提前编译装置的一实施例中,所述编译数据链接模块用于:
将所述编译数据所在的存储空间链接至内存管理单元;
所述提前编译文件生成模块用于:
依据存储空间的编译数据和指定格式生成提前编译文件。
在本申请提前编译装置的一实施例中,所述提前编译文件生成模块603包括:
项目获取子模块,用于获取提前编译文件的指定格式所包括的至少一个项目;
项目内容查找子模块,用于从所述编译数据中查找所述项目对应的项目内容,并写入所述提前编译文件。
在本申请提前编译装置的一实施例中,所述项目包括如下至少其中之一:
文件头、程序字节码地址表、公用对象地址表、提前编译对象页面地址表、提前编译对象页表;
其中所述文件头包括源程序数量、公用对象数量和编译数据占用的存储空间信息。
在本申请提前编译装置的一实施例中,所述加载模块604包括:
映射子模块,用于将所述文件头映射至系统的系统存储空间;
目标信息获取子模块,用于获取提前编译文件中与所述文件头中的源程序数量、公用对象数量、编译数据占用的存储空间信息对应的目标信息,并将该目标信息映射至系统存储空间;以及
加载子模块,用于将映射至所述系统存储空间的目标信息加载到所述内存管理单元。
在本申请提前编译装置的一实施例中,所述加载模块604还包括:
禁止子模块,用于禁止内存管理单元的内存分配申请。
在本申请提前编译装置的一实施例中,所述加载模块604还包括:
对比子模块,用于对比动态编程语言系统的系统符号表与提前编译文件的符号表;
替换子模块,用于当所述系统符号表与所述提前编译文件的符号表存在相同符号时,将相同符号在系统符号表中的地址替换为所述提前编译文件的符号表中的地址。
在本申请提前编译装置的一实施例中,所述装置还包括:
初始化模块605,用于初始化系统;以及
程序运行模块606,用于运行所述源程序。
在本申请提前编译装置的一实施例中,所述程序运行模块606包括:
检索数据结构建立子模块,用于根据所述提前编译文件建立检索数据结构,所述检索数据结构包括动态语言程序名称和对应的字节码地址;
名称查找子模块,用于在该检索数据结构中查找是否存在目标动态语言程序名称;
字节码地址获取子模块,用于当该检索数据结构中存在该目标动态语言程序名称时,获取该目标动态语言程序名称对应的字节码地址;
字节码加载子模块,用于根据该字节码地址加载字节码。
在本申请提前编译装置的一实施例中,所述编译数据链接模块602包括:
对象获取子模块,用于获取编译数据中的根节点对象;
对象确定子模块,用于确定根节点对象对应的子节点对象;
对象移动子模块,用于将所述根节点对象和所述子节点对象移动至所述存储空间中;
链接子模块,用于将所述存储空间链接到所述内存管理单元。
在本申请提前编译装置的一实施例中,所述存储空间包括存储页,所述存储页的格式与所述动态编程语言系统的系统存储空间的格式匹配。
在本申请提前编译装置的一实施例中,所述编译数据链接模块602还包括:
记录子模块,用于记录所述根节点对象和所述子节点对象移动前的存储地址和移动后的存储地址;以及
引用关系更新子模块,用于根据移动前的存储地址和移动后的存储地址更新所述存储空间内的对象引用关系。
在本申请提前编译装置的一实施例中,所述记录模块包括:
标识子模块,用于标识根节点对象对应的子节点对象;
移动子模块,用于将标识后的子节点对象移动到所述存储空间的连续地址内。
在本申请提前编译装置的一实施例中,所述记录模块还包括:
回收子模块,用于回收未标识的存储空间。
综上所述,本实施例提出的系统的提前编译装置至少具有如下优点:
本申请实施例提供的系统的提前编译装置,利用动态类型语言系统自身提供的机制,实现了一种适用于动态类型语言系统的提前编译方法。与现有的动态类型语言提前编译方法相比,本申请将提前编译文件加载到内存管理单元后,就可以直接运行,在程序运行时不需要再执行读入源代码文件、解释、生成字节码等动作;也不需要读入字节码、译码、反序列化、重构对象。本申请提供的方法具有系统开销小,程序响应速度快等优点。
除此之外,本实施例提出的系统的提前编译装置至少还包括如下优点:
此外,本申请采用定制的垃圾回收机制为了精简提前编译文件,提高程序加载速度,利用现有的移动GC算法,实现了定制的提前编译垃圾回收算法。以当前程序生成的字节码,符号表和常量池为根节点对象开始遍历内存管理单元,将无关对象回收到自动存储管理系统。然后将提前编译相关对象移动到堆的连续地址空间,随后将这一连续地址空间的内容写入文件(我们称之为提前编译文件)。确保提前编译文件中的对象没有冗余。
再者,在本申请提出的方案中,为了顺利将提前编译文件映射到系统并链接到堆中,本申请优选实施例中对指定格式进行了定制,例如指定格式中的项目包括文件头、程序字节码地址列表、公用对象地址列表、提前编译对象页面地址列表和提前编译对象页列表;文件头例如包括魔术数字、版本号、源程序数量、公用对象数量、所有提前编译对象占用页面数、校验和等。采用上述的格式,利用提前编译文件可以直接恢复程序的字节码、符号表和常量池,将所有相关的对象链接到堆中,完全省去了反序列化的过程,耗时最少,内存占用最低,程序访问局部性好,可以应用在系统程序和应用程序中。
对于装置实施例而言,由于其与方法实施例基本相似,所以描述得比较简单,相关之处参见方法实施例的部分说明即可。
本说明书中的各个实施例均采用递进的方式描述,每个实施例重点说明的都是与其他实施例的不同之处,各个实施例之间相同相似的部分互相参见即可。
尽管已描述了本申请实施例的优选实施例,但本领域内的技术人员一旦得知了基本创造性概念,则可对这些实施例做出另外的变更和修改。所以,所附权利要求意欲解释为包括优选实施例以及落入本申请实施例范围的所有变更和修改。
最后,还需要说明的是,在本文中,诸如第一和第二等之类的关系术语仅仅用来将一个实体或者操作与另一个实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存在任何这种实际的关系或者顺序。而且,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者终端设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者终端设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、物品或者终端设备中还存在另外的相同要素。
以上对本申请所提供的一种系统的提前编译方法和装置,进行了详细介绍,本文中应用了具体个例对本申请的原理及实施方式进行了阐述,以上实施例的说明只是用于帮助理解本申请的方法及其核心思想;同时,对于本领域的一般技术人员,依据本申请的思想,在具体实施方式及应用范围上均会有改变之处,综上所述,本说明书内容不应理解为对本申请的限制。