专利名称:实现多重返回位置的方法和装置的制作方法
技术领域:
本发明一般涉及一种方法及装置,用来实现一个函数调用的多个返回点。尤其是,本发明涉及有效地获取多重返回点的地址的方法及装置。
计算机系统通常是通过计算机系统的网络例如局域网、内部网(intranets)及国际互联网联在一起的,使得它们可以共享诸如软件或程序及代码之类的资源。另外,包括多个子程序的许多程序被编制为一种程序,在这种程序中调用了许多并不包括在该程序之内的“外部”函数。通常,这些函数可被许多子程序所共享,因而允许计算机的系统资源得到更有效的使用。
当子程序调用函数时,被调用的函数必须最终返回到该子程序。另外,对子程序的返回必须要传到该子程序内的正确位置。参见
图1,以下将说明在计算机程序及由该程序调用的函数之间的流程。计算机代码104包括一个子程序g()108。子程序g()108包括多个被执行的指令。如图所示,所述指令包括对函数f()116的反复调用112。
当函数f()116被调用并“正常”执行,例如未发生意外时,则函数f()116正常地完成其运行,并被返回到子程序g()108a计算机子程序。函数f()116返回子程序g()108a内的位置依赖于调用的位置,或子程序g()108a计算机子程序内调用函数f()116的位置。特别是,如果是作为调用112a的结果而执行函数f()116,则函数f()116返回到返回地址120,该地址正如本领域技术人员可以理解的那样,是在子程序g()108a计算机子程序内紧接在调用112a之后的位置。与此类似,如果函数f()116是在由调用112b调用时而执行的,则函数f()116返回到返回地址120。一旦函数f()116返回到子程序g()108a计算机子程序,则子程序g()108a一般都继续运行。
许多函数可以具有多于一个的返回位置或点。举个例子,一个函数除具有一个正常的或预期的返回点,还具有一个备用返回点。备用返回点通常被认为是“异常”的返回点,例如与发生异常情况相关的返回点。备用返回点一般被存储在,或被编制在一个整体程序之内,以便能根据需要容易地确定所述返回点。举一个例子,在由不是处理异常情况的函数处理所发生的异常情况时,程序需要备用返回点。
用于将多个函数与多个备用返回点联系在一起的一种机制是返回点或返回地址表。图2a是一个显示了与调用栈相关的返回点表的示意图。一个调用栈204包括一个调用程序帧(caller frame)208,该调用程序帧208调用另一帧,即被调用程序帧(callee frame)212。被调用程序帧212与函数f()214相关。因此,当调用程序208调用被调用程序帧212时,函数f()214开始运行。
在执行到函数f()214的末尾时,函数f()214返回到,并由此被调用程序帧212也返回到调用程序208。当到调用程序208的这种返回不是正常的返回时,则正常的返回地址可被当作进入返回点表220的索引216,以确定正确的备用返回点。例如,如果正常返回地址为“1234”,则可在返回点表220中查询以找到“1234”。一旦找到“1234”,则可得到与“1234”相关的备用返回点地址。如图所示,对于正常返回地址“1234”,其相应的备用返回点地址为“1256”。一旦得到所述的备用返回点地址,则将其用来确保被调用程序帧212能恰当地返回调用程序208。
虽然使用一般作为查询表或散列表的返回点表,对于确定用于被调用程序的一个合适的返回点是很有效的,但完成表的查询通常是很慢的。一种用于实现多重返回点的更快速的处理包括省去对表的查询而确定多个返回点。正如本领域技术人员所能理解的那样,在函数运行期间,对该函数基本上“知道”这个函数是应使用一个常规的返回,或是这个函数应使用一个备用返回。因此,可以存储与备用返回地址有关的数据。
图2b是表示了用来存储备用返回地址数据的子程序的示意图。子程序g()236包括对函数f()的一个调用238。不管对函数f()的调用238是否会导致需要返回备用地址,调用238通常都会返回到返回地址240。返回地址240识别所存储的备用返回地址数据242。所存储的备用返回地址数据242位于子程序g()236a计算机子程序内靠近调用238的地方,以使备用返回地址数据242能很容易地被访问。一般来说,备用返回地址数据242存储在该指令流自身之内。由于所存储的备用返回地址数据242有可能不代表一条合法指令,或可能具有不希望有的负面效应例如覆盖了寄存器内的或存储器单元内的一个值,所以子程序g()的执行有可能不在地址240处继续,而是必须在下一条指令244处继续。
当调用238正常返回时,调用238应返回到下一条指令244处。如图所示,在子程序g()236之内,下一条指令244离所存储的备用返回地址数据242偏移了一个距离D。因此,当调用238正常返回时,调用238必须返回到由返回地址240的位置加上一个偏移量D所确定的位置,该位置即为下一条指令244的位置。一般来说,由于距离D具有一个4字节的值,所以下一条指令244离返回地址240偏移了4个字节。
在需要一个备用返回地址时,访问程序内所存储的备用返回地址要比完成一个表的查询更具时效性,而在不需要备用返回地址时,访问所存储的备用返回地址的能力常常对该程序的性能予以负面的影响。当一个函数调用正常返回时,在返回地址的位置上加上一个偏移量以确定出所要执行的后续指令的位置,这种做法常常是比较慢的,而且会招致与计算所述后续指令位置相关的性能的恶化。换句话说,与正常返回有关的速度可能由于所存储的备用返回地址的实现而受到损害。另外,用于产生一个对一个正常返回或最有可能发生的返回“最佳推测”估计的分支推算,有可能由于使用跳转而受到损害,正如本领域技术人员所理解的那样。
换句话说,如下所述,“跳转”是用来绕过所存储的备用地址的。跳转或转移通常是包含在程序或子程序中,以绕过在某些场合有可能是不需要的代码片段。例如,如图2c所示,当函数调用正常返回时,有可能在子程序中执行跳转,以使能绕过所存储的返回地址。在子程序g()266中,对函数f()执行一个调用268。当调用268正常返回时,返回到由返回地址270所确定的子程序g()266内的一个位置。与返回地址270相应的这个位置是要跳转到位置L的一条指令272,该位置L位于距离指令272有一个固定偏移F处。因此,当调用268正常返回到返回地址270时,就执行一个到下一条指令274的跳转。这种跳转饶开了,或这种转移绕过了所存储的备用返回地址数据276。
虽然跳转的实现有可能减小了性能的恶化例如硬件性能的恶化,这种恶化与将返回地址加上一个偏移量以得到后续指令的位置相关,但是,这种跳转有可能很慢。必须将一个附加代码包括在程序内,以允许其跳转,因此增大了程序的整体大小。
如上所述,对于函数调用实现多重返回点的传统方法常常很慢且效率不高,因而,这些多重返回点的实现可有害地影响与函数调用相关的程序的性能。因此,需要的是一种用于实现多重返回点的有效的方法及装置,以便既可有效地发生正常返回,也可有效地发生备用返回。
这里公开了一种方法及装置,使实质上能存储与函数调用相关的一个备用返回地址,以便可容易地访问该备用返回地址。依据本发明的一个方面,实现有效地存储与子程序调用的一个函数相关的返回地址的一种方法,它包括在子程序执行期间,从该子程序内调用函数。一般来说,这个函数在该子程序的外部。该函数一旦被调用,便开始运行。最终,该函数返回到子程序。特别是,函数会返回到子程序内的一个位置,这个位置是由所希望的返回点,或正常的返回地址所确定的。与所希望的返回点相应的子程序内的指令是一条“伪”指令,该指令是以低运算开销执行的。选出所述伪指令以在不影响正常的程序运行的情况下运行,即不使用其结果。换句话说,伪指令的目的是以合适的方式编码所述备用返回点或多个点。
在一个实施例中,当函数以期望的方式返回到返回子程序时,在返回到所期望的点之前,函数的执行已经结束了,所述伪指令的执行没有任何效果。在另一个实施例中,当函数确实返回到备用返回点时,执行所述代码,以访问存储在正常返回点处的伪指令,且由伪指令所代表的库值中计算出所述备用返回点的地址。
在阅读了以下详细的说明及研究了以下附图中的各幅图之后,本发明的这些及其它优点将变得显而易见。
参照联系所述附图进行的以下详细的说明,可更好地理解本发明。
图1是一个表明调用外部方法的计算机代码的示意图。
图2a是表明了一个调用栈和一个相关返回点表的示意图。
图2b是表明了一个存储了与对函数调用相关的备用返回地址的计算机子程序的示意图。
图2c是表明了一个计算机子程序的示意图,该计算机子程序转移并绕过一个所存储的与对函数的调用相关的备用返回地址。
图3a是显示了依据本发明一实施例的计算机子程序的示意图,该子程序在调用了一个函数之后,执行了一条伪指令。
图3b是显示了依据本发明一实施例的计算机子程序的示意图,该子程序在调用一个函数之后,执行了多条伪指令。
图3c是显示了依据本发明一实施例的计算机子程序的示意图,该子程序在调用了一个函数之前,执行了一条伪指令。
图4是显示了依据本发明一个实施例的与子程序的执行相关的步骤的处理流程图,该子程序包括一个具有很多返回点的函数调用。
图5a是显示了依据本发明一实施例的一个正常返回的函数调用的示意图。
图5b是显示了依据本发明一实施例的一个函数调用的示意图,所述函数调用会引起发生异常及异常返回。
图6是显示了适于实现本发明的一个计算机系统的示意图。
图7是显示了适于实现本发明的一种虚拟装置的示意图。
在一个由计算机程序调用的函数在将要返回该计算机程序时,该函数可返回到若干返回位置或点中的任意一点。举个例子,一个函数可正常地或如所期望的那样返回。另外,函数也可以其它方式例如异常方式返回。一般必须存储与异常返回相应的异常返回点,以便能容易地访问到它。
适应从函数返回到程序内不同点的一些实现在查询表中存储了一些用于备用返回位置的地址。对表进行查询以确定备用返回地址的操作通常都很慢。明确地适应从函数返回到不同位置上的其它实现存储与备用返回地址相关的数据,该地址靠近对函数(并且从该函数返回)进行调用的位置。明显涉及存储一次调用附近的数据的这种实现,通常需要会导致硬件性能恶化的额外的附加空间开销或是会对正常返回有负面影响。
为实现来自函数调用的多重返回而不会引起性能恶化或极大地降低任何返回的效率,与返回相应的地址数据可包含在基本上执行非“有用”操作的一条指令中。即实质上没有相关性且一般以极小的开销例如比执行跳转所需的要小的开销而执行的一条指令,可被用来对备用返回地址编码。基本上没有相关性,且通常以极小的开销执行的一条指令,一般被看作“伪”指令。这类指令包括,但并不仅限于,一些指令例如一条移动指令或一条测试指令。
一般一条移动指令用于将数据移入一个寄存器或堆栈区。举个例子,用来将一个常数移入一个未使用的寄存器的一条移动指令可以具有以下语法mov constant,unused-reg其中“unused-reg”可以是当前不包括一个有用值的任一个寄存器,且“constant”可包括例如是任一个备用返回地址的数据。一条测试指令依据一个寄存器值设定处理器的标志位,且可具有如下语法tst constant,reg其中“reg”可以是任一寄存器,“constant”可包括与一个备用返回地址相关的数据。
由于执行伪指令一般只需要少量的附加计算,所以在来自函数调用的返回为正常情况时,执行一条伪指令不会有害地影响到计算机系统的总体性能。换句话说,在不需要备用返回时,执行一条伪指令一般不会影响计算机系统的性能。因此,不管返回是正常返回还是备用返回,对提供给函数调用使用的伪指令的执行是相对较快且有效的,其中这种函数调用有可能引起备用返回。
一般可将一条伪指令放在程序或子程序内的任何地方。举个例子,可将一条伪指令放在子程序内紧随对函数进行调用的位置。参见图3a,将会依据本发明的一实施例,对子程序内位于对函数的调用之后的一条伪指令所包含的内容进行说明。子程序g()304一般包括指令308。对函数f()的调用308a的返回既可是正常的,亦可是异常的。
当对函数f()的调用308a返回时,返回到子程序g()304内由返回地址310所确定的位置。返回地址310确认一条伪指令308b。伪指令308b一般位于离对函数f()的调用308a有一个固定偏移量例如4个字节的位置上。
在一个实施例中,当对函数f()的调用308a正常返回时,则执行伪指令308b而基本上不使用附加开销,这种对伪指令的执行,尤其是在现代超标量中央处理单元(CPU)中的执行,可在每个机器周期内运行许许多多的独立指令,正如本领域技术人员所能理解的那样。另外,当对函数f()的调用308a返回备用返回点时,它读取包含伪指令308b的字节,并提取出在伪指令308b内被编码的备用返回地址。接着,所述运行返回到这一备用返回点,因而完成了该备用返回。
在伪指令308b如上所述基本上不使用附加开销地运行之后,接下来,或下一步,执行子程序g()304内的指令308c。应该理解,指令308一般前接和后跟许多其它指令。
在一个实施例中,对函数的调用可具有多于一个的备用的或异常的返回点。例如,一个对函数的调用可涉及多种可能的意外,正如以下将参照图5a及5b所做的更详细的说明。当有可能有多于一个异常的返回时,则众多的伪指令可被包含在靠近函数调用的地方,以致每个异常返回地址都有一条相应的伪指令。在单独一条伪指令不足以保存寄存器或堆栈区内的所有相关数据的情况下,也可使用若干条伪指令。
图3b是显示了依据本发明一实施例,在对函数进行调用后,执行了若干条伪指令的计算机子程序的示意图。如图所示,子程序g()324包括指令328。可将指令328置于子程序g()324内的任何地方。换句话说,可将指令328置于靠近子程序g()324的起始处、在子程序g()324的中央、或大体上位于子程序g()324的末尾。当对函数f()的调用328a返回时,返回到由返回地址330所确定的位置。返回地址330确定了第一伪指令328b。在执行了第一伪指令328b后,就执行紧随第一伪指令328b的伪指令。最后,执行“第N”条伪指令328c。
每条伪指令例如伪指令328b、328c通常位于离调用328a有一个固定偏移量的位置,以便可根据调用328a而容易地设置虚位置。所有伪指令的全部运行使用了很少的开销,就如每一条伪指令基本上都不使用附加开销那样。后来,或接着,在“第N”条伪指令328c执行之后执行指令328d。
一般来说,伪指令不必位于对具有若干返回位置的函数的调用之后,也可将伪指令放在对具有多个返回位置的函数的调用之前。参见图3c,将根据本发明的一实施例,说明将一个伪指令插入到对子程序内的函数的调用之前的情况。如图所示,子程序g()344包括对伪指令348a的调用,该伪指令348a位于对函数f()的调用248b的前面。伪指令348a位于离对函数f()的调用的一个固定偏移量的位置。每次伪指令348a位于对子程序g()344内函数f()的调用248b之前时,伪指令348a与对函数f()的调用248b具有相同的偏移量。在一个实施例中,该偏移量为4个字节,尽管偏移量很可能有悬殊的变化。当对函数f()的调用348b返回时,返回到由返回地址350指定的位置。在所说明的实施例中,由返回地址350确定的位置包括一条指令348a。
接着参见图4,将依据本发明的一个实施例,说明包含在程序内的子程序的运行过程中,与一般地运行一个函数调用相关的步骤。如本技术领域人员所能理解的那样,正在执行的子程序可最终到达一个函数调用。在步骤402中,由子程序调用的函数开始运行。在函数执行的过程中,所产生的条件用来判断对函数的调用将会导致正常返回还是异常的或备用的返回。
当被调用的函数的执行在步骤402处引起正常返回时,则处理流转到步骤404,在步骤404中完成所调用函数的运行。在所调用的函数的执行结束后,在步骤406处,函数返回到由返回地址即正常返回地址所确定的位置。在所说明的实施例中,由返回地址所确定的位置上包括一条伪指令例如,如图3a所示的一条伪指令。一般来说,伪指令可以是任何一条合适的近似“无附加开销”的指令,这种指令不用改变与程序的全部运行相关的内部状态就可嵌入一个常数。如上所述,伪指令可包括,但并不仅限于,一条移动指令及一条测试指令。
伪指令在步骤412处执行之后,所述子程序继续执行。一般来说,子程序的继续执行可包括对各种指令的执行,如附加的函数调用及返回。当如果没有余下的指令可供执行,则子程序的运行就结束了。
返回到步骤402处执行所调用的函数,当所调用的函数的执行需要备用的即异常的返回时,则处理流由步骤402转到步骤408,步骤408从存储器内调出备用返回地址。特别是,在一个实施例中,从正常返回地址加一个偏移量的位置上调出备用返回地址。
一旦加载了备用返回地址,则在步骤410,执行从函数到由备用返回地址所确定的位置的跳转。当运行返回到备用地址时,伪指令被看作“数据”,因此,利用这样一个事实,即代表一条指令的位也可被看作一个二进制值。举个例子,一个处理器可对以下指令编码MOV#1234,regl其中,将一个可能是备用返回地址的十六进制常数“1234”作为字节序列“5B000001234”移入寄存器“regl”。然而,指令编码在不同的处理器类型之间是不同的,任何编码可基本上确定指令的所有部分,包括指令类型,例如“移入”、第一操作数例如常数“1234”、第二操作数例如寄存器“regl”。
如上所述,一个编译器使一条伪指令包括作为一伪指令的第一操作数的备用返回地址。因此,利用指令格式的常识,通过读取作为一个整数值的指令的2至5字节,可得到信息诸如一个常数值如一个备用返回地址之类的信息。
正如本技术领域人员所能理解的那样,伪指令形成一种模式,其中指令的一些位是固定的,一些是不定的。固定位一般不可变化,因为改变固定位会使指令的执行非常昂贵,或具有干扰程序正常运行的负面影响。举个例子,一些固定位可表明指令类型,例如“移动”。指令中的变化位可被用来对任意值例如备用返回点的地址编码,举个例子,在伪指令“5B00001234”中,字节“5B”可以是表明对寄存器“regl”的一个移入的固定部分,“00001234”可以是不定部分。一般来说,伪指令的可变部分是由许多其指令位的任意组合构成的,其指令位包括众多非连续的部分,并依赖于所使用的特殊的机器指令集合。
当跳转到备用返回地址后,处理流由步骤410转到步骤413,在步骤413处,执行与备用返回地址相关的代码。接下来,程序继续在步骤414处执行,直到运行结束。
多个返回地址对于实现各种程序设计语言装置是有用的。举个例子,可用伪指令来方便子程序的执行。这种子程序具有有可能发生意外的函数调用。当所调用的函数发生意外时,所述意外一般不受所调用函数的控制。更确切地说,函数的调用程序控制了该函数所发生的意外。图5A及5B是显示了依据本发明一实施例的一个函数的示意图,该函数或是可正常的返回,或是发生意外并由此异常返回。一个子程序g()504包括一个调用了函数f()512的try块508。子程序g()504进一步包括一个异常处理程序510,该程序510用来控制,或处理在函数try508的执行中所产生的异常现象。
如图5a所示,当函数f()512被调用,并正常返回时,即函数f()512没有产生意外时,函数f()512返回到try块508。特别是函数f()512返回到try块508内。由正常返回地址516所确定的位置。在所说明的实施例中,如上面参照图3a所做的说明那样,由正常返回地址516所确定的这个位置处是一条伪指令。
如图5b所示,当函数f()512的执行引起意外发生时,函数f()512返回到意外处理程序510。即当函数f()512产生意外时,就返回到由备用返回地址520所确定的位置,该位置标识与意外处理程序510相关的一条指令。
当意外处理程序510处理由函数f()512所发生的意外时,函数f()512最终在try块508后第一条指令522处继续执行。在一实施例中的伪指令是这样一条指令如一条移动指令或一条测试指令,这种指令可使备用返回地址能存储在指令流中。
一般可在任意合适的计算机系统中实现本发明。特别是,可使用任意合适的虚拟装置来实现如上所述的多个返回点,例如所述虚拟装置是参照图7所说明的虚拟装置。图6显示了用于实现本发明的一个典型的通用计算机系统。计算机系统730包括与存储器设备相耦合的任意多个处理器732(也被称作中央处理单元,或CPU),其中存储器设备包括主存储器734(一般是只读存储器,或ROM)及主存储器736(一般为随机存取存储器,或RAM)。
可用计算机系统730,或更具体地说是CPU732来支持一个虚拟装置,如本技术领域人员所能理解的那样。以下,将参照图7说明在计算机系统730上所支持的一个虚拟装置的例子。正如本技术领域中所公知的那样,在RAM一般被用来以双向方式传递数据及指令时,ROM只能以单向方式向CPU732传递数据及指令。CPU732一般可包括大量的处理器。两个主存储器734、736都可包括任意合适的计算机可读媒体。一般作为一个大容量存储器设备的从存储媒体738,也与CPU732双向耦合,并提供附加的数据存储器容量。大容量存储器设备738是一种可被用于存储程序的计算机可读媒体,该程序包括计算机代码、数据或类似数据。一般情况下,大容量存储器设备738是一种比主存储器设备734、736要慢的存储媒体,例如硬盘或带。大容量存储器设备738可以是磁带或纸带阅读机或其它众所周知的设备。必须明白,在适当的情况下,存储在大容量存储器设备738内的信息,可作为虚拟存储器以标准方式被插入以作为RAM736的一部分。一个特殊的主存储器设备734如CD-ROM也可向CPU732单向传送数据。
CPU732也可与一种或多种输入/输出设备740相耦合,这些输入/输出设备740可包括,但并不仅限于一些装置,例如视频监视器、跟踪球、鼠标、键盘、话筒、触敏显示器、转接卡读取器、磁或纸带阅读机、图形输入板、输入笔、声音或书写识别器,或其它当然是众所周知的输入设备如其它计算机。最后,CPU732可任意地与计算机或远程通信网络如使用如一般在712处所示的网络连接的局域网、互联网或一个内部网相耦合。对于这种网络连接,在执行如上所述的方法步骤的过程中可想象CPU732可从网络中接收信息,或向该网络输出信息。可从网络中接收这种经常被表示为CPU732执行的指令序列的信息,或向其输出这种信息,例如,是以体现在一个载波中的一个计算机数据信号的形式传送的。如上所述的设备及材料对计算机硬件及软件技术领域内的人员是众所周知的。
如在前说明,一个虚拟装置可在计算机系统730上执行。图7是代表了由图7中的计算机系统730所支持的且适合于完成本发明的一个虚拟装置的示意图。当一个计算机程序例如是以由California的Pala Alto的太阳(Sun)微系统公司所开发的JavaTM程序设计语言所写的计算机程序运行时,将源代码810提供给编译时环境805内的编译器820。编译器820将源代码810转换为字节代码830。一般来说,源代码810是在由软件开发人创建源代码830时被转换为字节代码830的。
字节代码830一般可被重建、下载、或相反通过网络例如图6的网络712分配,或被存储在存储器设备例如图6的主存储器734上。在所说明的实施例中,字节代码830是平台独立的。即字节代码830实际上可以在任何能运行一个合适的虚拟装置840的计算机系统中运行。举个例子,在JavaTM环境中,字节代码830可以在能运行JavaTM虚拟装置的计算机系统中运行。
将字节代码830提供给包括虚拟装置840的运行时环境。一般可通过使用如图7的CPU732的一个处理器执行运行时环境835。虚拟装置840包括一个编译器842、一个解释器844、及一个运行时系统846。一般既可将字节代码830提供给编译器842,也可将其提供给解释器844。
如上所述,当将字节代码830提供给编译器842时,包含在字节代码630中的方法被编译为机器指令。另一方面,当将字节代码830提供给解释器844时,字节代码830被一次一个字节地读入解释器844。由于每个字节代码已被读入解释器844中,所以接着解释器844执行由每个字节代码所确定的操作。一般来说,解释器844处理字节代码830,并连续地执行与字节代码830相关的操作。
当由操作系统860调用了一种方法时,如果确定了该方法是被当作解释方法而调用的,则运行时系统846可从解释器844中得到该方法。另一方面,如果确定了该方法是被当作编译方法而调用的,则运行时系统846激活编译器842。之后,编译器842由字节代码830产生出机器指令,并执行该机器语言指令。一般来说,当虚拟装置840结束时,机器语言指令被废弃。
虽然仅说明了本发明的几个实施例,但应理解本发明在未脱离本发明的主旨及范围的情况下以许多其它的形式实现。举个例子,虽然本发明的说明一般是依据有两个返回点的情况,但也可在对具有多于两个返回点的函数进行调用中实现本发明。一般来说,可将伪指令加在计算机子程序中,以用于与所调用函数相关的每个返回点。
一些机器指令集合被限制在32位的长度内,通常这种长度对表示一个完整的返回地址所需的全32住或64位值编码是不够的的,在这种情况下,构造直接对一个32位或64位值编码的伪指令是不可能的。然而,本发明仍可被用来向备用返回点提供快速访问。用以替换在伪指令中直接对备用返回地址编码,可将正常返回点和备用返回点之间的距离编码。在给出这一距离后,可在正常返回地址上加上这一距离,而容易地得到备用返回点。另外,可使用多个伪指令对在伪指令中的地址部分编码,正如以上参照图3b所做的说明那样。举个例子,第一伪指令可包括备用地址的第一个16位,而第二伪指令可包括32位值所余下的16位。
一般可广泛地变换与包括函数的程序的运行相关的步骤,该函数具有多个返回点。例如,如上参照图3c所做的说明中,与特定的函数调用相关的伪指令可位于函数调用之前。换句话说,可在函数调用之前执行一伪指令如移动指令或测试指令而未脱离本发明的主旨及范围,其中的函数调用是与伪指令相关。
多个返回点的使用适用于各种不同的用途。如上所述,可使用多个返回点以减轻发生意外的困扰。虽然只说明了依据本发明如何实现意外的一个例子,必须理解可广泛地变换意外的实现,而未脱离本发明的主旨和范围。使用多个返回点可适用于在系统如一个基于Smalltalk语言的系统中使用,其中的系统使用了非局部返回。当使用多重返回点时,可将相关伪指令放置在对具有多重返回点的函数的调用之后。也可将所述伪指令放在对函数的调用之前。最终,可将多条伪指令分布为一些伪指令位于调用之前,而其余的则位于调用之后。因此,应将本实施例看作是说明性的且不是对本发明的限制。本发明并不仅限于本文所给出的详细情况,还包括许多覆盖其全部范围的在附加权利要求的范围内所做的修改。
权利要求
1.用于存储与若干返回点中的一个点相关的数据的一种计算机实现方法,该方法使能有效地获得与若干返回点中的该点相关的数据,所述若干返回点包括一个期望的返回点及一个第一备用返回点,该计算机实现方法包括在子程序运行时,从子程序内部调用一个函数,其中函数是与该子程序分开的;开始执行该函数;从函数返回到子程序,其中函数返回到子程序内的由期望的返回点所确定的位置;以及执行子程序内的第一指令,其中对第一指令的执行几乎没有使用附加开销,并且对该子程序的执行没有明显的影响。
2.如权利要求1所述的一种计算机实现方法,其特征在于所述函数如所期望的那样返回到所述子程序,该方法进一步包括在返回到所期望的返回点之前,完成对所述函数的执行,所述所期望的返回点用于识别该子程序内的第一指令。
3.一种如权利要求2所述的计算机实现方法,进一步包括所述子程序的继续运行。
4.如前述权利要求之一的一种计算机实现方法,其特征在于开始执行函数的步骤包括加载第一备用返回点,其中第一备用返回点是由位于距离所期望的返回点有一个固定偏移量的位置上的一条指令所确定的。
5.如权利要求4所述的一种计算机实现方法,进一步包括中止对所调用的函数的运行;以及跳转到第一备用返回点。
6.用于存储与若干返回点中的一个点相关的数据的一种计算机系统,该系统能有效地获得与若干返回点中的该点相关的数据,所述若干返回点包括一个期望的返回,最及一个第一备用返回点,该计算机系统包括一个处理器;一个与处理器相关的调用装置,所述调用装置用于在子程序运行时,从子程序内部调用一个函数,其中函数是与该子程序分开的;一个与处理器相关的执行装置,该执行装置用于开始执行一个函数;以及一个返回装置,用于从函数返回到子程序,其中函数返回到子程序内由期望的返回点所确定的位置,其中返回装置还用于执行子程序内的第一指令,其中对第一指令的执行几乎没有使用附加开销,并且对该子程序的执行没有明显的影响。
7.如权利要求6所述的一种计算机系统,其特征在于将所述函数设置为如所期望的那样返回到所述子程序,所述执行装置还用于在返回到所期望的返回点之前,完成对所述函数的执行,所述所期望的返回点用于识别该子程序内的第一指令。
8.一种如权利要求6和7之一所述的计算机系统,其特征在于所述执行装置进一步包括一个加载器,该加载器用于加载第一备用返回点,该第一备用返回点是由位于离所期望的返回点有一个固定偏移量的位置上的一条指令确定的。
9.用于存储与若干返回点中的一个点相关的数据的一种计算机程序产品,该系统能有效地获得与若干返回点中的该点相关的数据,所述若干返回点包括一个期望的返回点,该计算机程序产品包括用于在子程序运行时,从子程序内部调用一个函数的计算机代码,其中函数是与该子程序分开的;用于开始执行一个函数的计算机代码;用于从函数返回到子程序的计算机代码,其中函数返回到子程序内由期望的返回点所确定的位置;用于执行子程序内的第一指令的计算机代码,其中对第一指令的执行几乎没有使用附加开销,并且对该子程序的执行没有明显的影响;以及一种能存储该计算机代码的计算机可读媒体。
10.如权利要求9的一种计算机程序产品,其特征在于所述计算机可读媒体是从由数据信号所组成的群中选出的一种,所述数据信号可以是实现在一载波、一CD-ROM、一计算机磁盘、一计算机带、及一计算机磁盘驱动器内的。
11.用于存储与若干返回点中的一个点相关的数据的一种计算机实现方法,该方法能有效地获得与若干返回点中的该点相关的数据,所述若干返回点包括一个期望的返回点及一个第一备用返回点,该计算机实现方法包括执行一个子程序;在子程序运行时,从子程序内部访问一个函数,该函数实际上是与该子程序分开的;启动函数的运行;从函数返回到子程序,其中函数返回到子程序内由期望的返回点所确定的位置;以及执行子程序内的第一指令,其中对第一指令的执行对该子程序的全部执行速度没有明显的影响。
12.如权利要求11的一种计算机实现方法,进一步包括确定何时函数如所期望的那样返回到子程序;以及当函数如所期望的那样返回到子程序时,在返回到所期望的返回点之前,完成对函数的运行,将所期望的返回点设置为能识别子程序内的第一指令。
13.如前述权利要求之一所述的一种计算机实现方法,其特征在于启动函数的运行包括识别第一备用返回点,其中所述第一备用返回点是由离所期望的返回点有一个固定偏移量的位置上的一条指令所识别的。
14.如权利要求13所述的一种计算机实现方法,进一步包括中止函数的运行;以及跳转到第一备用返回点。
15.用于运行子程序的一种计算机实现方法,所述子程序包括一个函数调用和若干返回点,所述计算机实现方法包括开始执行子程序;启动函数调用的运行;加载与该子程序相关的第一返回地址;从函数调用返回到第一返回地址;执行与第一返回地址相关的代码,其中执行与第一返回地址相关的代码包括将与指令相关的位翻译为二进制值;以及继续执行能够所述子程序。
全文摘要
公开了一种基本上能有效存储与一函数调用相关的备用返回地址,以便可容易地访问该备用返回地址的方法及装置。依据本发明的一个方面,用于使能有效地存储与由一子程序调用的函数相关的返回地址的方法。函数一旦被调用,就开始运行。最终,该函数返回到子程序。相应于所期望返回点的子程序内的指令是一条伪指令,该伪指令以低附加开销运行,且不影响程序运行。当所调用的程序返回到备用返回点时,它通过阅读嵌入在所述伪指令内的数据而得到该地址。
文档编号G06F9/42GK1234549SQ9812430
公开日1999年11月10日 申请日期1998年10月5日 优先权日1997年10月6日
发明者U·赫尔茨勒, R·格里瑟梅尔 申请人:太阳微系统有限公司