程序变换方法

文档序号:6651073阅读:227来源:国知局
专利名称:程序变换方法
技术领域
本发明涉及变换用面向对象语言描述的程序的程序变换方法,特别涉及将虚函数调用变换为直接函数调用的程序变换方法。
背景技术
近年来,随着程序的大规模化,为了提高程序的开发效率、实现再利用,或者为了提高程序的可维护性,频繁用C++或Java(注册商标)等面向对象语言进行程序开发。
作为面向对象语言的特征之一,有多态性。所谓“多态性”,表示其动作按照执行程序时的对象实例的类型来动态地变化的性质。
为了实现该多态性,例如在C++语言中具有称作虚函数的功能。用图1~图4来说明该虚函数。
图1是用面向对象语言C++描述的程序。类A的成员函数f、g及h的声明中指定的关键词“virtual”指定了成员函数f、g及h是虚函数。所谓“虚函数”,是指在执行程序时按照指针指向的对象的类型来动态决定要执行的函数的函数,在派生类中重定义了基类的虚函数的情况下,在指针指向派生类的对象的情况下,执行派生类的虚函数。
类B继承了类A,类B的成员函数g覆盖了基类A的虚函数g,执行类B特有的动作。
此时,在函数t2内指针变量p调用成员函数g后,成为虚函数调用。此时,如果指针变量p指向的对象是类A的对象,则执行类A的函数g;如果是类B的对象,则执行类B的函数g。这样,按照指针变量p指向的对象的类型在执行时决定要执行的函数。
该虚函数的实现方法的概略图示于图2。
类B类型的对象obj_b在内部保持指向虚函数表的指针成员vptr。成员vptr指向类B的虚函数表vtbl_B。在类B的虚函数表中,保持着可由类B调用的所有虚函数的地址。
考虑指针变量p调用虚函数g的情况。
在指针变量p指向类B类型的对象obj_b的情况下,p保持着obj_b的起始地址。虚函数调用所调用的函数的地址需要通过下述过程来取得首先取得虚函数表,接着取得要调用的函数的地址。
即,取得将指针变量p的值加上offset1所得的地址的内容,该值加上offset2所得的地址的内容成为要调用的函数的地址。
因此,执行虚函数调用的汇编码如图3所示。而执行函数的直接调用的汇编码如图4所示,虚函数调用的代码往往指令数多,执行速度也慢。
因此,尽量减少虚函数调用,程序的执行性能将提高。
作为用于减少执行虚函数调用的次数、提高执行性能的现有技术,有下述技术比较虚函数调用所调用的函数的地址,在要调用的函数是某个特定的函数的情况下直接调用该函数(例如参照(日本)特开2000-40007号公报)。由此,可以变换为在能够确定虚函数调用所执行的函数的情况下执行直接调用该函数的代码,而在不能确定的情况下执行通常的虚函数调用的代码。用特开2000-40007号公报记载的方法变换了图5所示的程序的箭头(A)的函数h的概略图示于图6。这样,在虚函数的地址是成员函数“A∷f”(由类A定义的函数f)的地址的情况下,直接调用函数“A∷f”;而在其他情况下,进行虚函数调用。进而,可以通过内联展开函数的直接调用来提高执行性能。
此外,有下述技术分析类的继承关系,将没有派生类的类的虚函数调用变换为函数的直接调用(例如参照(日本)特开平10-320204号公报)。由此,可以在编译程序时将虚函数调用变换为函数的直接调用,所以能够提高程序的执行性能。用特开平10-320204号公报记载的方法变换了图5所示的程序的箭头(A)的函数h的概略图示于图7。
这里,在能够确定要调用虚函数的类的情况下,能够确定虚函数调用所调用的函数。例如,有下述情况对于图5的箭头(B)所示的类A的成员函数f,可以确定this指针的类型只能是类A。此时,在this指针调用虚函数g的情况下执行的函数必定为类A的成员函数g。这里,所谓this指针,表示在成员函数的内部指向启动了该成员函数的对象的特别的指针。
但是,在特开2000-40007号公报记载的技术中,如图8所示,即使在能够确定调用虚函数的类的情况下也生成比较函数的地址的代码,所以与直接调用函数的代码相比,有执行性能及代码长度变差的问题。
此外,由于this指针的类型是类A,所以在特开平10-320204号公报记载的技术中,在调用虚函数的类具有派生类的情况下,有不能将虚函数调用变换为函数的直接调用的问题。

发明内容
本发明就是为了解决上述课题而提出的,其目的在于提供一种程序变换方法,着眼于有时能够确定成员函数的this指针的类型的事实,能够提高执行性能,而且减小代码长度,同时将虚函数调用变换为函数的直接调用。
为了解决上述现有的课题,本发明的程序变换方法,变换用面向对象语言描述的程序,其特征在于,包含方法分析步骤,在上述程序中,分析调用方法的实例的类型;虚方法调用提取步骤,在上述方法的定义中,提取上述实例的虚方法调用;以及虚方法调用变换步骤,根据上述方法分析步骤的分析结果,将上述虚方法调用提取步骤提取出的虚方法调用变换为直接方法调用。
能够将虚方法(即虚函数)调用变换为直接方法调用(即函数的直接调用),能够提高程序的执行性能。此外,能够减小程序的代码长度。
此外,本发明另一方面的程序变换方法,变换用面向对象语言描述的程序,其特征在于,包含方法分析步骤,在上述程序中,分析调用方法的实例的类型;虚方法调用提取步骤,在上述方法的定义中,提取上述实例的虚方法调用;虚方法复制步骤,根据上述方法分析步骤的结果,复制上述虚方法;以及虚方法调用变换步骤,根据上述方法分析步骤的分析结果,将由上述虚方法调用提取步骤提取出的虚方法调用变换为直接方法调用。
能够通过复制虚方法,将虚方法调用变换为直接方法调用的可能性提高。因此,能够进一步提高程序的执行性能,而且能够减小程序的代码长度。
此外,本发明另一方面的程序变换方法变换用面向对象语言描述的程序,其特征在于,包含编译步骤,编译上述程序;和结合步骤,结合上述编译步骤的编译结果;上述编译步骤包含方法分析步骤,在上述程序中,分析调用方法的实例的类型;虚方法调用提取步骤,在上述方法的定义中,提取上述实例的虚方法调用;以及输出步骤,输出上述方法分析步骤的分析结果、上述虚方法调用提取步骤的分析结果及上述程序的变换结果;上述结合步骤包含分析数据提取步骤,输入上述编译步骤的输出,提取上述编译步骤的输出中包含的分析结果;虚方法调用变换步骤,根据上述分析结果提取步骤的结果,将上述虚方法调用变换为直接方法调用;以及链接步骤,链接上述虚方法调用变换步骤的结果。
能够用与上述程序变换方法不同的结构,得到同样的程序执行性能。
此外,本发明另一方面的程序变换方法,变换用面向对象语言描述的程序,其特征在于,包含预编译步骤,从上述程序中提取规定的信息;和变换步骤,根据上述预编译步骤的提取结果,将虚方法调用变换为直接方法调用;上述预编译步骤包含方法分析步骤,在上述程序中,分析调用方法的实例的类型;和虚方法调用提取步骤,在上述方法的定义中,提取上述实例的虚方法调用;上述变换步骤包含输入步骤,接收上述程序、上述方法分析步骤的分析结果及上述虚方法调用提取步骤的分析结果,作为输入;和虚方法调用变换步骤,根据由上述输入步骤输入的分析结果,将由上述虚方法调用提取步骤提取出的虚方法调用变换为直接方法调用。
能够用与上述程序变换方法也不同的结构,得到同样的程序执行性能。
根据本发明,能够提供一种程序变换方法,能够提高执行性能,而且减小代码长度,同时将虚函数调用变换为函数的直接调用。


