软件原子化的制作方法

文档序号:6412136阅读:586来源:国知局
专利名称:软件原子化的制作方法
技术领域
计算机软件通常被创建为直译语言系统或编译语言系统。直译语言系统将高级程序语句翻译成可执行的形式,并一次执行一条语句而不是在执行之前全部翻译完(即,编译)这些高级语句。Basic、LISP和APL通常作为直译语言来实现。编译语言系统在执行之前将高级程序语句翻译成中间目标代码格式。在编译语言系统中,程序语句以源代码程序语言(例如,C、C++)来编写。源代码包含有以不能被计算机直接执行的高级或编译语言编写的人可以读的程序语句。源代码由编译器处理,编译器通过遵循一组句法和语义规则将源代码转换成目标代码(例如,OBJ文件)。然后目标代码被使用链接程序链接在一起产生可执行计算机程序(例如,.EXE文件)。
计算机可执行程序当存储在盘以及装入计算机内存时可能很大。动态链接库(DLL)提供了一种机制来存储从主可执行计算机程序中分离出的可执行例程和数据。只有当可执行计算机程序需要时,可执行例程才被装入。DLL通过只有当用到例程或数据时才使用内存来节约空间。DLL还组织和管理与可执行计算机程序分离和与其它DLL分离的计算机代码和数据。这就允许程序设计员在DLL中可以只对某些例程进行改正和改善而不会影响调用计算机程序或任何其它DLL的操作。此外,DLL可以在多个计算机程序之间共享。DLL自身可能是相当大的,并且多个可执行例程通常被组织成为在DLL内的单个模块,使得DLL在下载、更新和加载方面并不是很颗粒化。
存在最小化与更新较大DLL或其它代码/数据相关的传输时间的技术。使用差别检测算法(例如,rsync)的文件传输协议可以降低传输的时间。这些算法可以将源和目标文件配置成数据块,分析这些块,并只传输在源和目标文件之间不同的块。
还可以使用压缩来降低在通信介质上以及从盘到内存的代码和数据的传输时间。对可执行代码大小尤其敏感的嵌入式处理器系统已经实现了对可执行代码实施压缩。可以使用代码的压缩“线”表示,但是这些代码必须在执行之前被解压缩。其它技术提供了直接执行压缩代码(例如,“字节代码RISC”或“BRISC”虚拟机)。
CurlTM语言在一个集成的环境中组合了布局、脚本和程序设计的能力。通过客户端的执行来搭配这些全部特征化的语言,CurlTM技术可以在Web上传送快速、有效、高功能的应用程序,并能够进行客户和服务器交互操作的交互Web业务能力。CurlTM内容使用增加了CurlTM插件和CurlTM运行时间环境的Web浏览器来显示。CurlTM运行时间环境在许多根据大约相等数量的代码和数据编译的运行时间环境中是非典型的。CurlTM运行时间环境是使用大量DLL来实现的。

发明内容
使用传统技术(例如,EXE和DLL)来实现计算机系统呈现出很多问题。这些计算机系统显示了较长的起动时间,使用太多内存,且由于它们使用了大颗粒化的可执行例程和数据而导致更新很麻烦。因此,本发明提供一种使用软件原子化建立和执行软件原子从而组织和管理可执行计算机软件的精细颗粒化方法。
原子是由原子id(识别符)唯一标识的代码片断或数据单元。代码原子典型地处于源语言(例如,C/C++)程序的级别上。数据原子是数据单元,并可以有任意大小。当需要时,原子被拖入内存,并且当不再需要时可以被换出。
本发明提供了一种通过从原子数据库将原子装入内存从而按需装入原子化计算机程序代码和数据的方法,所述原子以精确颗粒、分别可寻址的方式定义代码或数据。原子包括原子识别符、计算机程序代码或数据信息和计算机程序代码或数据参考信息(referenceinformation)。该计算机程序代码或数据信息的载入是通过将每个参考变换成合适的地址,并按合适的偏移将该地址插入原子的本体来完成的。
代码的延迟(lazy),或按需加载载入是通过将基于参考的原子识别符转换成分支例程的内存地址来提供的。分支例程装入被参考原子并跳转到其上。原子加载类型可以通过修改计算机程序代码或数据参考信息以影响渴望(eager)或延迟加载技术来改变。原子加载类型可以基于分析前一原子加载经历的运行时间来确定。当加载时,原子可以经由只读缓冲器在多个可执行处理之间共享。
“回补(back-patching)”技术可以应用于通过分支来参考目标原子的所有原子。原子参考(atom reference)是由在执行调用的调用例程内的源偏移、被调用原子的目的地原子id和被调用原子之内的目的地偏移来定义的。一旦分支例程加载其目标原子,该分支例程的内存地址就由被参考原子的内存地址重写。
数据的延迟,或按需加载的载入通过提供代码的延迟加载来隐含地提供,以及通过编码参考原子识别符以便被参考数据原子直到在运行时间被实际访问才被加载来明确地提供。由于参考数据的代码的加载可以延迟到被调用为止,所以,代码所参考的数据同样被延迟一隐含地提供数据的迟缓加载。明确松散数据(lazy data)典型地需要程序设计员支持以便标记数据被延迟加载(例如,使用编译器命令)。在一个实施例中,明确松散数据使用特定编码算法来参考,该算法将参考原子识别符乘以2并将参考原子识别符加1来产生松散数据原子识别符。
在本发明的另一个实施例中,由原子管理程序来提供优化。可以基于对在前原子加载经历的运行时间模式的分析来重新排序基于盘的原子数据库中的原子以便有效访问。计算机程序代码或数据信息可按压缩格式存储。压缩可以减少原子的加载时间和减少存储原子所需的盘空间。可以通过碎片收集来节约内存,从而基于预定使用门限将加载原子从内存移除。加载原子的执行可以在加载由该加载原子参考的所有原子以便提供流执行(streaming execution)环境之前开始。
可以通过代替计算机程序代码或数据信息以及计算机程序代码或数据参考信息来更新原子数据库中的某些原子。
代码和数据原子可以使用析取器从程序设计语言对象(例如,.obj文件)来建立。原子也可以使用产生能够由原子管理程序处理的原子的任何其它处理来建立。在本发明的一个实施例中,原子化计算机程序代码和数据的方法包括接收按照用于定义单独可寻址代码和数据的目标代码格式的计算机程序代码和数据,并从以目标代码格式存储的计算机程序代码和数据中提取计算机代码和数据信息。计算机程序代码和数据参考信息也从按目标代码格式存储的计算机程序代码和数据中提取。计算机程序代码和数据参考信息被修改来使用原子识别符,并被存储在一个原子中,该原子包括原子识别符、计算机程序代码或数据信息、计算机程序代码或数据参考信息。
在本发明的一个实施例中,定义了一种用来存储由在数据处理系统上执行的计算机程序访问的数据的存储器,该存储器可以存储由数据结构定义的原子。该数据结构包括头部和原子映象(atom map)。所述原子映象包括原子映象头部和原子映象阵列。该原子映象阵列包括原子偏移序列,该参考原子的原子偏移序列包括原子识别符,计算机程序代码和/或数据信息;计算机程序代码和/或数据参考信息。原子映象还可提供从原子识别符到符号名的映射。
本发明实施例提供了更快的计算机程序启动时间,更小的可执行代码(例如,插件程序、运行时间)下载,更小的盘占用空间,更小的内存占用空间,以及当代码和数据被在原子化(可寻址)单元级别上处理时更小的更新文件。这种原子的精细颗粒化方法提供用于确切加载所需代码和数据,并且不用仅仅因为其位于可执行文件的附近而加载其它代码和数据。原子化用于基于原子所建立的精细颗粒化、单独可寻址的单元优化对代码和数据的随机访问。由于代码和数据被原子化成精细颗粒化、单独可寻址的单元,因此它们变得更小,并且从而在需要更新时更易于以后修补。


