一个不幸的事实是,当我们开启了编译链接的优化选项后,Swift的对象方法的调用机制做了非常大的改进。最主要的就是进一步弱化了通过虚函数表来进行间接方法调用的实现,而是大量的改用了一些内联的方式来处理方法函数调用。同时对多态的支持也采用了一些别的策略。具体用了如下一些策略:
大量的将函数实现换成了内联函数模式,也就是对于大部分类中定义的源代码比较少的方法函数都统一换成内联。这样对象方法的调用将不再通过虚函数表来间接调用,而是简单粗暴的将函数的调用改为直接将内联函数生成的机器码进行拷贝处理。这样的一个好处就是由于没有函数调用的跳转指令,而是直接执行方法中定义的指令,从而极大的加速了程序的运行速度。另外一个就是使得整个程序更加安全,因为此时函数的实现逻辑已经散布到各处了,除非恶意修改者改动了所有的指令,否则都只会影响局部程序的运行。内联的一个的缺点就是使得整个程序的体积会增大很多。比如下面的类代码在优化模式下的Swift语言源代码和C语言伪代码实现:
- ////////Swift源代码
-
- //类定义
- class CA {
- open func foo(_ a:Int, _ b:Int) ->Int {
- return a + b
- }
-
- func main() {
- let obj = CA()
- let a = obj.foo(10,20)
- let b = obj.foo(a, 40)
- }
-
- ////////C伪代码
-
-
- //...........................................运行时定义部分
-
-
- //Swift类描述。
- struct swift_class {
- ... //其他的属性,因为这里不关心就不列出了
- //这里也没有虚表的信息。
- };
-
- //...........................................源代码中类的定义和方法的定义和实现部分
-
-
- //类定义
- struct CA {
- struct swift_class *isa;
- };
-
- //这里没有方法实现,因为短方法被内联了。
-
- struct swift_class classCA;
-
-
- //...........................................源代码中程序运行的部分
-
-
- void main() {
- CA *obj = CA.__allocating_init(classCA);
- obj->isa = &classCA;
- int a = 10 + 20; //代码被内联优化
- int b = a + 40; //代码被内联优化
- }
2. 就是对多态的支持,也可能不是通过虚函数来处理了,而是通过类型判断采用条件语句来实现方法的调用。就比如下面Swift语言源代码和C语言伪代码:
- ////////Swift源代码
-
- //基类
- class CA{
- @inline(never)
- open func foo(){}
- }
-
- //派生类
- class CB:CA{
- @inline(never)
- override open func foo(){}
- }
-
- //全局函数接收对象作为参数
- @inline(never)
- func testfunc(_ obj:CA){
- obj.foo()
- }
-
-
- func main() {
- //对象的创建以及方法调用
- let objA = CA()
- let objB = CB()
- testfunc(objA)
- testfunc(objB)
- }
- ////////C伪代码
-
- //...........................................运行时定义部分
-
-
- //Swift类描述
- struct swift_class {
- ... //其他的属性,因为这里不关心就不列出了
- //这里也没有虚表的信息。
- };
-
-
- //...........................................源代码中类的定义和方法的定义和实现部分
-
- //类定义
- struct CA {
- struct swift_class *isa;
- };
-
- struct CB {
- struct swift_class *isa;
- };
-
- //Swift类的方法的实现
- //基类CA的foo方法实现
- void fooForA(){}
- //派生类CB的foo方法实现
- void fooForB(){}
- //全局函数方法的实现
- void testfunc(CA *obj)
- {
- //这里并不是通过虚表来进行间接调用而实现多态,而是直接硬编码通过类型判断来进行函数调用从而实现多态的能力。
- asm("mov x20, obj");
- if (obj->isa == &classCA)
- fooForA();
- else if (obj->isa == &classCB)
- fooForB();
- }
-
- //类的描述信息构建,这些都是在编译代码时就明确了并且保存在数据段中。
- struct swift_class classCA;
- struct swift_class classCB;
-
- //...........................................源代码中程序运行的部分
-
- void main() {
- //对象实例创建以及方法调用的代码。
- CA *objA = CA.__allocating_init(classCA);
- objA->isa = &classCA;
- CB *objB = CB.__allocating_init(classCB);
- objB->isa = &classCB;
- testfunc(objA);
- testfunc(objB);
- }
(编辑:晋中站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|