通过以下结合示出了本发明的特定具体实施例的附图进行的描述,本发明的这些和其他目的、优点以及特性将变得很明显。在附图中图1是包含虚函数调用的程序例的图。
图2是虚函数调用机构的安装例的图。
图3是与虚函数调用对应的汇编码的图。
图4是与函数的直接调用对应的汇编码的图。
图5是用于说明现有技术的包含虚函数调用的程序例的图。
图6是特开2000-40007号公报记载的技术的变换结果的图。
图7是特开平10-320204号公报记载的技术的变换结果的图。
图8是现有技术中的课题的图。
图9是说明本发明实施方式1的程序变换装置执行的处理的概略的图。
图10是本发明实施方式1的程序变换装置的结构的图。
图11是本发明实施方式1的程序变换步骤的结构图。
图12是类继承关系分析处理(S104)的流程图。
图13是本发明实施方式1的程序存储部101中保存着的程序例的图。
图14是本发明实施方式1的类的继承关系信息113的图。
图15是虚函数重定义分析处理(S105)的流程图。
图16是本发明实施方式1的虚函数重定义信息114的图。
图17是虚函数直接调用分析处理(S107)的流程图。
图18是本发明实施方式1的虚函数直接调用信息115的图。
图19是虚函数调用变换处理(S108)的流程图。
图20是本发明实施方式1的虚函数调用变换步骤中生成的程序的图。
图21是说明本发明实施方式2的程序变换装置执行的处理的概略的图。
图22是本发明实施方式2的类的继承关系信息113的图。
图23是本发明实施方式2的虚函数重定义信息114的图。
图24是本发明实施方式2的虚函数直接调用信息115的图。
图25是本发明实施方式2的虚函数调用变换处理(S108)的流程图。
图26是本发明实施方式2的虚函数调用变换处理中生成的程序的图。
图27是说明本发明实施方式3的程序变换装置执行的处理的概略的图。
图28是本发明实施方式3的程序变换装置的结构的图。
图29是本发明实施方式3的程序变换步骤的结构图。
图30是本发明实施方式3的程序存储部101中保存着的程序例的图。
图31是本发明实施方式3的类的继承关系信息113的图。
图32是本发明实施方式3的虚函数重定义信息114的图。
图33是本发明实施方式3的虚函数直接调用信息115的图。
图34是虚函数调用变换判定处理(S201)的流程图。
图35是本发明实施方式3的可直接调用语句信息116的图。
图36是虚函数定义复制处理(S202)的流程图。
图37是本发明实施方式3的虚函数定义复制步骤中生成的类定义的图。
图38是本发明实施方式3的虚函数定义复制步骤中生成的虚函数表的图。
图39是虚函数调用变换处理(S203)的流程图。
图40是本发明实施方式3的虚函数调用变换步骤中生成的程序的图。
图41是说明本发明实施方式4的程序变换装置执行的处理的概略的图。
图42是本发明实施方式4的类的继承关系信息113的图。
图43是本发明实施方式4的虚函数重定义信息114的图。
图44是本发明实施方式4的虚函数直接调用信息115的图。
图45是本发明实施方式4的虚函数调用变换判定处理(S201)的流程图。
图46是本发明实施方式4的可直接调用语句信息116的图。
图47是本发明实施方式4的复制虚函数信息的图。
图48是本发明实施方式4的虚函数定义复制信息(S202)的流程图。
图49是本发明实施方式4的虚函数定义复制处理中生成的类定义的图。
图50是本发明实施方式4的虚函数定义复制处理中生成的虚函数表的图。
图51是本发明实施方式4的虚函数调用变换处理中生成的程序的图。
图52是说明本发明实施方式5的程序变换装置执行的处理的概略的图。
图53是本发明实施方式5的类的继承关系信息113的图。
图54是本发明实施方式5的虚函数重定义信息114的图。
图55是本发明实施方式5的虚函数直接调用信息115的图。
图56是本发明实施方式5的虚函数调用变换判定处理(S201)的流程图。
图57是本发明实施方式5的可直接调用语句信息116的图。
图58是本发明实施方式5的复制虚函数信息中保存着的信息的图。
图59是本发明实施方式5的虚函数定义复制步骤中生成的类定义的图。
图60是本发明实施方式5的虚函数定义复制步骤中生成的虚函数表的图。
图61是本发明实施方式5的虚函数调用变换步骤中生成的程序的图。
图62是本发明实施方式6的程序变换装置的结构的框图。
图63是本发明实施方式6的程序变换装置执行的处理的流程图。
图64是本发明实施方式7的程序变换装置的结构的框图。
图65是本发明实施方式7的程序变换装置执行的处理的流程图。
具体实施例方式以下,参照附图来说明本发明的程序变换装置的实施方式的一例。
在本实施方式中,在满足以下的条件(1)至条件(4)的情况下,能够确定this指针的类型,所以将虚函数F1的调用变换为直接函数调用。
即,条件(1)在虚函数F2的定义中描述了虚函数F1。
条件(2)this指针调用了虚函数F1。
条件(3)虚函数F2所属的类C1没有派生类,或者在类C1的所有直接派生类中重定义了虚函数F2。
条件(4)类C1的派生类的对象不直接调用虚函数F2。
图9是说明实施方式1的程序变换装置根据上述4个条件执行的处理的概略的图。即,考虑给出了图9(a)所示的类的定义、而且给出了图9(b)所示的程序的情况。
在设虚函数g为虚函数F1、设虚函数f为虚函数F2的情况下,图9(b)的语句“this->g()”满足条件(1)及条件(2)。即,在虚函数F2(虚函数f)的定义中描述了虚函数F1(虚函数g),所以满足条件(1)。此外,this指针调用了虚函数F1(虚函数g),所以满足条件(2)。
此外,考虑条件(3)。如图9(b)所示,虚函数F2(虚函数 f)所属的类C1是类A。因此,如图9(a)所示,在类C1(类A)的所有直接派生类(即类B)中重定义了虚函数F2(虚函数 f)。因此,满足条件(3)。
再者,考虑条件(4)。在程序中不存在A∷f(void)的直接调用。因此,类C1(类A)的派生类(类B、C、D)的对象不直接调用虚函数F2(虚函数f)。因此,满足条件(4)。
因此,在这种情况下,能够将图9(b)所示的虚函数g的调用如图9(c)所示变换为类A的虚函数g的直接调用。
图10是本发明实施方式1的程序变换装置100的结构的图。程序变换装置100是接受用面向对象语言--C++语言描述的程序、输出目标程序的装置,包括程序存储部101、输入部102、语法分析部103、类继承关系分析部104、虚函数重定义分析部105、分析信息存储部106、虚函数直接调用分析部107、虚函数调用变换部108、输出部109、以及生成代码存储部110。
程序存储部101是存储程序变换装置100中作为变换对象的、用面向对象语言--C++语言描述的程序111的存储装置。在程序存储部101中,存储着1个以上的程序111。
输入部102是依次输入程序存储部101中保存着的所有程序111、并输出到语法分析部103的处理部。
语法分析部103是分析从输入部102接收到的程序111的语法、并进行符号表的生成或语法树的生成等、将其分析结果交给类继承关系分析部104的处理部。
类继承关系分析部104是提取程序111中包含的所有类并分析类间的继承关系、生成分析结果——类的继承关系信息的处理部。
虚函数重定义分析部105是分析类的虚函数是否重定义了基类的虚函数、生成分析结果——虚函数重定义信息的处理部。
虚函数直接调用分析部107是分析程序中直接调用的虚函数及启动对象、并生成虚函数直接调用信息的处理部。
分析信息存储部106是存储类继承关系分析部104生成的类的继承关系信息113、虚函数重定义分析部105生成的虚函数重定义信息114及虚函数直接调用分析部107生成的虚函数直接调用信息115的存储装置。
虚函数调用变换部108是参照分析信息存储部106中保存着的类的继承关系信息113、虚函数重定义信息114及虚函数直接调用信息115、判定能否将虚函数调用变换为函数的直接调用、并在能够变换的情况下变换为函数的直接调用的处理部。
输出部109是将虚函数调用变换部108的变换结果作为目标程序112保存到生成代码存储部110中的处理部。
生成代码存储部110是存储目标程序112的存储装置。
图11是本发明实施方式1的程序变换装置100执行的处理的流程图。
输入部102依次输入程序存储部101中保存着的所有程序111,并交给语法分析部103(S102)。
语法分析部103分析从输入部102接收到的程序111的语法,进行符号表的生成和语法树的生成等,并将其分析结果交给类继承关系分析部104(S103)。
类继承关系分析部104提取程序111中包含的所有类并分析类间的继承关系,将分析结果作为类的继承关系信息113保存到分析信息存储部106中(S104)。
虚函数重定义分析部105分析类的虚函数是否重定义了基类的虚函数,将分析结果作为虚函数重定义信息114保存到分析信息存储部106中(S105)。
虚函数直接调用分析部107分析程序111中直接调用的虚函数及启动对象,将分析结果作为虚函数直接调用信息115保存到分析信息存储部106(S107)。
虚函数调用变换部108参照分析信息存储部106中保存着的类的继承关系信息113、虚函数重定义信息114及虚函数直接调用信息115,判定能否将虚函数调用变换为函数的直接调用,在能够变换的情况下变换为函数的直接调用(S108)。
输出部109将虚函数调用变换部108的变换结果作为目标程序112保存到生成代码存储部110中(S109)。
其中,输入步骤S102、语法分析步骤S103、输出步骤S109不是本发明的重点,所以省略详细说明。
接着,参照程序例来说明程序变换装置100执行的处理的细节。
首先,输入部102从程序存储部101输入所有程序111(S102),语法分析部103进行程序111的语法树和符号表的生成等(S103)。
接着,说明类继承关系分析处理(S104)的细节。图12是类继承关系分析处理(S104)的详细流程图。这里,作为输入到程序变换装置100中的程序111,考虑图13所示的程序111。
类继承关系分析处理(S104)包含从a1到a7的步骤。以下按记号的顺序来进行说明。
在步骤a1中,类继承关系分析部104对语法分析部103分析出的所有程序111中包含的所有类C1重复以下的处理。即,对图13的所有程序111中包含的类A、B、C及D重复以下的处理。
在步骤a2中,类继承关系分析部104检查类C1是否已经记录在类的继承关系信息113中。在已经记录的情况下,将处理转移到步骤a7;而在未记录的情况下,将处理转移到步骤a3。在一开始分析图13的类A时步骤a2的判定为“否”,将处理转移到步骤a3。而在其后分析类A时步骤a2的判定为“是”,将处理转移到步骤a7。对类B、C及D也同样。
在步骤a3中,类继承关系分析部104将类C1登录到类的继承关系信息113中。在适用于图13的类A的情况下,向类的继承关系信息113中登录类A。对类B、C及D也同样。
在步骤a4中,类继承关系分析部104检查类C1是否具有基类C2。在类C1没有基类C2的情况下,将处理转移到步骤a5;而在具有基类C2的情况下,将处理转移到步骤a6。在图13的类A的情况下,类A没有基类。因此步骤a4的判定为“否”,将处理转移到步骤a5。而在类B的情况下作为基类而具有类A,所以步骤a4的判定为“是”,将处理转移到步骤a6。类C及D也分别具有基类B,所以步骤a4的判定为“是”,将处理转移到步骤a6。
在步骤a5中,类继承关系分析部104生成类C1的类树,登录到类的继承关系信息113中(a5)。所谓类树,是指表示类的继承关系的图。在图13的类A的情况下,类继承关系分析部104对类A生成类树,向类的继承关系信息113中登录生成的类树。
在步骤a6中,类继承关系分析部104将类C1作为类C2的派生类添加到C2所属的类树中,更新类树。在图13的类B的情况下,将类B作为类A的派生类登录到类A所属的类树中。将类C及类D也同样作为类B的派生类登录到类树中。
在步骤a7中,将处理转移到步骤a1,重复循环的处理。
图14是类继承关系分析部104分析图13的程序111的结果的类的继承关系信息113的图。在类的继承关系信息113中,示出了类B是类A的派生类,类C及D是类B的派生类。
接着,说明虚函数重定义分析处理(S105)的细节。图15是虚函数重定义分析处理(S105)的详细流程图。这里,作为输入到程序变换装置100中的程序111,考虑图13所示的程序111。
虚函数重定义分析处理(S105)包含从b1到b8的步骤。以下按记号的顺序来进行说明。
在步骤b1中,虚函数重定义分析部105对类的继承关系信息113中包含的所有类C1重复以下的处理。即,对图14所示的类A、B、C及D的各个重复以下的处理。
在步骤b2中,虚函数重定义分析部105将类C1的所有虚函数的重定义标记设为OFF(“关”),记录到虚函数重定义信息114中。在类A的情况下,对虚函数f、g及h将重定义标记设为OFF,记录到虚函数重定义信息114中。对类B、C及D也同样进行记录。
在步骤b3中,虚函数重定义分析部105检查类C1是否具有基类C2。在类C1具有基类C2的情况下,将处理转移到步骤b4;而在没有基类C2的情况下,将处理转移到步骤b8。在图14的类的继承关系信息113所示的类A的情况下,类A没有基类,所以步骤b3的判定为“否”,将处理转移到步骤b8。而在类B的情况下作为基类而具有类A,所以步骤b3的判定为“是”,将处理转移到步骤b4。类C及D也分别具有基类B,所以步骤b3的判定为“是”,将处理转移到步骤b4。
在步骤b4中,虚函数重定义分析部105对类C1的所有虚函数F1重复以下的处理。在图13的类B的情况下,对类B的虚函数f、g及h重复以下的处理。
在步骤b5中,虚函数重定义分析部105检查虚函数F1是否覆盖了类C1的基类C2的虚函数。在虚函数F1覆盖了基类C2的虚函数的情况下将处理转移到步骤b6,而在未覆盖的情况下将处理转移到步骤b7。在图13的类B的虚函数f的情况下,覆盖了基类A的虚函数f,所以步骤b5的判定为“是”,将处理转移到步骤b6。而在类B的虚函数h的情况下,未覆盖基类A的虚函数h,所以步骤b5的判定为“否”,将处理转移到步骤b7。
在步骤b6中,虚函数重定义分析部105将虚函数F1的重定义标记设为ON(“开”)。在图13的类B的虚函数f的情况下,将与类B的虚函数f对应的重定义标记设定为ON。
在步骤b7中,虚函数重定义分析部105将处理转移到步骤b4,重复循环的处理。
在步骤b8中,虚函数重定义分析部105将处理转移到步骤b1,重复循环的处理。
图16是示出用虚函数重定义分析部105分析图13的程序111的结果的虚函数重定义信息114的图。虚函数重定义信息114的左栏示出了类名,中栏示出了虚函数名,右栏示出了虚函数是否重定义了。在ON的情况下表示重定义了,而在OFF的情况下表示未重定义。例如,在类B中,示出了虚函数f和g重定义了,而虚函数h未重定义。
接着,说明虚函数直接调用分析处理(S107)的细节。图17是虚函数直接调用分析处理(S107)的详细流程图。这里,作为输入到程序变换装置100中的程序111,考虑图13所示的程序111。
虚函数直接调用分析处理(S107)包含从c1到c4的步骤。以下按记号的顺序来进行说明。
在步骤c1中,虚函数直接调用分析部107对语法分析处理(S103)分析出的所有程序111中的所有语句S1重复以下的处理。在图13中,“this->g();”和“obj_c.g();”等成为处理的对象。
在步骤c2中,虚函数直接调用分析部107检查在语句S1中是否包含虚函数F1的直接调用。在语句S1中包含虚函数F1的直接调用的情况下将处理转移到步骤c3,而在不包含直接调用的情况下将处理转移到步骤c4。在图13的语句“this->g();”中,不直接调用类A的虚函数g,所以步骤c2的判定为“否”,将处理转移到步骤c4。而在语句“obj_c.g();”中,直接调用了类B的虚函数g,所以步骤c2的判定为“是”,将处理转移到步骤c3。
在步骤c3中,虚函数直接调用分析部107将虚函数F1的启动对象的类C1和虚函数F1记录到虚函数直接调用信息115中。在图13的语句“obj_c.g();”中,将启动对象的类C、及“B∷g”记录到虚函数直接调用信息115中。
在步骤c4中,虚函数直接调用分析部107将处理转移到步骤c1,重复循环的处理。
图18是虚函数直接调用分析部107分析图13的程序111的结果的虚函数直接调用信息115的图。
接着,说明虚函数调用变换处理(S108)的细节。图19是虚函数调用变换处理(S108)的详细流程图。这里,作为输入到程序变换装置100中的程序111,考虑图13所示的程序111。
虚函数调用变换处理(S108)包含从d1到d8的步骤。以下按记号的顺序来进行说明。
在步骤d1中,虚函数调用变换部108对程序111中的包含虚函数F1的调用的所有语句S1重复以下的处理。在图13中,“this->g();”、“this->h();”等成为处理对象。
在步骤d2中,虚函数调用变换部108检查语句S1是否被包含在虚函数定义F2中。在语句S1被包含在虚函数定义F2中的情况下,将处理转移到步骤d3;而在不包含在虚函数定义F2中的情况下,将处理转移到步骤d8。图13的语句“this->g();”被包含在虚函数“A∷f”中,所以步骤d2的判定为“是”,将处理转移到步骤d3。同样,语句“this->h();”被包含在虚函数“B∷g”中,所以步骤d2的判定为“是”,将处理转移到步骤d3。此外,语句“obj_c.g();”被包含在函数t中,但是函数t不是虚函数,所以步骤d2的判定为“否”,将处理转移到步骤d8。
在步骤d3中,虚函数调用变换部108检查语句S1是否是this指针的调用。在语句S1是this指针的调用的情况下,将处理转移到步骤d4;而在不是this指针的调用的情况下,将处理转移到步骤d8。在图13的语句“this->g();”及语句“this->h();”中,虚函数g及h的调用是this指针进行的,所以步骤d3的判定为“是”,将处理转移到步骤d4。这里,说明this指针。如上所述,所谓this指针,表示在成员函数的内部指向启动了该成员函数的对象的特别的指针。例如,通过图13的函数t内的成员函数调用“obj_c.g();”,来执行类B的成员函数g。此时,类B的成员函数g的this指针指向启动了成员函数g的对象obj_c。
在步骤d4中,虚函数调用变换部108参照类的继承关系信息113来检查虚函数F2所属的类C1是否具有派生类。在类C1具有派生类的情况下,将处理转移到步骤d5;而在没有派生类的情况下,将处理转移到步骤d7。在图13的虚函数“A∷f”中,参照类的继承关系信息113可知f所属的类A具有派生类,所以步骤d4的判定为“是”,将处理转移到步骤d5。同样,在虚函数“B∷g”中,可知g所属的类B具有派生类,所以步骤d4的判定为“是”。
在步骤d5中,虚函数调用变换部108检查是否在类C1的所有直接派生类C2中重定义了虚函数F2。在所有直接派生类C2中重定义了虚函数F2的情况下,将处理转移到步骤d6;而在未重定义的情况下,将处理转移到步骤d8。在图13中,参照虚函数重定义信息114可知,在类A的所有直接派生类B中重定义了虚函数f,所以步骤d5的判定为“是”,将处理转移到步骤d6。而在类B的直接派生类D中重定义了虚函数g,但是在直接派生类C中未重定义虚函数g,所以步骤d5的判定为“否”,将处理转移到步骤d8。
在步骤d6中,虚函数调用变换部108检查类C1的所有派生类C3的对象是否不直接调用虚函数F2。在不直接调用虚函数F2的情况下,将处理转移到步骤d7;而在直接调用了的情况下,将处理转移到步骤d8。考虑图13的程序111。参照虚函数直接调用信息115可知,类A的所有派生类B、C及D的对象不直接调用虚函数f,所以步骤d6的判定为“是”,将处理转移到步骤d7。
在步骤d7中,虚函数调用变换部108将语句S1变换为函数F1的直接调用。对图13的语句“this->g();”,将虚函数g变换为直接调用,变换为与描述成“this->A∷g();”的情况同等的代码。
在步骤d8中,虚函数调用变换部108将处理转移到步骤d1,重复循环的处理。
图20是虚函数调用变换部108变换图13的程序111的结果所得到的代码的图。在该代码中,直接调用了虚函数A∷g。
如上所述,向本实施方式的程序变换装置100输入了图13所示的程序111的结果,能够将包含虚函数调用的语句“this->g();”变换为函数的直接调用。因此,能够提高执行目标程序112时的执行速度。
其中,在上述实施方式中,类继承关系分析处理(S104)、虚函数重定义分析处理(S105)、虚函数直接调用分析处理(S107)、虚函数调用变换处理(S108)分别只执行了一次,但是也可以在必要时重复多次。
此外,在虚函数及虚函数所属的类满足特定条件的情况下,能够在该虚函数定义中确定this指针的类型,但是在进行类对象的生成处理的构造函数、或进行删除处理的析构函数中,this指针的类型能够确定为该构造函数或析构函数所属的类。因此,也可以将构造函数或析构函数中描述的this指针的虚函数调用变换为函数的直接调用。
此外,在能够根据程序的性质或执行结果来清楚地确定this指针的类型的情况下,也可以根据pragma指令、选项指定及程序的执行历史信息等,将虚函数调用变换为函数的直接调用。
在本实施方式中,虚函数调用变换部108执行的处理与实施方式1不同。
在本实施方式中,在满足以下的条件(1)至条件(4)的情况下,能够确定this指针的类型,所以将虚函数F1的调用变换为直接函数调用。
即,(1)在虚函数F2的定义中描述了虚函数F1。
(2)this指针调用了虚函数F1。
(3)虚函数F2所属的类C1没有派生类,或者在重定义了虚函数F1的派生类C2中也重定义了虚函数F2。
(4)类C2以外的派生类的对象不直接调用虚函数F2。
图21是说明实施方式2的程序变换装置根据上述4个条件执行的处理的概略的图。即,考虑给出了图21(a)所示的类的定义、而且给出了图21(b)所示的程序的情况。
在设虚函数g为虚函数F1、设虚函数f为虚函数F2的情况下,图21(b)的语句“this->g()”满足条件(1)及条件(2)。即,在虚函数F2(虚函数f)的定义中描述了虚函数F1(虚函数g),所以满足条件(1)。此外,this指针调用了虚函数F1(虚函数g),所以满足条件(2)。
此外,考虑条件(3)。如图21(a)所示,在重定义了虚函数F1(虚函数g)的派生类C2(类C)中也重定义了虚函数F2(虚函数f)。因此,满足条件(3)。
再者,考虑条件(4)。在程序中没有类B以外的A∷f(void)的直接调用。因此,类C2(类C)以外的派生类(类B、D)的对象不直接调用虚函数F2(虚函数f)。因此,满足条件(4)。
因此,在这种情况下,能够将图21(b)所示的虚函数g的调用,如图21(c)所示变换为类A的虚函数g的直接调用。
以下,参照程序例来说明实施方式2的程序变换装置100执行的处理。
如图11所示,首先,输入部102从程序存储部101输入所有程序111(S102),语法分析部103进行程序的语法树或符号表的生成等(S103)。
接着,类继承关系分析部104分析程序111中包含的类及类间的继承关系,将分析结果记录到类的继承关系信息113中(S104)。类继承关系分析处理(S104)与图12所示的相同。类继承关系分析处理(S104)分析图13的程序111的结果——类的继承关系信息113示于图22。
接着,虚函数重定义分析部105分析基类的虚函数的重定义状态,将分析结果记录到虚函数重定义信息114中(S105)。虚函数重定义分析处理(S105)与图15所示的相同。虚函数重定义分析处理(S105)分析图13的程序111的结果——虚函数重定义信息114示于图23。
接着,虚函数直接调用分析部107分析要直接调用的虚函数,并将分析结果记录到虚函数直接调用信息115中(S107)。虚函数直接调用分析处理(S107)与图17所示的相同。虚函数直接调用分析处理(S107)分析图13的程序111的结果——虚函数直接调用信息115示于图24。
接着,参照图25来说明虚函数调用变换部108执行的处理,以将该处理适用于图13所示的程序111的情况为例。
虚函数调用变换部108执行的虚函数调用变换处理(S108)包含从e1到e8的步骤。以下按记号的顺序来进行说明。
在步骤e1中,虚函数调用变换部108对程序中的包含虚函数调用的所有语句S1重复以下的处理。在图13中处理“this->g();”、“this->h();”等。
在步骤e2中,虚函数调用变换部108检查语句S1是否被包含在虚函数定义F2中。在语句S1被包含在虚函数定义F2中的情况下,将处理转移到步骤e3;而在不包含在虚函数定义F2中的情况下,将处理转移到步骤e8。图13的语句“this->g();”被包含在虚函数“A∷f”中,所以步骤e2的判定为“是”,将处理转移到步骤e3。同样,语句“this->h();”被包含在虚函数“B∷g”中,所以步骤e2的判定为“是”,将处理转移到步骤e3。而语句“obj_c.g();”被包含在函数t中,函数t不是虚函数,所以步骤e2的判定为“否”,将处理转移到步骤e8。
在步骤e3中,虚函数调用变换部108检查语句S1是否是this指针的调用。在语句S1是this指针的调用的情况下,将处理转移到步骤e4;而在不是对×this指针的调用的情况下,将处理转移到步骤e8。在图13的语句“this->g();”及语句“this->h();”中,虚函数g及h的调用是this指针进行的,所以步骤e3的判定为“是”,将处理转移到步骤e4。
在步骤e4中,虚函数调用变换部108参照类的继承关系信息113,来检查虚函数F2所属的类C1是否具有派生类。在类C1具有派生类的情况下,将处理转移到步骤e5;而在没有派生类的情况下,将处理转移到步骤e7。在图13的虚函数“A∷f”中,参照类的继承关系信息113可知,f所属的类A具有派生类,所以步骤e4的判定为“是”,将处理转移到步骤e5。同样,在虚函数“B∷g”中,可知g所属的类B具有派生类,所以步骤e4的判定为“是”。
在步骤e5中,虚函数调用变换部108检查是否在类C1的派生类中的、重定义了虚函数F1的派生类C2中重定义了虚函数F2。在重定义了虚函数F2的情况下,将处理转移到步骤e6;而在未重定义的情况下,将处理转移到步骤e8。在图13中,参照虚函数重定义信息114可知,重定义了虚函数“A∷g”的类A的派生类只有类B,同时可知在类B中重定义了虚函数f。因此,步骤e5的判定为“是”,将处理转移到步骤e6。而重定义了虚函数“A∷h”的类B的派生类只有类D,同时在类D中重定义了虚函数g,所以步骤e5的判定为“是”。
其中,一旦在派生类C2中重定义了虚函数F1,则在步骤e5的处理中无需将继承了C2的派生类作为搜索对象。这是因为,即使未在继承了C2的派生类中重定义虚函数F1,从C2的派生类调用的F1也是类C2的F1,类C1的虚函数F1必定处于重定义了的状态。
在步骤e6中,虚函数调用变换部108检查类C2及C2的所有派生类的对象是否不直接调用虚函数F2。在不直接调用虚函数F2的情况下,将处理转移到步骤e7;而在直接调用了的情况下,将处理转移到步骤e8。在图13中,参照虚函数直接调用信息115可知,类B及类B的派生类——类C、D的对象不直接调用虚函数f,所以步骤e6的判定为“是”,将处理转移到步骤e7。同样,只有类C的对象直接调用虚函数g,类D的对象不直接调用,所以步骤e6的判定为“是”。
在步骤e7中,虚函数调用变换部108将语句S1变换为函数F1的直接调用。对图13的语句“this->g();”,将虚函数g变换为直接调用,变换为与描述成“this->A∷g();”的情况同等的代码。同样,将“this->h();”变换为与描述成“this->B∷h();”的情况同等的代码。
在步骤e8中,虚函数调用变换部108将处理转移到步骤e1,重复循环的处理。
虚函数调用变换部108变换图13的程序111的结果所得到的代码示于图26。在该代码中,直接调用了虚函数A∷g()和虚函数B∷h()。
如上所述,向本实施方式的程序变换装置100输入了图13所示的程序111的结果是,能够将包含虚函数调用的语句“this->g();”及语句“this->h();”变换为函数的直接调用。因此,能够提高执行目标程序112时的执行速度。
其中,在上述实施方式中,类继承关系分析处理(S104)、虚函数重定义分析处理(S105)、虚函数直接调用分析处理(S107)、虚函数调用变换处理(S108)分别只执行了一次,但是也可以在必要时重复多次。
此外,在虚函数及虚函数所属的类满足特定的条件的情况下,能够在该虚函数定义中确定this指针的类型,但是在进行类对象的生成处理的构造函数、或进行删除处理的析构函数中,this指针的类型能够确定为该构造函数或析构函数所属的类。因此,也可以将构造函数或析构函数中描述的this指针的虚函数调用变换为函数的直接调用。
此外,在能够根据程序的性质或执行结果来清楚地确定this指针的类型的情况下,也可以根据pragma指令、选项指定及程序的执行历史信息等,将虚函数调用变换为函数的直接调用。
在本实施方式中,在满足以下的条件(1)至条件(4)的情况下,能够确定this指针的类型,所以将虚函数F1的调用变换为直接函数调用。
即,(1)在虚函数F2的定义中描述了虚函数F1。
(2)this指针调用了虚函数F1。
(3)虚函数F2所属的类C1的派生类的对象不直接调用虚函数F2。
(4)复制所有不在派生类中重定义的虚函数。
图27是说明实施方式3的程序变换装置根据上述4个条件执行的处理的概略的图。即,考虑给出了图27(a)所示的类的定义、和图27(c)所示的程序的情况。
在设虚函数g为虚函数F1、设虚函数f为虚函数F2的情况下,图27(c)的语句“this->g()”满足条件(1)及条件(2)。即,在虚函数F2(虚函数f)的定义中描述了虚函数F1(虚函数g),所以满足条件(1)。此外,this指针调用了虚函数F1(虚函数g),所以满足条件(2)。
此外,考虑条件(3)。在程序中不存在A∷f(void)的直接调用。因此,虚函数F2(虚函数f)所属的类C1(类A)的派生类(类B、C、D)的对象不直接调用虚函数F2(虚函数f)。因此,满足条件(3)。
再者,复制所有未在派生类(类B、C、D)中重定义的虚函数。即,如图27(b)所示,在类B中复制虚函数f及虚函数g,并在类D中复制虚函数g。由此,满足条件(4)。
因此,在这种情况下,能够将图27(c)所示的虚函数g的调用如图27(d)所示变换为类A的虚函数g的直接调用。
图28是本发明实施方式3的程序变换装置200的结构的图。程序变换装置200包括输入部102、语法分析部103、类继承关系分析部104、虚函数重定义分析部105、分析信息存储部206、虚函数直接调用分析部107、虚函数调用变换判定部201、虚函数定义复制部202、虚函数调用变换部203、以及输出部109构成。
其中,程序存储部101、输入部102、语法分析部103、类继承关系分析部104、虚函数重定义分析部105、虚函数直接调用分析部107、输出部109及生成代码存储部110进行与图10所示的实施方式1的程序变换装置100的各部同样的处理。因此,这里不重复其详细说明。
虚函数调用变换判定部201参照分析信息存储部106中保存的类的继承关系信息113及虚函数直接调用信息115,判定能否将虚函数调用变换为函数的直接调用,将与包含能够变换为直接调用的虚函数调用的语句有关的信息(以下称为“可直接调用语句信息”。)保存到分析信息存储部106中。
虚函数定义复制部202参照分析信息存储部106中保存的类的继承关系信息113及虚函数重定义信息114,复制未在派生类中重定义的虚函数,变换为在派生类中重定义了的状态。
虚函数调用变换部203将分析信息存储部106中保存的可直接调用语句信息116中包含的语句,变换为函数的直接调用。
分析信息存储部106是存储各步骤中分析出的信息的存储装置。即,分析信息存储部106是存储类的继承关系信息113、虚函数重定义信息114、虚函数直接调用信息115及可直接调用语句信息116的存储装置。
图29是本实施方式的程序变换装置200执行的处理的流程图。
其中,输入处理(S102)、语法分析处理(S103)、类继承关系分析处理(S104)、虚函数重定义分析处理(S105)、虚函数直接调用分析处理(S107)及输出处理(S109),与图11所示的程序变换装置100执行的对应的处理相同。因此,这里不重复其详细说明。
在虚函数调用变换判定处理(S201)中,虚函数调用变换判定部201参照分析信息存储部106中保存的类的继承关系信息113及虚函数直接调用信息115,判定能否将虚函数调用变换为函数的直接调用,并将可直接调用语句信息116保存到分析信息存储部206中。
在虚函数定义复制处理(S202)中,虚函数定义复制部202参照分析信息存储部106中保存的类的继承关系信息113及虚函数重定义信息114,复制未在派生类中重定义的虚函数,变换为在派生类中重定义了的状态。
在虚函数调用变换处理(S203)中,虚函数调用变换部203将分析信息存储部106中保存的可直接调用语句信息116中包含的语句,变换为函数的直接调用。
接着,参照图30所示的程序例111来说明程序变换装置200执行的处理的细节。
首先,输入部102从程序存储部101输入所有程序111(S102),语法分析部103进行程序111的语法树和符号表的生成等(S103)。
接着,类继承关系分析部104分析程序111中包含的类及类间的继承关系,将分析结果记录到类的继承关系信息113中(S104)。类继承关系分析处理(S104)与图12所示的相同。类继承关系分析处理(S104)分析图30的程序111的结果——类的继承关系信息113示于图31。
接着,虚函数重定义分析部105分析基类的虚函数的重定义状态,将分析结果记录到虚函数重定义信息114中(S105)。虚函数重定义分析处理(S105)与图15所示的相同。虚函数重定义分析处理(S105)分析图30的程序111的结果——虚函数重定义信息114示于图32。
接着,虚函数直接调用分析部107分析直接调用的虚函数,将分析结果记录到虚函数直接调用信息115中(S107)。虚函数直接调用分析处理(S107)与图17所示的相同。虚函数直接调用分析处理(S107)分析图30的程序111的结果——虚函数直接调用信息115示于图33。
接着,参照图34来说明虚函数调用变换判定部201执行的处理,以将该处理适用于图30所示的程序111的情况为例。
虚函数调用变换判定部201执行的虚函数调用变换判定处理(S201)包含从f1到f6的步骤。以下按记号的顺序来进行说明。
在步骤f1中,虚函数调用变换判定部201对程序111中的包含虚函数调用的所有语句S1重复以下的处理。在图30中处理“this->g();”、“this->h();”等。
在步骤f2中,虚函数调用变换判定部201检查语句S1是否被包含在虚函数定义F2中。在语句S1被包含在虚函数定义F2中的情况下,将处理转移到步骤f3,而在不包含在虚函数定义F2中的情况下,将处理转移到步骤f6。图30的语句“this->g();”被包含在虚函数“A∷f”中,所以步骤f2的判定为“是”,将处理转移到步骤f3。同样,语句“this->h();”被包含在虚函数“B∷g”中,所以步骤f2的判定为“是”,将处理转移到步骤f3。而语句“obj_c.g();”被包含在函数t中,函数t不是虚函数,所以步骤f2的判定为“否”,将处理转移到步骤f6。
在步骤f3中,虚函数调用变换判定部201检查语句S1是否是this指针的调用。在语句S1是this指针的调用的情况下,将处理转移到步骤f4,而在不是对×this指针的调用的情况下,将处理转移到步骤f6。在图30的语句“this->g();”及语句“this->h();”中,this指针进行虚函数g及h的调用,所以步骤f3的判定为“是”,将处理转移到步骤f4。
在步骤f4中,虚函数调用变换判定部201检查虚函数F2所属的类C1的所有派生类C3的对象是否不直接调用虚函数F2。在未直接调用虚函数F2的情况下,将处理转移到步骤f5,而在直接调用了的情况下,将处理转移到步骤f6。在图30中,参照虚函数直接调用信息115可知,类A的所有派生类B、C及D的对象不直接调用虚函数“A∷f”,所以步骤f4的判定为“是”,将处理转移到步骤f5。而检查虚函数“B∷g”的直接调用可知,类C的对象直接调用了虚函数“B∷g”,所以步骤f4的判定为“否”,将处理转移到步骤f6。
在步骤f5中,虚函数调用变换判定部201将语句S1添加到可直接调用语句信息116中。在图30中,将语句“this->g();”添加到可直接调用语句信息116中。
在步骤f6中,虚函数调用变换判定部201将处理转移到步骤f1,重复循环的处理。
虚函数调用变换判定部201通过虚函数调用变换判定处理(S201)分析图30的程序111的结果——可直接调用语句信息116示于图35。
接着,参照图36来说明虚函数定义复制部202执行的虚函数定义复制处理(S202),以将该处理适用于图30所示的程序111的情况为例。
虚函数定义复制部202执行的虚函数定义复制处理(S202)包含从g1到g7的步骤。以下按记号的顺序来进行说明。
在步骤g1中,虚函数定义复制部202检查可直接调用语句信息116是否是空集。在是空集的情况下,结束虚函数定义复制处理(S202),而在不是空集的情况下,将处理转移到步骤g2。在图30的程序111中,可直接调用语句信息116不是空集,所以步骤g1的判定为“否”,将处理转移到步骤g2。
在步骤g2中,虚函数定义复制部202对所有程序111中包含的所有类C1重复以下的处理。即,对图30的所有程序111中包含的类A、B、C及D重复。
在步骤g3中,虚函数定义复制部202检查类C1是否具有基类C2。在类C1具有基类C2的情况下,将处理转移到步骤g4;而在没有基类C2的情况下将处理转移到步骤g7。在图30的类A的情况下,类A没有基类,所以步骤g3的判定为“否”,将处理转移到步骤g7。而在类B的情况下,作为基类而具有类A,所以步骤g3的判定为“是”,将处理转移到步骤g4。类C及D也分别具有基类B,所以步骤g3的判定为“是”,将处理转移到步骤g4。
在步骤g4中,虚函数定义复制部202检查在类C2的虚函数中是否存在未在类C1中重定义的函数F1。在存在未在类C1中重定义的函数F1的情况下,将处理转移到步骤g5;而在不存在的情况下,将处理转移到步骤g7。在图30的类B的情况下,参照虚函数重定义信息114可知,未重定义基类A的虚函数f及h,所以步骤g4的判定为“是”,将处理转移到步骤g5。同样,在类B、C及D的情况下也分别有未重定义基类的虚函数的情况,所以步骤g4的判定为“是”。
在步骤g5中,虚函数定义复制部202复制类C2的虚函数F1来生成虚函数F2,并以在类C1中重定义了的形式变换类C1的定义。在图30的类B的情况下,复制基类A的虚函数f及h来生成f’及h’,并以在类B中重定义了的形式变换类B的定义。在类C及D的情况下,也同样复制基类B的虚函数,并变换类的定义。
在步骤g6中,虚函数定义复制部202将类C1的虚函数表的函数F1一栏置换为函数F2。在图30的类B的情况下,类B的虚函数表的函数f及h一栏分别是“A∷f(void)”、“A∷h(void)”,改写为复制的函数“B∷f’(void)”“B∷h’(void)”。同样,将类C、类D的虚函数表一栏改写为复制的函数。
在步骤g7中,虚函数定义复制部202将处理转移到步骤g2,重复循环的处理。
虚函数定义复制处理(S202)变换图30的程序111的结果的程序及各类的虚函数表分别示于图37及图38。
接着,参照图39来说明虚函数调用变换部203执行的虚函数调用变换处理(S203),以将该处理适用于图30所示的程序111的情况为例。
虚函数调用变换部203执行的虚函数调用变换处理(S203)包含从h1到h3的步骤。以下按记号的顺序来进行说明。
在步骤h1中,虚函数调用变换部203对可直接调用语句信息116中包含的所有语句S1重复以下的处理。在图30的程序111中,对可直接调用语句信息116中包含的语句“this->g()”执行以下的处理。
在步骤h2中,虚函数调用变换部203将语句S1中包含的虚函数调用变换为函数的直接调用。在图30中,将语句“this->g()”的虚函数调用变换为函数的直接调用,变换为与描述成“this->A∷g();”的情况同等的代码。
在步骤h3中,虚函数调用变换部203将处理转移到步骤h1,重复循环的处理。
虚函数调用变换处理(S203)变换图30的程序111的结果所得到的代码示于图40。
如上所述,向本实施方式的程序变换装置200适用了图30所示的程序111的结果是,能够将包含虚函数调用的语句“this->g();”变换为函数的直接调用。因此,能够提高执行目标程序112时的执行速度。
其中,在上述实施方式中,类继承关系分析处理(S104)、虚函数重定义分析处理(S105)、虚函数直接调用分析处理(S107)、虚函数调用变换判定处理(S201)、虚函数定义复制处理(S202)、虚函数调用变换处理(S203)分别只执行了一次,但是也可以在必要时重复多次。
此外,在虚函数及虚函数所属的类满足特定的条件的情况下,能够在该虚函数定义中确定this指针的类型,但是在进行类对象的生成处理的构造函数、或进行删除处理的析构函数中,this指针的类型能够确定为该构造函数或析构函数所属的类。因此,也可以将构造函数或析构函数中描述的this指针的虚函数调用变换为函数的直接调用。
此外,在能够根据程序的性质或执行结果来清楚地确定this指针的类型的情况下,也可以根据pragma指令、选项指定及程序的执行历史信息等,将虚函数调用变换为函数的直接调用。
在本实施方式中,虚函数调用变换判定部201及虚函数定义复制部202执行的处理与实施方式3不同。后面将描述虚函数调用变换判定部201及虚函数定义复制部202分别执行的虚函数调用变换判定处理(S201)及虚函数定义复制处理(S202)。
此外,分析信息存储部206还存储复制虚函数信息(未图示)。后面将描述复制虚函数信息。
在本实施方式中,在满足以下的条件(1)至条件(4)的情况下,能够确定this指针的类型,所以将虚函数F1的调用变换为直接函数调用。
即,(1)在虚函数F2的定义中描述了虚函数F1。
(2)this指针调用了虚函数F1。
(3)虚函数F2所属的类C1以外的派生类的对象不直接调用虚函数F2。
(4)复制所有未在类C1的直接派生类中重定义的虚函数F2。
图41是说明实施方式4的程序变换装置根据上述4个条件执行的处理的概略的图。即,考虑给出了图41(a)所示的类的定义、和图41(c)所示的程序的情况。
在设虚函数g为虚函数F1、设虚函数f为虚函数F2的情况下,图41(c)的语句“this->g()”满足条件(1)及条件(2)。即,在虚函数F2(虚函数f)的定义中描述了虚函数F1(虚函数g),所以满足条件(1)。此外,this指针调用了虚函数F1(虚函数g),所以满足条件(2)。
此外,考虑条件(3)。在程序中不存在A∷f(void)的直接调用。因此,虚函数F2(虚函数g)所属的类C1(类A)以外的派生类(类B、C、D)的对象不直接调用虚函数F2(虚函数g)。因此,满足条件(3)。
再者,复制所有未在类C1(类A)的直接派生类(类B)中重定义的虚函数F2(虚函数f)。即,如图41(b)所示,在类B中复制虚函数f。由此,满足条件(4)。
因此,在这种情况下,如图41(d)所示,能够将图41(c)所示的虚函数g的调用变换为类A的虚函数g的直接调用。
以下,参照程序例来说明实施方式4的程序变换装置200执行的处理。
首先,输入部102从程序存储部101输入所有程序111(S102),语法分析部103进行程序的语法树和符号表的生成等(S103)。
接着,类继承关系分析部104分析程序中包含的类及类间的继承关系,并将分析结果记录到类的继承关系信息113中(S104)。类继承关系分析处理(S104)与图12所示的相同。类继承关系分析处理(S104)分析图30的程序111的结果——类的继承关系信息113示于图42。
接着,虚函数重定义分析部105分析基类的虚函数的重定义状态,将分析结果记录到虚函数重定义信息114中(S105)。虚函数重定义分析处理(S105)与图15所示的相同。虚函数重定义分析处理(S105)分析图30的程序111的结果——虚函数重定义信息114示于图43。
接着,虚函数直接调用分析部107分析直接调用的虚函数,并将分析结果记录到虚函数直接调用信息115中(S107)。虚函数直接调用分析处理(S107)与图17所示的相同。虚函数直接调用分析处理(S107)分析图30的程序111的结果——虚函数直接调用信息115示于图44。
接着,参照图45来说明虚函数调用变换判定部201执行的虚函数调用变换处理(S201)的细节,以将该处理适用于图30所示的程序111的情况为例。
虚函数调用变换判定处理(S201)包含从j1到j7的步骤。以下按记号的顺序来进行说明。
在步骤j1中,虚函数调用变换判定部201对程序111中的包含虚函数调用的所有语句S1重复以下的处理。在图30中,“this->g();”、“this->h();”等成为处理对象。
在步骤j2中,虚函数调用变换判定部201检查语句S1是否被包含在虚函数定义F2中。在语句S1被包含在虚函数定义F2中的情况下将处理转移到步骤j3,而在不包含在虚函数定义F2中的情况下将处理转移到步骤j7。图30的语句“this->g();”被包含在虚函数A∷f中,所以步骤j2的判定为“是”,将处理转移到步骤j3。同样,语句“this->h();”被包含在虚函数“B∷g”中,所以步骤j2的判定为“是”,将处理转移到步骤j3。而语句“obj_c.g();”被包含在函数t中,函数t不是虚函数,所以步骤j2的判定为“否”,将处理转移到步骤j7。
在步骤j3中,虚函数调用变换判定部201检查语句S1是否是this指针的调用。在语句S1是this指针的调用的情况下,将处理转移到步骤j4;而在不是this指针的调用的情况下,将处理转移到步骤j7。在图30的语句“this->g();”及语句“this->h();”中,虚函数g及h的调用是this指针进行的,所以步骤j3的判定为“是”,将处理转移到步骤j4。
在步骤j4中,虚函数调用变换判定部201检查虚函数F2所属的类C1的所有派生类C3的对象是否不直接调用虚函数F2。在不直接调用虚函数F2的情况下将处理转移到步骤j5,而在直接调用了的情况下,将处理转移到步骤j7。在图30中,参照虚函数直接调用信息115可知,类A的所有派生类B、C及D的对象不直接调用虚函数“A∷f”,所以步骤j4的判定为“是”,将处理转移到步骤j5。而检查虚函数“B∷g”的直接调用可知,类C的对象直接调用了虚函数“B∷g”,所以步骤j4的判定为“否”,将处理转移到步骤j7。
在步骤j5中,虚函数调用变换判定部201将语句S1添加到可直接调用语句信息116中。在图30中,将语句“this->g();”添加到可直接调用语句信息116中。
在步骤j6中,虚函数调用变换判定部201将类C1的所有直接基类和虚函数F2的对子P1作为复制虚函数信息而添加到分析信息存储部206中。在图30中,类A的直接基类只有类B,所以将类B和A∷f的对子添加到复制虚函数信息中。在直接基类有多个的情况下,将多个对子添加到复制虚函数信息中。
在步骤j7中,虚函数调用变换判定部201将处理转移到步骤j1,重复循环的处理。
虚函数调用变换判定处理(S201)分析图30的程序111的结果——可直接调用语句信息116及复制虚函数信息分别示于图46及图47。
接着,参照图48来说明虚函数定义复制部202执行的虚函数定义复制处理(S202),以将该处理适用于图30所示的程序111的情况为例。
虚函数定义复制处理(S202)包含从k1到k6的步骤。以下按记号的顺序来进行说明。
在步骤k1中,虚函数定义复制部202检查可直接调用语句信息116是否是空集。在是空集的情况下,结束虚函数定义复制处理(S202),而在不是空集的情况下,将处理转移到步骤k2。在图30的程序111中,可直接调用语句信息116不是空集,所以步骤k1的判定为“否”,将处理转移到步骤k2。
在步骤k2中,虚函数定义复制部202对复制虚函数信息的所有对子P1重复以下的处理。在图30中,对类B和虚函数“A∷f”的对子重复以下的处理。
在步骤k3中,虚函数定义复制部202检查是否在对子P1的类C1中重定义了对子P1的虚函数F1。在未重定义的情况下将处理转移到步骤k4,而在重定义了的情况下将处理转移到步骤k6。在图30的对子P1的类B的情况下,参照虚函数重定义信息114可知,未在类B中重定义对子P1的虚函数“A∷f”,所以步骤k3的判定为“是”,将处理转移到步骤k4。
在步骤k4中,虚函数定义复制部202复制虚函数F1来生成虚函数F2,并以在类C1中重定义了的形式变换类C1的定义。在图30的类B的情况下,复制虚函数“A∷f”来生成f’,并以在类B中重定义了的形式变换类B的定义。
在步骤k5中,虚函数定义复制部202将登录有所有类C2的虚函数表的函数F1的一栏置换为函数F2。在图30中,将类B、C及D的虚函数表的函数f“A∷f(void)”一栏改写为复制的函数“B∷f’(void)”。
在步骤k6中,虚函数定义复制部202将处理转移到步骤k2,重复循环的处理。
通过虚函数定义复制部202执行的虚函数定义复制处理(S202)而变换图30的程序111的结果——程序及各类的虚函数表分别示于图49及图50。
接着,虚函数调用变换部203将虚函数调用变换为函数的直接调用(S203)。虚函数调用变换处理(S203)与图39所示的相同。虚函数调用变换处理(S203)变换图30的程序111的结果所得到的代码示于图51。
如上所述,向本实施方式的程序变换装置200输入了图30所示的程序的结果是,能够将包含虚函数调用的语句“this->g();”变换为函数的直接调用。因此,能够提高执行目标程序112时的执行速度。此外,程序变换装置200复制所需最低限度的虚函数。因此,也能够减少目标程序112的代码长度的增加。
其中,在上述实施方式中,类继承关系分析处理(S104)、虚函数重定义分析处理(S105)、虚函数直接调用分析处理(S107)、虚函数调用变换判定处理(S201)、虚函数定义复制处理(S202)、虚函数调用变换处理(S203)分别只执行一次,但是也可以在必要时重复多次。
此外,在虚函数及虚函数所属的类满足特定的条件的情况下,能够在该虚函数定义中确定this指针的类型,但是在进行类对象的生成处理的构造函数、或进行删除处理的析构函数中,this指针的类型能够确定为该构造函数或析构函数所属的类。因此,也可以将构造函数或析构函数中描述的this指针的虚函数调用变换为函数的直接调用。
此外,在能够根据程序的性质或执行结果来清楚地确定this指针的类型的情况下,也可以根据pragma指令、选项指定及程序的执行历史信息等,将虚函数调用变换为函数的直接调用。
本实施方式5的程序变换装置200的虚函数调用变换判定部201进行的处理与实施方式4不同。后面将描述虚函数调用变换判定部201执行的虚函数调用判定处理(S201)。
在本实施方式中,在满足以下的条件(1)至条件(4)的情况下,能够确定this指针的类型,所以将虚函数F1的调用变换为直接函数调用。
即,(1)在虚函数F2的定义中描述了虚函数F1。
(2)this指针调用了虚函数F1。
(3)在虚函数F2所属的类C1的派生类中,未重定义虚函数F1的类C2以外的类的对象不直接调用虚函数F2。
(4)复制所有未在类C2以外的派生类中重定义的虚函数F2。
图52是说明实施方式5的程序变换装置根据上述4个条件执行的处理的概略的图。即,考虑给出了图52(a)所示的类的定义、和图52(c)所示的程序的情况。
在设虚函数g为虚函数F1、设虚函数f为虚函数F2的情况下,图52(c)的语句“this->g()”满足条件(1)及条件(2)。即,在虚函数F2(虚函数f)的定义中描述了虚函数F1(虚函数g),所以满足条件(1)。此外,this指针调用了虚函数F1(虚函数g),所以满足条件(2)。
此外,考虑条件(3)。在程序中不存在类B以外的A∷f(void)的直接调用。因此,在虚函数F2(虚函数f)所属的类C1(类A)的派生类(类B、C、D)中、未重定义虚函数F1(虚函数g)的类C2(类B、D)以外的类(类C)的对象不直接调用虚函数F2(虚函数f)。因此,满足条件(3)。
再者,复制所有未在类C2(类B、D)以外的派生类(类C)中重定义的虚函数F2(虚函数f)。即,如图52(b)所示,在类C中复制虚函数f。由此,满足条件(4)。
因此,在这种情况下,如图52(d)所示,能够将图52(c)所示的虚函数g的调用变换为类A的虚函数g的直接调用。
以下,参照程序例来说明实施方式5的程序变换装置200执行的处理。
首先,输入部102从程序存储部101输入所有程序111(S102),语法分析部103进行程序的语法树和符号表的生成等(S103)。
接着,类继承关系分析部104分析程序中包含的类及类间的继承关系,将分析结果记录到类的继承关系信息113中(S104)。类继承关系分析处理(S104)的处理与图12所示的相同。类继承关系分析处理(S104)分析图30的程序111的结果——类的继承关系信息113示于图53。
接着,虚函数重定义分析部105分析基类的虚函数的重定义状态,将分析结果记录到虚函数重定义信息114中(S105)。虚函数重定义分析处理(S105)的处理与图15所示的相同。虚函数重定义分析处理(S105)分析图30的程序111的结果——虚函数重定义信息114示于图54。
接着,虚函数直接调用分析部107分析直接调用的虚函数,并将分析结果记录到虚函数直接调用信息115中(S107)。虚函数直接调用分析处理(S107)与图17所示的相同。虚函数直接调用分析处理(S107)分析图30的程序111的结果——虚函数直接调用信息115示于图55。
接着,参照图56来说明虚函数调用变换判定部201执行的虚函数调用变换处理(S201)的细节,以将该处理适用于图30所示的程序111的情况为例。
虚函数调用变换判定部201执行的虚函数调用变换判定处理(S201)包含从m1到m7的步骤。以下按记号的顺序来进行说明。
在步骤m1中,虚函数调用变换判定部201对程序111中的包含虚函数调用的所有语句S1重复以下的处理。在图30中处理“this->g();”、“this->h();”等。
在步骤m2中,虚函数调用变换判定部201检查语句S1是否被包含在虚函数定义F2中。在语句S1被包含在虚函数定义F2中的情况下,将处理转移到步骤m3;而在不包含在虚函数定义F2中的情况下,将处理转移到步骤m8。图30的语句“this->g();”被包含在虚函数A∷f中,所以步骤m2的判定为“是”,将处理转移到步骤m3。同样,语句“this->h();”被包含在虚函数“B∷g”中,所以步骤m2的判定为“是”,将处理转移到步骤m3。而语句“obj_c.g();”被包含在函数t中,函数t不是虚函数,所以步骤m2的判定为“否”,将处理转移到步骤m8。
在步骤m3中,虚函数调用变换判定部201检查语句S1是否是this指针的调用。在语句S1是this指针的调用的情况下,将处理转移到步骤m4,而在不是this指针的调用的情况下,将处理转移到步骤m8。在图30的语句“this->g();”及语句“this->h();”中,this指针进行虚函数g及h的调用。因此,步骤m3的判定为“是”,将处理转移到步骤m4。
在步骤m4中,虚函数调用变换判定部201检查在虚函数F2所属的类C1的所有派生类中是否有重定义F1的类C2。在有重定义F1的类C2的情况下,将处理转移到步骤m5;而在没有的情况下,将处理转移到步骤m6。在图30中,参照虚函数重定义信息114可知,在虚函数“A∷f”所属的类A的派生类B、C及D中重定义虚函数g的类是类B。因此,步骤m4的判定为“是”,将处理转移到步骤m5。此外,在虚函数“B∷g”所属的类B的派生类C及D中重定义虚函数h的类是类D,所以步骤m4的判定为“是”,将处理转移到步骤m5。
在步骤m5中,虚函数调用变换判定部201检查类C2的所有派生类C3的对象是否直接调用了虚函数F2。在直接调用了虚函数F2的情况下,将处理转移到步骤m8,而在未直接调用的情况下,将处理转移到步骤m6。在图30的程序111中,参照虚函数直接调用信息115可知,未用类B的所有派生类C及D直接调用虚函数“A∷f”,所以步骤m5的判定为“是”,将处理转移到步骤m6。而类D没有派生类,所以派生类不直接调用虚函数“B∷g”,所以步骤m5的判定为“是”。
在步骤m6中,虚函数调用变换判定部201将语句S1添加到可直接调用语句信息116中。在图30中,将语句“this->g();”及语句“this->h();”添加到可直接调用语句信息116中。
在步骤m7中,虚函数调用变换判定部201将类C2及虚函数F2的对子P1添加到复制虚函数信息中。在图30中,将类B和A∷f的对子、及类D和B∷g的对子添加到复制虚函数信息中。
在步骤m8中,虚函数调用变换判定部201将处理转移到步骤m1,重复循环的处理。
虚函数调用变换判定处理(S201)分析图30的程序的结果——可直接调用语句信息116及复制虚函数信息分别示于图57及图58。
接着,虚函数定义复制部202在必要时复制虚函数的定义,变换类定义及虚函数表(S202)。虚函数定义复制处理(S202)与图48所示的相同。虚函数定义复制处理(S202)变换图30的程序111的结果——程序及各类的虚函数表分别示于图59及图60。
接着,虚函数调用变换部203将虚函数调用变换为函数的直接调用(S203)。虚函数调用变换处理(S203)与图39所示的相同。虚函数调用变换处理(S203)变换图30的程序111的结果所得到的代码示于图61。
如上所述,向本实施方式的程序变换装置200输入了图30所示的程序111的结果是,能够将包含虚函数调用的语句“this->g();”及语句“this->h();”变换为函数的直接调用。因此,能够提高执行目标程序112时的执行速度。此外,程序变换装置200复制所需最低限度的虚函数,所以也能够减少目标程序112的代码长度的增加。
其中,在上述实施方式中,类继承关系分析处理(S104)、虚函数重定义分析处理(S105)、虚函数直接调用分析处理(S107)、虚函数调用变换判定处理(S201)、虚函数定义复制处理(S202)、虚函数调用变换处理(S203)分别只执行了一次,但是也可以在必要时重复多次。
此外,在虚函数及虚函数所属的类满足特定的条件的情况下,能够在该虚函数定义中确定this指针的类型,但是在进行类对象的生成处理的构造函数、或进行删除处理的析构函数中,this指针的类型能够确定为该构造函数或析构函数所属的类。因此,也可以将构造函数或析构函数中描述的this指针的虚函数调用变换为函数的直接调用。
此外,在能够根据程序的性质或执行结果来清楚地确定this指针的类型的情况下,也可以根据pragma指令、选项指定及程序的执行历史信息等,将虚函数调用变换为函数的直接调用。
在实施方式1的程序变换装置100中,依次输入所有程序111,对所有程序111一次进行处理,但是在实施方式6的程序变换装置中,逐个文件地输入程序,并逐个文件地进行程序变换处理。
图62是本发明实施方式6的程序变换装置300的结构图。程序变换装置300是接受用面向对象语言——C++语言描述的多个程序、输出可执行程序的装置,包括程序存储部301、编译部310、目标程序存储部302、结合部320、以及可执行程序存储部303。
程序存储部301是逐个文件地存储作为程序变换装置300中的变换对象的、用面向对象语言——C++语言描述的多个程序111a~111c的存储装置。
编译部310是将多个程序111a~111c编译为多个目标程序112a~112c的处理部,由输入部312、语法分析部313、类继承关系分析部314、虚函数重定义分析部315、虚函数直接调用分析部317、以及输出部318构成。
目标程序存储部302是存储与程序存储部301中保存着的程序111a~111c分别对应的目标程序112a~112c的存储装置。
结合部320是根据目标程序存储部302中存储着的多个目标程序112a~112c来生成1个可执行程序324的处理部,由输入部321、虚函数调用变换部322、以及链接部323构成。
可执行程序存储部303是存储从结合部320的链接部323输出的可执行程序324的存储装置。
结合以下说明的程序变换装置300执行的处理来说明其他处理部。
图63是程序变换装置300执行的处理的流程图。
输入部312选择程序存储部301中保存着的程序111a~111c中的1个文件(1个程序),交给语法分析部313(S312)。其中,每当翻译部310结束对1个文件的编译处理时,输入部312就将下一个文件交给语法分析部313。
语法分析部313分析从输入部312接受到的程序的语法,进行符号表的生成和语法树的生成等,将其分析结果交给类继承关系分析部314(S313)。
类继承关系分析部314提取程序中包含的所有类并分析类间的继承关系,并将分析结果作为类的继承关系信息113保存到分析信息存储部316中(S314)。
虚函数重定义分析部315分析类的虚函数是否重定义了基类的虚函数,将分析结果作为虚函数重定义信息114保存到分析信息存储部316中(S315)。
虚函数直接调用分析部317分析程序中直接调用的虚函数及启动对象,并将分析结果作为虚函数直接调用信息115保存到分析信息存储部316(S317)。
输出部318将虚函数调用分析部317的变换结果及分析信息存储部316中保存着的分析信息作为目标程序而保存到目标程序存储部302中(S318)。
输入部321接受目标程序存储部302中存储着的所有目标程序112a~112c,交给虚函数调用变换部322(S321)。
虚函数调用变换部322参照从输入部321接受到的目标程序112a~112c中包含的分析信息中保存的类的继承关系信息113、虚函数重定义信息114及虚函数直接调用信息115,判定能否将虚函数调用变换为函数的直接调用,在能够变换的情况下,变换为函数的直接调用(S322)。
链接部323通过结合接虚函数调用变换部322变换后的所有目标程序来生成可执行程序324,并将该可执行程序324记录到可执行程序存储部303中(S323)。
其中,语法分析处理(S313)、类继承关系分析处理(S314)、虚函数重定义分析处理(S315)、虚函数直接调用分析处理(S317)及虚函数调用变换处理(S322)的处理分别与实施方式1的语法分析处理(S103)、类继承关系分析处理(S104)、虚函数重定义分析处理(S105)、虚函数直接调用分析处理(S107)及虚函数调用变换处理(S108)相同。
因此,与实施方式1的程序变换装置100同样,向程序变换装置300输入了图13所示的程序111的结果是,能够将虚函数调用的代码变换为图20所示的代码。因此,能够提高执行可执行程序324时的执行速度。
其中,实施方式2、实施方式3、实施方式4及实施方式5中通过与实施方式6同样地构成,也能够得到与各实施方式同样的变换结果。
在实施方式1的程序变换装置100中,同时进行了分析信息的收集和虚函数调用的变换,但是也可以分别执行分析信息的收集和虚函数调用的变换。在本实施方式的程序变换装置的特征在于,分别执行分析信息的收集和虚函数调用的变换。
图64是本发明实施方式7的程序变换装置400的结构图。程序变换装置400是接受用面向对象语言——C++语言描述的多个程序、输出目标程序的装置,包括程序存储部401、预编译部410、分析信息存储部402、程序变换部420、以及生成代码存储部403。
程序存储部401是逐个文件地存储程序变换装置400中作为变换对象的、用面向对象语言——C++语言描述的多个程序111a~111c的存储装置。
预编译部410是依次接受程序存储部401中保存着的所有程序111a~111c、生成各种分析信息(类的继承关系信息113、虚函数重定义信息114及虚函数直接调用信息115)的处理部,由输入部412、语法分析部413、类继承关系分析部414、虚函数重定义分析部415、以及虚函数直接调用分析部416构成。
程序变换部420是参照分析信息存储部402中保存着的类的继承关系信息113、虚函数重定义信息114及虚函数直接调用信息115,来判定能否将程序111a~111c中的虚函数调用变换为函数的直接调用,并在能够变换的情况下,变换为函数的直接调用的处理部。该程序变换部420由输入部421、语法分析部422、虚函数调用变换部423、以及输出部424构成。
生成代码存储部403是存储从程序变换部420输出的目标程序112的存储装置。
结合以下说明的程序变换装置400执行的处理来说明其他处理部。
图65是程序变换装置400执行的处理的流程图。
输入部412依次输入程序存储部401中保存着的所有程序111a~111c,交给语法分析部413(S412)。
语法分析部413分析从输入部412接受到的程序111a~111c的语法,进行符号表的生成或语法树的生成等,并将其分析结果交给类继承关系分析部414(S413)。
类继承关系分析部414提取程序111a~111c中包含的所有类并分析类间的继承关系,将分析结果作为类的继承关系信息113保存到分析信息存储部402中(S414)。
虚函数重定义分析部415分析类的虚函数是否重定义了基类的虚函数,并将分析结果作为虚函数重定义信息114而保存到分析信息存储部402中(S415)。
虚函数直接调用分析部416分析程序111a~111c中直接调用的虚函数及启动对象,并将分析结果作为虚函数直接调用信息115保存到分析信息存储部402中(S416)。
输入部421依次输入分析信息存储部402中保存着的类的继承关系信息113、虚函数重定义信息114及虚函数直接调用信息115、以及程序存储部401中保存着的程序111a~111c,交给语法分析部422(S421)。
语法分析部422分析从输入部421接受到的程序111a~111c的语法,进行符号表的生成或语法树的生成等,将其分析结果交给虚函数调用变换部423(S422)。此外,语法分析部422将类的继承关系信息113、虚函数重定义信息114及虚函数直接调用信息115交给虚函数调用变换部423。
虚函数调用变换部423参照从语法分析部422接受到的类的继承关系信息113、虚函数重定义信息114及虚函数直接调用信息115,判定能否将虚函数调用变换为函数的直接调用,在能够变换的情况下,变换为函数的直接调用(S423)。
输出部424将通过各步骤变换的程序作为目标程序112记录到生成代码存储部403中。
其中,语法分析处理(S413、S422)、类继承关系分析处理(S414)、虚函数重定义分析处理(S415)、虚函数直接调用分析处理(S416)及虚函数调用变换处理(S423)分别与实施方式1的语法分析处理(S103)、类继承关系分析处理(S104)、虚函数重定义分析处理(S105)、虚函数直接调用分析处理(S107)及虚函数调用变换处理(S108)相同。
因此,与实施方式1的程序变换装置100同样,向程序变换装置400输入了图13所示的程序111的结果是,能够将虚函数调用的代码变换为图20所示的代码。因此,能够提高执行目标程序112时的执行速度。
其中,实施方式2、实施方式3、实施方式4及实施方式5通过构成为与实施方式7同样,也能够得到与各实施方式同样的变换结果。
产业上的可利用性本发明能够适用于编译器,特别是能够适用于变换用面向对象语言描述的程序的编译器等。
权利要求
1.一种程序变换方法,变换用面向对象语言描述的程序,其特征在于,包含方法分析步骤,在上述程序中,分析调用方法的实例的类型;虚方法调用提取步骤,在上述方法的定义中,提取上述实例的虚方法调用;以及虚方法调用变换步骤,根据上述方法分析步骤的分析结果,将由上述虚方法调用提取步骤提取出的虚方法调用变换为直接方法调用。
2.如权利要求1所述的程序变换方法,其特征在于,上述方法分析步骤包含类继承关系分析步骤,在上述程序中,分析类的继承关系;虚方法重定义分析步骤,分析上述类中的上述虚方法的重定义状况;虚方法直接调用分析步骤,在上述程序中,分析上述虚方法的直接调用;以及实例确定步骤,根据上述类继承关系分析步骤、上述虚方法重定义分析步骤及上述虚方法直接调用分析步骤的分析结果,来确定调用上述方法的上述实例的类型;在上述方法分析步骤能够确定上述实例的类型的情况下,上述虚方法调用变换步骤将由上述虚方法调用提取步骤提取出的虚方法调用变换为直接方法调用。
3.如权利要求2所述的程序变换方法,其特征在于,上述实例确定步骤包含下述步骤判定上述方法所属的类是否具有派生类;在上述类具有派生类的情况下,判定是否在直接继承上述类的所有类中重定义了上述方法;以及判定上述类的所有派生类的实例是否直接调用了上述方法。
4.如权利要求2所述的程序变换方法,其特征在于,上述实例确定步骤包含下述步骤判定上述方法所属的类是否具有派生类;在上述类具有派生类的情况下,判定是否在对由上述虚方法调用提取步骤提取出的上述虚方法进行重定义的第二类中重定义了上述方法;以及判定上述第二类及上述第二类的所有派生类的实例是否直接调用了上述方法。
5.如权利要求1所述的程序变换方法,其特征在于,在上述方法是实例生成方法时,上述方法分析步骤确定调用上述方法的上述实例的类型。
6.如权利要求1所述的程序变换方法,其特征在于,在上述方法是实例删除方法时,上述方法分析步骤确定调用上述方法的上述实例的类型。
7.一种程序变换方法,变换用面向对象语言描述的程序,其特征在于,包含方法分析步骤,在上述程序中,分析调用方法的实例的类型;虚方法调用提取步骤,在上述方法的定义中,提取上述实例的虚方法调用;虚方法复制步骤,根据上述方法分析步骤的结果,复制上述虚方法;以及虚方法调用变换步骤,根据上述方法分析步骤的分析结果,将由上述虚方法调用提取步骤提取出的虚方法调用变换为直接方法调用。
8.如权利要求7所述的程序变换方法,其特征在于,上述方法分析步骤包含类继承关系分析步骤,在上述程序中,分析类的继承关系;虚方法重定义分析步骤,分析上述类中的上述虚方法的重定义状况;虚方法直接调用分析步骤,在上述程序中,分析上述虚方法的直接调用;以及实例确定步骤,根据上述类继承关系分析步骤、上述虚方法重定义分析步骤及上述虚方法直接调用分析步骤的分析结果,确定调用上述方法的上述实例的类型;在上述方法分析步骤能够确定上述实例的类型的情况下,上述虚方法调用变换步骤将由上述虚方法调用提取步骤提取出的虚方法调用变换为直接方法调用。
9.如权利要求8所述的程序变换方法,其特征在于,上述实例确定步骤包含下述步骤判定上述方法所属的类是否具有派生类;和判定上述类的所有派生类的实例是否直接调用了上述方法;在上述虚方法复制步骤中,对上述程序中包含的所有类,在上述类具有基类的情况下,将上述基类中包含的虚方法中的未在上述类中重定义的上述虚方法,在上述类中进行重定义。
10.如权利要求8所述的程序变换方法,其特征在于,上述实例确定步骤包含下述步骤判定上述方法所属的类是否具有派生类;和判定上述类的所有派生类的实例是否直接调用了上述方法;在上述虚方法复制步骤中,对直接继承上述方法所属的类的所有第二类,当在上述第二类中未重定义上述方法时,在上述第二类中重定义上述方法。
11.如权利要求8所述的程序变换方法,其特征在于,上述实例确定步骤包含下述步骤判定上述方法所属的类是否具有派生类;在上述类具有派生类的情况下,提取对由上述虚方法调用提取步骤提取出的上述虚方法进行重定义的第三类;以及判定上述第三类及上述第三类的所有派生类的实例是否直接调用了上述方法;在上述虚方法复制步骤中,当在上述第三类中未重定义上述方法时,在上述第三类中重定义上述方法。
12.一种程序变换方法,变换用面向对象语言描述的程序,其特征在于,包含编译步骤,编译上述程序;和结合步骤,结合上述编译步骤的编译结果;上述编译步骤包含方法分析步骤,在上述程序中,分析调用方法的实例的类型;虚方法调用提取步骤,在上述方法的定义中,提取上述实例的虚方法调用;以及输出步骤,输出上述方法分析步骤的分析结果、上述虚方法调用提取步骤的分析结果及上述程序的变换结果;上述结合步骤包含分析数据提取步骤,输入上述编译步骤的输出,提取上述编译步骤的输出中包含的分析结果;虚方法调用变换步骤,根据上述分析结果提取步骤的结果,将上述虚方法调用变换为直接方法调用;以及链接步骤,链接上述虚方法调用变换步骤的结果。
13.一种程序变换方法,变换用面向对象语言描述的程序,其特征在于,包含预编译步骤,从上述程序中提取规定的信息;和变换步骤,根据上述预编译步骤的提取结果,将虚方法调用变换为直接方法调用;上述预编译步骤包含方法分析步骤,在上述程序中,分析调用方法的实例的类型;和虚方法调用提取步骤,在上述方法的定义中,提取上述实例的虚方法调用;上述变换步骤包含输入步骤,接收上述程序、上述方法分析步骤的分析结果及上述虚方法调用提取步骤的分析结果,作为输入;和虚方法调用变换步骤,根据由上述输入步骤输入的分析结果,将由上述虚方法调用提取步骤提取出的虚方法调用变换为直接方法调用。
全文摘要
本发明的程序变换方法,着眼于有时能够确定成员函数的this指针的类型的事实,能够提高执行性能,减小代码长度,将虚函数调用变换为函数的直接调用,它变换用面向对象语言描述的程序,包含方法分析步骤,在上述程序中,分析调用方法的实例的类型;虚方法调用提取步骤,在上述方法的定义中,提取上述实例的虚方法的调用;以及虚方法调用变换步骤,根据上述方法分析步骤的分析结果,将上述虚方法调用提取步骤提取出的虚方法调用变换为直接方法调用。
文档编号G06F9/44GK1776621SQ20051012675
公开日2006年5月24日 申请日期2005年11月18日 优先权日2004年11月19日
发明者田中裕久 申请人:松下电器产业株式会社
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1