通过下面对本发明优选实施例的更具体描述,本发明的上述和其它目的、特点和优点将显而易见,如在附图中说明的那样,其中,在所有不同视图中,相同的参考字符指代相同的部件。附图不必按比例,而应强调说明本发明的原理。
图1是在其上实施本发明一个实施例的计算机系统的图。
图2是图1计算机系统中的计算机的内部结构图。
图3说明了在运行时间建立和加载计算机程序来显示输出的传统过程。
图4说明了在运行时间建立和加载原子化计算机程序来显示输出的软件原子化过程。
图5说明了原子提取过程。
图6是原子数据库和原子的图。
图7是原子管理程序的图。
图8说明了原子管理过程。
图9是原子数据库数据结构图。
图10是原子映射头部数据结构图。
图11是原子映射阵列数据结构图。
图12是原子偏移序列数据结构图。
图13是编码原子数据结构图。
图14是编码原子参考数据结构图。
图15是四个编码程序和三个数据单元的示例系统图。
图16a是示例数据原子的图。
图16b是示例代码原子的图。
具体实施例方式
下面描述本发明的优选实施例。该优选实施例适于原子化实现CurlTM运行时间环境的计算机程序,该环境执行原子化的CurlTM运行时间的适当部分来处理以CurlTM语言、脚本或非Curl程序编写的软件。
图1是在其上实施本发明实施例的计算机系统的图。客户计算机50和服务器计算机60提供处理、存储、和输入/输出设备用于原子化和执行原子化计算机程序。客户计算机50还通过通信网络70连接到包括其它客户计算机50和服务器计算机60的其它计算设备。通信网络70可以是因特网的一部分,因特网是当前使用TCP/IP协议组进行相互通信的计算机、网络和网关的世界性集合。因特网提供了在主节点或主计算机之间高速数据通信链路的主干,其包括路由数据和消息的成千上万的商业、政府、教育和其它计算机网络。在本发明的另一个实施例中,用来原子化和执行原子化计算机程序的处理、存储、和输入/输出设备可以在独立计算机上实现。
图2是图1计算机系统中的计算机(例如,50、60)的内部结构图。每个计算机包括系统总线200,这里总线是一组用来在计算机元件之间传输数据的硬件连线。总线200实质上是连接能够在各单元之间传输信息的计算机系统(例如,处理器、硬盘存储器、内存、输入/输出端口、网络端口等)的不同单元的共享管道。连接于系统总线200的是用来将各种输入输出设备(例如,显示器、打印机、扬声器等)连接于计算机的I/O设备接口202。网络接口206允许计算机连接到附着于网络(例如,网络70)的各种其它设备上。内存208是用于用来实施本发明一个实施例的计算机软件指令(例如,原子析取器150和原子管理程序160)和数据结构(例如,原子数据库120)的易失性存储器。盘存储器210是用于用来实施本发明一个实施例的计算机软件指令(例如,原子析取器150和原子管理程序160)和数据结构(例如,原子数据库120)的非易失性存储器。
中央处理单元204也连接于系统总线700并用于执行计算机指令(例如,原子析取器150和原子管理程序160),从而允许计算机原子化并执行原子化计算机程序。
图3说明了在运行时间建立和加载计算机程序以显示输出的传统过程。源代码102是由计算机程序设计员使用源代码程序设计语言(例如,C、C++)编制的。编译器104处理该源代码并产生目标代码106文件。一个或多个目标代码106文件被使用链接程序108链接来产生链接程序部分109。链接程序部分109被组合来产生可执行代码110。可执行代码110可作为独立的可执行程序(例如,EXE文件)或作为代码共享库(例如,DLL文件)被链接。可执行代码110被加载程序112载入内存来执行,以便产生运行时间显示114。
图4说明了在用于运行时间建立和加载原子化计算机程序来显示输出的软件原子化过程。与使用传统处理一样,源代码102由计算机程序设计员使用源代码程序设计语言(例如,C,C++)编制。编译器104处理该源代码并产生目标代码106文件。在源代码102被以通常方式汇编成目标代码106文件之后,原子析取器150处理该目标代码106文件来识别原子130。精细颗粒化、单独可寻址原子130被放入原子数据库120,其中每个原子130接收一个唯一原子id 132。精细颗粒化原子130定义了任意整数个字节的代码和数据。对于代码和数据的参考被转换成原子id参考。例如,在代码内的程序调用通过它们的原子id 132被转换成其它原子130的调用。数据参考也通过它们的原子id 132被转换成数据原子参考。
原子析取器150利用目标代码文件106并从该代码产生原子130。根据传统加载程序需要相同信息来加载和调用程序以及优化只读数据的事实,从目标代码106提取原子130所需的信息已被嵌入到目标文件中。从目标代码文件106中提取多个数据原子所需的信息需要各种数据量的分离。这种分离可以由某些传统编译器(例如,gcc)自动进行,或由程序设计员在源代码(例如编译器指示)中直接标记数据数量来明确地进行。在运行时间,原子管理程序160从原子数据库120中访问原子130并将它们加载到内存中来执行。所加载原子130然后产生运行时间显示114,或它们被编程为当被执行时产生的任何其它结果。原子管理程序160可以基于静态代码分析或动态剖析(dynamicprofiling)来确定加载原子130的最佳顺序。通过依靠编译器在目标代码文件106中建立分离部分,可以自动进行原子化过程,这避免了需要手动分解和分析。编译器的使用提供了建立代码和数据分离部分的一种选择,可选地,可以使用其它程序处理源文件来产生原子130。
图5说明了原子提取过程。在步骤302,以目标代码格式接收计算机程序代码和/或数据。在步骤304,以目标代码格式从计算机程序代码和/或数据中提取计算机程序代码和/或数据信息。在步骤306,以目标代码格式从计算机程序代码和/或数据中提取计算机程序代码和/或数据参考信息。在步骤308,修改计算机程序代码和/或数据参考信息以使用原子识别符。最后,在步骤310,计算机程序代码和/或数据信息和计算机程序代码和/或数据参考信息被存储于原子中,所述原子包括原子识别符;计算机程序代码和/或数据信息;计算机程序代码和/或数据参考信息。
图6是原子数据库和原子的图。从概念上讲,原子数据库120可以被视为原子130的有向图。原子字节134(节点)由原子id 132(节点id)标识并由原子参考136(边缘)链接。原子数据库120存储原子130。每个原子130由一个唯一原子id 132标识。每个原子130的代码和/或数据被表示为原子字节134。原子130可以被压缩,包括原子字节134内的代码和/或数据以及原子参考136。在某些环境中,解压缩比读盘的时间快,并且压缩和解压缩处理提供了明显的性能改善以及减少的内存和盘存储器空间。
图7是原子管理程序的图。在运行时间,本发明的一个实施例回避传统的用于加载共享库(即,DLL)的机制,而是使用更有效的原子机制,其以原子130的颗粒度而不是例如内存的4K块来加载。原子管理程序160根据需要从原子数据库120中加载原子130。原子管理程序160分配主内存并接着在缓冲器内管理原子130。原子析取器150预先已修改程序调用以便间接地通过用于原子管理程序160的原子130,其将现有原子130放在内存中,或者如果它们还没被加载,就从原子数据库120中加载它们。
缓冲器管理提供了多种好处,包括有界限的内存使用、降低的主机交换和系统颠簸以及降低的启动时间。有界限的内存使用将内存使用限制到任意具体大小。例如,可以为代码原子130选择精确的8MB内存,并且当需要一个更新的原子时,将旧原子130交换出来。本发明的实施例通过限制内存的使用来降低主机交换和系统颠簸,因此,主机不需要使用其内存管理机制来管理内存的过渡使用。由于主机内存管理是通用目的并且不必使其与具体需要一致,从而主机内存管理的效率固有地较低。通过精确地加载所需的代码,并且不必加载仅仅因为其处于共享库“附近”的其它代码,降低了内存消耗。原子管理程序160降低了启动时间。原子管理程序160将加载并执行第一原子130。当需要新原子130时,它们被加载并执行。因此,代码立刻执行,而无需等待整个代码组被载入内存。本发明的实施例在下载完成之前开始执行正在被下载的代码原子130(受还未发送的原子130可用性的限制)。
原子管理程序160管理三个缓存器只读代码缓存器170、只读数据缓存器180(例如,常量)和读写数据缓存器190(例如,全局数据)。由于读写数据可以是任意大小,并且不能从原子数据库120重新加载,其大小不被限制,因此,可以使用主机的虚拟内存系统来对其管理。
将原子130一次一个地装入缓存器比如果可以确定它们是相关的(例如,它们都“很快”将被需要)则同时装入原子130的一个工作组效率更低。工作组协调器(tuner)被用来确定哪些原子130形成“工作组”。该工作组协调器适用于收集用于原子化环境的信息。一旦收集到该信息,则使用一种机制来利用这些信息,例如原子数据库120内的表示原子130相互关系的指示。本发明的实施例提供了在盘上重新排序原子130来匹配具体加载序列的能力,从而提供更快的加载。
通过原子管理程序对只读代码缓存器170的管理提供了一定的加载优化。当一个原子130向另一个原子130作出一个程序调用时,通常使用分支经由原子管理程序160来作出调用。当调用程序代码在内存中的映象被修改以直接跳到(链接急变(link snapping))目标原子130时,程序调用更快。然而,一旦链接被急变,原子管理程序160不使得该链接无效就不能移动或交换出目标原子130。对于频繁被调用的原子130,这可以是一个很值得的折中。原子管理程序160利用工具来确定哪些原子130有资格被直接调用,并将原子130锁定到内存中。对链接急变的分析可以在运行时间通过将代码/数据锁入内存中来作出,或者在编译时通过标记某些原子参考136以便在运行时间不使用分支来作出。
多种程序可以访问相同的原子数据库120以共享代码和/或数据。如果主处理器在主处理之间支持共享内存,那么只读代码缓存器170和只读数据缓存器180也可以在主处理之间共享。
图8说明了原子管理过程。在步骤322,原子管理处理通过从原子数据库中载入原子到内存中来管理原子化的计算机程序代码和/或数据,所述原子包括原子识别符;计算机程序代码和/或数据信息;和计算机程序代码和/或数据参考信息。在步骤324,计算机程序代码和/或数据参考信息接着被从使用原子识别符和偏移修改为使用内存地址。
图9是原子数据库结构图。原子数据库120存储原子130。原子130相应于单个数据,例如,一个编译的程序或串常数。原子130当需要时被从原子数据库120载入到内存。这就降低了内存的占用空间并减少盘I/O。原子数据库120是从原子id 132值(整数)到原子130的一个映射。原子id 132可以表示为标识原子130的31-比特整数。原子130可以按任何顺序加载。优化原子数据库120在盘上的表示以节约空间并减少将原子130载入内存所需的I/O。原子数据库120还提供从原子id 132值到与相关原子130相关的信息的映射,例如,符号和调试信息。原子数据库120是一个由多个不同的部分构成的文件,每个部分具有可变的大小,这些部分包括DB-头部350和原子映象360。在不同的实施例中,原子映象360可以是主体原子映象、符号原子映象、范畴原子映象和/或描述原子映象。DB-头部350必须首先出现,但是其它映象部分的顺序、位置和数量是任意的。DB-头部350包含用于每个其它部分的文件偏移。每个部分,如果存在,必须确切地出现一次。
DB-头部350在数据库文件中正好处于第一位。它包含有关该文件和其它部分位置的某些全局信息,包括幻数(magic-number)、版本号、cpu类型、os类型、主体原子映象偏移、符号原子映象偏移、范畴原子映象偏移和描述原子映象偏移。
幻数将该文件识别为原子数据库120,并且还定义在该文件中的所有其它多字节数的终止端(endianness)。如果数据库被按小尾序(little endian)字节顺序0xD7 0x150xFF 0x31存储,那么幻数就包括这些四字节。对于一个大尾序(big endian)文件来说,字节被反转0x31 0xFF 0x15 0xD7。该字节序列没有特定的意义。数据库文件将总是被存储在包含其代码的处理器的本地终止端(字节顺序)。这就避免了在运行时间对浪费的字节交换的需要。然而,幻数清楚地规定了终止端以便交叉平台工具可以操作原子数据库120。
版本号表示数据库所使用文件格式的版本。
CPU类型表示产生该数据库的CPU的类型(例如,Pentium、PowerPC,等)。
OS类型是产生该数据库的操作系统的类型(例如,Win32、Linux、MacOS X,等)。
主体原子映象偏移是相对于该文件的开始,主体原子映象部分开始处的文件偏移。
符号原子映象偏移是相对于文件的开始,符号原子映象部分开始处的文件偏移。
范畴原子映象偏移是相对于文件的开始,范畴原子映象部分开始处的文件偏移。
描述原子映象偏移是相对于文件的开始,描述原子映象部分开始处的文件偏移。
图10是原子映象头部数据的结构图。原子映象360包含原子映象头部370和原子映象阵列380。原子映象360将原子id 132映射到可以发现与该原子id 132相关的某些信息处的文件偏移。原子映象360表示将为任意原子id 132组工作,但其为原子id 132的毗邻范围被最优化,因此,例如,原子id 132{12,23,24,216}的原子映象360将比原子id 132{10,11,12,13}的原子映象占用更多空间。原子映象360部分开始于包括缺省原子序列增量(delta)372、原子偏移序列阵列大小374、原子偏移序列阵列偏移376和原子映象数据偏移378的原子映象头部370。
缺省原子序列增量372字段可以被用在原子映象360中,该映象包含用于相应于连续原子id 132的数据的文件偏移的序列。这些序列在原子映象360中被“增量编码”以节省空间。增量编码(delt coding)是将连续对之间的差别存储作为序列数的技术。对于很多序列来说,增量很小,并且由于许多编码方案可以更紧凑地存储零附近的数字,所以增量序列通常占用比源序列更小的空间。例如,增量编码版本{1000,1011,1012,1013,1015,1016}将看起来象{1000,1,1,1,2,1}。增量通常是小的正数,但是它们可以通过从每一个中减去一个良好选择的常数,即,缺省原子序列增量372,而变得甚至更接近于零。例如,假设源数字序列是{1000,1050,1104,1165,1202}。增量编码该序列产生{1000,50,54,61,37}。由于缺省原子序列增量372等于50,该序列将被进一步调整为{1000,0,4,11,-13}。由于最终数字更靠近零,所以该序列可以被更紧凑地编码。还可以使用霍夫曼(Huffman)编码或算术编码方案。
原子偏移序列阵列大小374是在原子映象360阵列序列中的条目的数量。
原子偏移序列阵列偏移376是相对于在数据库文件中的原子映象360部分的开始,原子映象360阵列序列的文件偏移。
原子映象数据偏移378是相对于在原子数据库120文件中的原子映象360部分的开始,在原子映象360数据开始处的文件偏移。
原子映象360(例如,主体原子映象,符号原子映象,范畴原子映象和描述原子映象)包含原子映象阵列380。每个原子映象阵列380单元是对文件偏移的压缩序列(即,原子偏移序列390)的参考。每个原子偏移序列390包含用于属于一组连续原子id 132的信息的压缩的文件偏移。
图11是原子映象阵列数据结构图。原子映象阵列380包括下列单元第一id 382,序列大小384和序列偏移386。第一id 382是序列中的第一原子130的原子id 132。序列大小384是在原子偏移序列390中的原子130的数量。在序列中的原子130具有开始于第一id 382的连续原子id 132。序列偏移386是相对于原子数据库120的原子映象360部分的开始,至原子偏移序列390的开始的文件偏移。原子映象阵列380通过在每个序列中的第一原子130的原子id 132被排序。这就可以通过进行对分查找来将原子id 132映射到其包含序列。扫描该包含序列将产生所需原子130的文件偏移。
图12是原子偏移序列数据结构图。原子偏移序列390是文件偏移的增量编码阵列,其包括第一原子文件偏移392和增量编码文件偏移394阵列。每个文件偏移被加到原子映象数据偏移378,并相对于原子映象360部分的开始解释该结果。由于缓冲了每一序列的固定开销,所以一个长序列比两个包含相同数量文件偏移的较小序列占用的空间少。然而,较长的序列需要更长的时间来搜索。因此,原子映象360典型地被分成更多序列而不必严格按照必需,来对其长度以及搜索时间进行合理的限制。然而,对于序列大小并没有固定限制。
第一原子文件偏移392是在序列中的第一原子130的文件偏移。序列的剩余部分是一串开始于该值的增量。
增量编码文件偏移阵列394是编码文件偏移序列的字节块,在文件偏移处可以发现属于连续原子id 132的数据。
为了编码一个序列,编码器从文件偏移序列开始。这些表示字节偏移被添加到原子映象数据偏移378。例如,假设源文件偏移序列是{1000,1050,1104,1165,1645,760}。注意,在文件中,原子130并不一定是按照顺序的。首先,该序列被增量编码为{1000,50,54,61,480,-885}。如果缺省原子序列增量372等于50,那么该序列将进一步被调整为{1000,0,4,11,430,-935}。最后,该序列中的每个数字(在第一个之后,其被存储在第一原子文件偏移392中)被编码为大小可变的整数。编码产生字节序列{0x00 0x04 0x0B 0x83 0x2E 0xF8 0x59}。某些整数使用对较小值占用较少字节的可变大小编码方案来存储。带符号整数被编码为7比特值的序列。不管数据库的整体终止端如何,这些值被按大尾序字节顺序(最高有效字节为先)存储。每个字节的高位比特是表示后面是否还有字节的特定标志。第一字节的第七个比特(数字数据的最高有效位)是符号扩展。无符号整数被编码为7比特值的序列。不管数据库的整体终止端如何,这些值被按大尾序字节顺序(最高有效字节为先)存储。每个比特的高位比特是表示后面是否还有字节的特定标志。所产生的值被零扩展。
原子映象360被用来使特定类型的信息与原子id 132相关。例如,原子映象360可以被用作代码/数据主体信息、符号信息、范畴信息和描述信息。
主体原子映象将每个原子id132映射到加载该原子id 132所需的信息块,该信息块包括对于普通原子,包括有关可以被组合来形成最终普通原子主体的原子字节134和原子参考136的压缩信息,对于特殊用途的原子,包括适合于特殊用途原子的每个子字节的信息。
所述块的第一字节被用来编码一组原子标志396。如果原子标志396的低三位的值不包含特殊用途识别符(例如,表示值“7”的三位比特),那么原子130是普通原子,否则,是特殊用途原子。为了加快加载普通原子主体,原子130的原子参考136和原子字节134在原子数据库120文件中被连续存储。为了使原子数据库120的大小较小,从而提高其被加载的速度,普通原子主体的原子参考136和原子字节134被以多种方式压缩。
图13是编码原子数据结构的图。用于普通原子的信息块包括原子标志396、原子数量信息397、编码原子参考398、和编码原始原子(raw atom)字节399。
原子标志396使用标志字节的不同比特来规定原子的压缩类型。本发明的实施例支持多种压缩类型。原子标志396的其它比特规定了原子应该被载入哪种缓存器(即,只读代码缓存器、只读数据缓存器、读写数据缓存器)。其它比特还定义了原子130加载时所需调整的对数底数(log base)2(例如,存储在这些比特中的值“3”将使得原子130在加载时使该原子130调整模8个字节)。
原子数量信息397是包含有关有多少参考将出现在编码原子参考398块和有多少原始字节(raw byte)将从编码原始字节399块中提取出的信息的字节块。该条目将确定将要提取的参考数量和原始字节数量。概念原子字节134和原子参考136被分别编码为编码原子参考398和编码原子原始字节399。
图14是编码原子参考数据结构图。每个编码原子参考398是描述从该原子130到其它原子130的参考的字节块。例如,如果原子130表示调用由另一个原子130表示的另一个程序的程序,那么后一原子130将在编码原子参考398中描述。该编码原子参考398阵列被原子管理程序160用来在加载原子130时将它们链接在一起。
原子数量信息397是由编码原子参考398编码的原子参考的数量。
每个编码原子参考398包含原子参考类型402、源偏移增量404、目的地(dest)偏移406和目的地原子-id 408。
原子参考类型402定义了从原子130到其它原子130的参考的不同类型。并非所有类型都被所有平台使用。有效的原子参考类型402包括渴望绝对(eager-absolute)-32、渴望相对-32、延迟绝对(lazy-absolute)代码-32、延迟相对代码-32和延迟绝对-32。
渴望绝对-32使原子管理程序160立即加载参考原子130并存储至它的一个绝对地址。
渴望相对-32与渴望绝对-32相似,但渴望相对-32存储一个至参考原子130的相对偏移。相对偏移是从参考的开始测量的。
延迟绝对代码-32定义了一个至包含代码的原子130的绝对地址(例如,32比特)。它是“延迟”的,因为直到参考原子130被第一次调用它才被实际载入。原子管理程序160通过建立指向代码分支的参考来管理延迟的加载,该代码分支在第一次调用参考原子130时延迟加载它。
延迟相对代码-32与延迟绝对代码-32相似,但是延迟相对代码-32存储至参考的相对偏移。该相对偏移是从参考的开始测得的。
延迟,或按需加载,通过提供代码的延迟加载来隐含地加载数据,以及通过编码参考原子识别符来明确地加载数据,以便参考数据原子直到在运行时间被实际访问时才被加载。由于参考数据的代码的加载可以被延迟直到被调用,所以代码所参考的数据同样被延迟-隐含地提供数据的延迟加载。明确的松散数据典型地需要程序设计员支持以便标记该数据将被延迟加载(例如,使用编译器命令)。在一个实施例中,明确的松散数据使用特定的编码算法来参考,该编码算法将参考原子识别符乘以2和将参考原子识别符增加1来产生松散数据原子识别符。
延迟绝对-32定义了至另一个原子130的绝对(例如,32-比特)地址。其是“延迟”的,因为参考原子130不能够实际确切地被加载。相反,原子管理程序160通过存储编码地址(2*参考原子id)+1来链接该参考。注意,该编码地址总是奇数。与可以使用跳转分支的延迟代码参考不同,松散数据参考需要与原子管理程序160正运行的程序合作。它必须检查奇数指针值并识别它们是否为松散数据参考。接着需要通过调回到原子管理程序160来加载所需的原子130,并典型地用最终地址重写该参考。自然延迟加载的数据必须已知具有偶调整(even alignment),否则这种指针的奇数值将是模糊的。
源偏移增量404规定了在出现参考的原子130中有多少字节。该值被表示为从前一参考的末端的增量。第一参考被编码为好像在源偏移0结束处存在前一参考。参考总是通过按它们的源偏移排序来存储,因此,在该阵列中的增量总是非负的。例如,如果原子130在字节偏移0,4,8,12,20处具有四字节参考,那么用于那些参考的源偏移增量字段将被编码为0,0,0,0,4。
目的地偏移406将多个字节的偏移编码成该参考所指向的参考(目的地)原子130。
目的地原子-id 408是该参考所指向的原子130的原子id 132。
编码原始原子字节399是表示用于原子130的原子字节134的字节块,其中需要用来容纳对其它原子130的任何参考的空间被“清空(spliced out)”,并且其中剩余原始字节被按原子压缩类型规定的方式压缩。由于编码参考信息包含源偏移(识别进行参考的位置)、目的地id(识别目标原子)和目的地偏移(识别在该参考所指向的目标原子中有多少字节),所以原子字节内的参考可被移除来建立原始字节。例如,如果原子字节134表示C串常数,该阵列可以具有字符串序列,可能是压缩的。如果相反,原子字节134由四个数据字节构成,其后是对另一个原子130的四字节参考,其后是八个另外的数据字节,那么编码原始原子字节399将只包含这十二字节的数据,可以是压缩的。四字节参考将在加载期间被“接合(spliced in)”入位,这使得完全加载的原子字节134占有16字节。
特殊用途原子由包含特殊用途识别符的原子标志396定义(例如,其低三位设置为值“7”)。原子标志396的剩余比特规定了特殊用途原子是dll参考原子还是dll原子。
Dll参考原子包括三个字段原子标志、dll原子id和dll符号。Dll参考原子相应于外部DLL(例如printf()库函数的原子130)的符号。这些原子130表示为DLL和在该DLL中查找的符号的一对。Dll原子id规定了dll原子的id,其规定了在其中查找dll符号的DLL。Dll符号规定了哪个符号在DLL中查找。
Dll原子包括原子标志字段和dll路径名字段。Dll原子与dll参考原子相关并用来规定dll参考原子将在其中查找符号的DLL。Dll路径名规定了适合传递到dlopen、LoadLibrary或等同函数的路径名。其被作为C串存储(以0结束的字节序列)。
符号原子映象将原子id 132映射到文本符号,通过此,相关原子130可以通过名字来访问。符号对于以用户友好的方式参考原子130是有用的。例如,当利用原子识别符值57参考原子130时,对于程序设计人员来说通过名字(例如“printf”)参考原子130,比通过其原子识别符值(例如,“57”)参考该原子更容易。
范畴原子映象是从原子id 132到没有固定语义的文本范畴的原子映象360。描述原子映象考虑到了开发者的特定原子种类。在另一个例子中,范畴可以用来标记原子130以识别字符串原子130,识别用于国际化和许多其它目的的原子130。
描述原子映象是从原子id 132到没有固定语义的文本描述的原子映象360。当开发/调试基于原子的系统时,描述原子映象被用来存储对于开发者有用的调试信息。
原子参考的参考类型可以基于对参考的利用做出概要来静态或动态地改变。原子参考136一般缺省为“延迟”以便延迟加载实际原子字节134直到它在运行时间实际被需要。“渴望”参考使得当调用原子130被加载时加载被参考的数据代码,而无论其是否实际被需要。通常在运行时间于给定的原子130之内执行的运行时间代码路径将不执行原子130内的所有指令。加载不被调用或不被参考的原子130是对内存和处理资源的浪费。
对用于代码的延迟参考的分解包括指向当参考原子130第一次被调用时延迟加载参考原子130的代码分支。对用于数据的延迟参考的分解包括将参考原子id存储为由(2*参考原子id)+1定义的修改的原子id。
一旦延迟代码参考被执行/访问,可以进行优化以避免间接使用代码分支。该优化包括“回补”参考代码以直接参考所加载的原子130。回补利用在内存中直接跳转到代码原子130来代替使用分支。回补可以为第一个实际调用程序执行并且也可以应用于任何加载原子130,以便如果并且当参考原子130被实际调用时,可以直接跳转到它。代码分支可以留在内存中由没有对其进行回补的其它原子使用。本发明的实施例规定代码原子130和数据原子130参考被标记以在原子级别上影响特定加载操作(例如,延迟或渴望)。
图15是五个代码程序和三个数据单元的示例系统图。在该示例中,程序P1调用程序P2和P3,程序P1也访问数据单元D1,其访问数据单元D2。程序P2调用程序P4并访问数据单元D3。程序P3访问数据单元D1并调用程序P5。根据本发明的一个实施例,每个代码程序{P1,P2,P3,P4,P5}定义为单个的单独可寻址原子。类似地,每个数据单元{D1,D2,D3}定义为单个的单独可寻址原子。在运行时间,当P1被加载时,D1立刻被加载,这使得D2将被加载。如果对P2和P3的参考是延迟的,那么将建立用于P2和P3的分支,考虑到程序代码的实际加载将被延迟,直到如果或者当它们实际被调用为止。很可能某些代码程序(例如,错误处理程序)在正常执行路径期间不会被调用。在这种情况下,通过延迟加载可以节省处理和内存。基于代码(例如,P2)的延迟加载的数据(例如,D3)的隐含加载节省了处理器和内存两者。
数据原子参考可以被编码以提供用于数据单元的类似容量。数据的明确延迟加载可以提供甚至更多的节约(例如,D3的加载甚至可以被延迟到P2被加载之后)。
通过修改参考原子的原子识别符,原子管理程序160可以延迟数据单元/原子的加载直到它实际被参考为止。对于代码原子,很可能某些数据原子(例如,错误消息)在正常执行路径期间不会被参考。数据原子的延迟/迟缓加载也节省了处理和内存。
传统系统(例如,Linux DLL)提供了代码分支,但是这些系统在启动时建立了用于所有可能参考的分支。相反,本发明的实施例只为被加载原子130实际参考的每个原子130建立分支。参考图13,加载P1会使得用于P2和P3的分支被建立,但不建立用于P4的分支。传统的系统典型地在启动时加载所有数据单元。例如,在传统系统中,在启动时D1,D2和D3都将被加载。相反,本发明的实施例在加载D2时或只有当D3被实际使用时才加载D3。在加载方面,以相似的方式来处理数据和代码的灵活性提供许多性能改善。对于具有相对大的数据与代码之比的系统尤其如此。
图16a是示例数据原子130的图。数据原子130被概念性地表示以示例它们的原子id 132、原子字节134和原子参考136。数据原子16001(类似于图15的D1)包含两个数据项(原子字节134)至个人名字(例如,“Mary Smith”)的参考(指针)和表示Mary的年龄(例如,47)的整数。参考(原子参考136)是对原子16002的参考。参考16002(类似于图15中的D2)是表示字符串“Mary Smith”(原子字节132)的数据原子130,原子16002不参考任何其它原子。
图16b是示例代码原子130的图。代码原子130被概念地表示以示例它们的原子id 132、原子字节134和原子参考136。代码原子15000(类似于图15中的P5)表示print_person()程序的可执行代码,其用来打印出人名和年龄。代码原子16000(类似于图15中的P3)表示调用print_person()函数以打印输出Mary的名字和年龄的程序。代码原子16000通过参考数据原子16001来参考用于Mary的数据,并通过参考代码原子15000print_person()来调用print_person()函数。因此,由原子16000表示的原子包含两个原子参考136,对原子15000(用于print_person()程序的代码原子)的代码原子参考136和对原子16001(用于Mary的数据的数据原子)的数据原子参考136。
虽然本发明参考其优选实施例进行了特别展示和描述,但是本领域技术人员应该明白,在不脱离由所附权利要求包括的本发明的范围的情况下,可以对其作出各种形式和细节上的变化。
具体来说,原子数据库120被描述为具有大量不同的部分,本领域技术人员很容易认识到,表示原子130的不同用途的各部分可以在本发明的教导的范围之内被添加或移除。此外,实际盘编码方案可以在本发明的教导范围之内进行改变。
虽然本发明的实施例适合于实现CurlTM运行时间,但是所有的公开并不将本发明的使用限制于CurlTM运行时间。本发明的各实施例可以适用于任何软件程序。
权利要求
1.一种按照需要加载原子化计算机程序代码和数据的方法,包括将以精细颗粒化、单独可寻址方式定义代码或数据的原子从原子数据库加载到内存中,所述原子包括原子识别符;计算机程序代码或数据信息;计算机程序代码或数据参考信息;和通过将参考原子识别符变换成内存地址来修改计算机程序代码或数据信息。
2.根据权利要求1的方法,其中,内存地址是用于加载被参考原子并跳转到该被参考原子的分支例程的内存地址。
3.根据权利要求2的方法,其中,到所述分支例程的内存地址由直接参考所述被参考原子的更新的内存地址来重写。
4.根据权利要求2的方法,其中,到所述分支例程的内存地址对于参考所述被参考原子的所有被加载原子进行重写。
5.根据权利要求1的方法,其中,所述修改步骤进一步包括编码内存地址以便被参考数据原子直到在运行时间实际被访问时才加载。
6.根据权利要求5的方法,其中,所述编码步骤包括将参考原子识别符乘以2并将该参考原子识别符加1来产生松散数据原子识别符。
7.根据权利要求1的方法,进一步包括步骤基于对在前的原子加载经历的运行时间模式的分析,重新排序基于盘的原子数据库中的原子以使访问有效率。
8.根据权利要求1的方法,进一步包括步骤通过代替计算机程序代码或数据信息以及计算机程序代码或数据参考信息来更新在原子数据库中的至少一个原子。
9.根据权利要求1的方法,进一步包括步骤向原子数据库中的原子添加新的原子。
10.根据权利要求1的方法,进一步包括步骤从原子数据库中的原子中删除所选原子。
11.根据权利要求1的方法,其中,所述加载步骤进一步包括解压缩以压缩格式存储的计算机程序代码或数据信息。
12.根据权利要求1的方法,其中,基于预定使用门限从内存中移除被加载原子。
13.根据权利要求1的方法,其中,被加载原子的执行在加载由该被加载原子所参考的所有原子之前开始。
14.根据权利要求1的方法,进一步包括步骤修改计算机程序代码或数据参考信息以影响渴望或延迟加载技术。
15.根据权利要求14的方法,其中,修改步骤基于对在前的原子加载经历的运行时间模式的分析来确定加载技术。
16.根据权利要求1的方法,其中,被加载原子通过只读缓存器在多个可执行处理之间共享。
17.一种原子化计算机程序代码和数据的方法,包括接收按照定义单独可寻址代码和数据的目标代码格式的计算机程序代码和数据;从按照目标代码格式的计算机程序代码和数据中提取计算机程序代码和数据信息;从按照目标代码格式的计算机程序代码和数据中提取计算机程序代码和数据参考信息;修改计算机程序代码和数据参考信息以使用原子识别符;和将计算机程序代码和数据信息以及计算机程序代码和数据参考信息存储在一个原子中,该原子包括原子识别符;计算机程序代码或数据信息;和计算机程序代码或数据参考信息。
18.一种按照需要加载原子化计算机程序代码和数据的装置,包括原子,其包括原子识别符;计算机程序代码或数据信息;计算机程序代码或数据参考信息;和原子管理程序单元,其将以精细颗粒化、单独可寻址方式定义代码或数据的原子从原子数据库加载到内存中,并通过将参考原子识别符变换成内存地址来修改计算机程序代码或数据信息。
19.一种原子化计算机程序代码和数据的装置,包括接收器,用于接收按照定义单独可寻址代码和数据的目标代码格式的计算机程序代码和数据;提取器,用于从按照目标代码格式的计算机程序代码和数据中提取计算机程序代码和数据信息,并从按照目标代码格式的计算机程序代码和数据中提取计算机程序代码和数据参考信息;修改器,用于修改计算机程序代码和数据参考信息以使用原子识别符;和存储单元,用于将计算机程序代码和数据信息以及计算机程序代码和数据参考信息存储在一个原子中,所述原子包括原子识别符;计算机程序代码或数据信息;和计算机程序代码或数据参考信息。
20.一种按照需要加载原子化计算机程序代码和数据的装置,包括用于将以精细颗粒化、单独可寻址方式定义代码或数据的原子从原子数据库加载到内存中的设备,所述原子包括原子识别符;计算机程序代码或数据信息;计算机程序代码或数据参考信息;和用于通过将参考原子识别符变换成内存地址来修改计算机程序代码或数据信息的设备。
21.一种用于原子化计算机程序代码和数据的装置,包括用来接收按照定义单独可寻址代码和数据的目标代码格式的计算机程序代码和数据的设备;用来从按照目标代码格式的计算机程序代码和数据中提取计算机程序代码和数据信息的设备;用来从按照目标代码格式的计算机程序代码和数据中提取计算机程序代码和数据参考信息的设备;用来修改计算机程序代码和数据参考信息以使用原子识别符的设备;和用来将计算机程序代码和数据信息以及计算机程序代码和数据参考信息存储在一个原子中的设备,所述原子包括原子识别符;计算机程序代码或数据信息;和计算机程序代码或数据参考信息。
22.一种计算机程序产品,包括用来按照需要加载原子化计算机程序代码和数据的计算机可用介质;嵌入在该计算机可用介质中的一组计算机程序指令,包括以下指令将以精细颗粒化、单独可寻址方式定义代码或数据的原子从原子数据库加载到内存,所述原子包括原子识别符;计算机程序代码或数据信息;计算机程序代码或数据参考信息;和通过将参考原子识别符变换成内存地址来修改计算机程序代码或数据信息。
23.一种计算机程序产品,包括用来原子化计算机程序代码和数据的计算机可用介质;嵌入在该计算机可用介质上的一组计算机程序指令,包括下列指令接收按照定义单独可寻址代码和数据的目标代码格式的计算机程序代码和数据;从按照目标代码格式的计算机程序代码和数据中提取计算机程序代码和数据信息;从按照目标代码格式的计算机程序代码和数据中提取计算机程序代码和数据参考信息;修改计算机程序代码和数据参考信息以使用原子识别符;和将计算机程序代码和数据信息以及计算机程序代码和数据参考信息存储在一个原子中,所述原子包括原子识别符;计算机程序代码或数据信息;和计算机程序代码或数据参考信息。
24.一种嵌入在包括代码片段的载波中的计算机数据信号,用来按照需要加载原子化计算机程序代码和数据,其包括下列指令将以精细颗粒化、单独可寻址方式定义代码或数据的原子从原子数据库加载到内存,所述原子包括原子识别符;计算机程序代码或数据信息;计算机程序代码或数据参考信息;和通过将参考原子识别符变换成内存地址来修改计算机程序代码或数据信息。
25.一种嵌入在包括代码片段的载波中的计算机数据信号,用于原子化计算机程序代码和数据,包括下列指令接收按照定义单独可寻址代码和数据的目标代码格式的计算机程序代码和数据;从按照目标代码格式的计算机程序代码和数据中提取计算机程序代码和数据信息;从按照目标代码格式的计算机程序代码和数据中提取计算机程序代码和数据参考信息;修改计算机程序代码和数据参考信息以使用原子识别符;和将计算机程序代码和数据信息以及计算机程序代码和数据参考信息存储在一个原子中,所述原子包括原子识别符;计算机程序代码或数据信息;和计算机程序代码或数据参考信息。
26.一种用来存储由在数据处理系统上执行的计算机程序所访问的数据的存储器,其包括存储在表示原子数据库的存储器中的数据结构,该数据结构包括头部;和原子映象,该原子映象包括原子映象头部;和原子映象主体,该原子映象主体包括参考原子偏移序列的原子映象阵列,所述原子偏移序列包括第一原子文件偏移;增量编码文件偏移阵列;以及,参考一个原子包括原子标志;原子数量信息;编码的原子参考;和编码的原始原子字节。
27.根据权利要求26的存储器,其中,所述原子映象提供原子识别符到符号名的映射。
全文摘要
软件原子化提供了一种通过将以精细颗粒化、单独可寻址方式定义代码或数据的原子从原子数据库加载到内存以按照需要加载原子化计算机程序代码和数据的方法。原子包括原子识别符、计算机程序代码或数据信息以及计算机程序代码或数据参考信息。所述计算机程序代码或数据信息通过将参考信息变换成内存地址来修改。本发明提供了以隐含地以及明确地两种方式延迟加载数据。当参考延迟加载的代码时,数据被隐含地延迟加载。通过编码参考原子识别符延迟加载数据,以便被参考数据原子直到在运行时间被实际访问才被加载。
文档编号G06F9/445GK1826586SQ03815271
公开日2006年8月30日 申请日期2003年6月3日 优先权日2002年6月3日
发明者马修·J.·郝斯特特尔, 本杰明·R.·哈瑞森 申请人:住商信息系统株式会社
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1