Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 为什么这个内联程序集在libobjc中调用release、retain和autorelease?_Objective C_Assembly_Inline Assembly_Libobjc - Fatal编程技术网

Objective c 为什么这个内联程序集在libobjc中调用release、retain和autorelease?

Objective c 为什么这个内联程序集在libobjc中调用release、retain和autorelease?,objective-c,assembly,inline-assembly,libobjc,Objective C,Assembly,Inline Assembly,Libobjc,下面的代码片段取自苹果公司的ObjC运行时(libobjc)源代码。我不知道这到底是什么意思。(抱歉,谷歌搜索能力不强) 更新: 下面是调用bypass_msgSend_release()生成的结果: movl -4(%ebp), %eax movl %eax, (%esp) calll "-[NSObject release]" 以下是文件后面部分的retain的实际实现: __attribute__((aligned(16))) id objc_retain(id obj)

下面的代码片段取自苹果公司的ObjC运行时(libobjc)源代码。我不知道这到底是什么意思。(抱歉,谷歌搜索能力不强)

更新:

下面是调用bypass_msgSend_release()生成的结果:

movl    -4(%ebp), %eax
movl    %eax, (%esp)
calll   "-[NSObject release]"

以下是文件后面部分的
retain
的实际实现:

__attribute__((aligned(16)))
id
objc_retain(id obj)
{
    if (!obj || OBJC_IS_TAGGED_PTR(obj)) {
        goto out_slow;
    }
#if __OBJC2__
    if (((class_t *)obj->isa)->hasCustomRR()) {
        return [obj retain];
    }
    return bypass_msgSend_retain(obj);
#else
    return [obj retain];
#endif
 out_slow:
    // clang really wants to reorder the "mov %rdi, %rax" early
    // force better code gen with a data barrier
    asm volatile("");
    return obj;
}
因此,如果它是一个标记指针,则什么也不做。公平地说,这意味着它实际上与堆上的任何内容都没有关系,也没有保留计数

否则在过去,他们只会向对象发送消息
retain
。现在,如果注意到对象包含自定义的
retain
(毫无疑问,这不是旧运行时将记录的内容,因此需要进行版本检查),则它们会向对象发送消息
retain
,否则它们会使用旁路方法

旁路似乎直接调用
[NSObject retain]
的已知地址


那我猜呢?这是一种速度优化。如果您可以确定没有自定义保留,并且实际上直接跳到
IMP
,那么您就节省了动态调度的成本。考虑到编译器现在在ARC下自动抛出C调用(尤其不是Objective-C调用),这意味着您永远不会去做更昂贵的事情。

这些似乎是对retain、release和autorelease的显式调用,以避免编译器反对相同的调用。至于他们为什么出现,我一点线索都没有。这是哪个文件?我想这是为了绕过ARC,这会禁止呼叫。但我猜在这一点上。非常有趣的发现。请随意再次编辑它;我不是想改变你的问题,只是说得更清楚些。请注意,在标题中不需要标记,代码本身也在问题中,因此可以在搜索中找到。我建议对标题进行严格的散文式描述。@mojuba-字符串只是方法的实际链接器可见名称。它用引号括起来,因为它包含非标准字符。这很有意义,并解释了
绕过\u msgSend\u
。跳过去,该死D
__attribute__((aligned(16)))
id
objc_retain(id obj)
{
    if (!obj || OBJC_IS_TAGGED_PTR(obj)) {
        goto out_slow;
    }
#if __OBJC2__
    if (((class_t *)obj->isa)->hasCustomRR()) {
        return [obj retain];
    }
    return bypass_msgSend_retain(obj);
#else
    return [obj retain];
#endif
 out_slow:
    // clang really wants to reorder the "mov %rdi, %rax" early
    // force better code gen with a data barrier
    asm volatile("");
    return obj;
}