译:Swift ABI (二)
泊学翻译自Swift在Github上发布的Swift ABI Manifesto Swift ABI的构成在实践中,ABI关注的内容是紧密耦合在一起的。但是,作为一个概念模型。我更愿意把它分成6个独立的分类: 1.和类型相关的,例如:所有的结构和类对象应该有确定的内存布局。为了达成二进制层次上的交互(这里应该指的是不同版本Swift编译器生成的结果在二进制上兼容),它们必须共享相同的布局协议。这部分内容会在数据布局的章节进行讨论。 2.Swift可执行程序,运行时、反射机制、调试器以及可视化工具都和类型的metadata息息相关。因此,metadata应该有一种更稳定的读取方式,要不为类型的metadata设计确定的内存布局,要不为访问类型的metadata提供一套稳定的APIs。这部分内容会在类型的metadata章节继续讨论。 3.程序库中每一个被导出或来自外部的符号都需要一个唯一的名称,这个名称的识别应该在所有的二进制实体之间达成一致。由于Swift提供了函数重载以及上下文相关的名字空间(这里应该指的是通过module引入的名字空间),因此,在代码中出现的任何名称可能都不是全局唯一的。为了把它们表达成一个全局唯一的名字,Swift使用了一种叫做name mangling的技术。具体的name mangling方案会在Mangling章节中讨论。 4.函数必须知道如何相互调用,因此我们需要约定调用栈在内存中是如何布局的,哪些寄存器会在调用间被保留。这些内容统称为函数的调用约定。这部分内容会在Calling Convention章节中讨论。 5.Swift发布的时候自带了一个运行时库,用来处理诸如动态类型转换、引用计数、类型反射等相关的工作。Swift程序在编译的时候会调用这些运行时中的API。因此,Swift运行时API也是Swift ABI的一部分。运行时API的稳定性会在运行时的章节中讨论。 6.除此之外,Swift还自带了一个标准库,其中定义了很多公共的类型、结构和基于这些结构的方法。为了让这份自带的标准库可以被用不同版本Swift编写的程序调用,标准库也需要对外暴露一份稳定的API。因此,和标准库中定义的类型需要有确定的内存布局一样,Swift标准库的API也是Swift ABI的一部分。关于标准库ABI的稳定性会在标准库的章节中进行讨论。 数据布局背景 首先,我们来定义一些术语。
数据布局,也被称作类型布局,定义了一个对象的数据在内存中的布局。这包括了对象在内存中的大小,对象的对齐(稍后会定义)以及如何在对象中找到每一个数据成员。 如果编译器可以在编译期确定一个对象的布局,这个对象的布局就是静态的。如果对象的布局只有在运行时在可以确定,这类对象的布局就是不透明的(opaque layout)。我们会在opaque layout章节中深入讨论这类对象。 布局和类型的属性在Swift里,对于每一个静态布局的类型T,ABI指定了计算以下内容的方式:
把计算对齐和对象大小的方式结合在一起,就是这个类型的对象占用内存时的步进计算方式,它等于把对象的尺寸按照内存对齐的大小向上取整一个单位(最小是1单位。例如,对象的大小是7,内存要求8字节对齐,那么对象占用的内存就向上调整到8)。这种计算方式对于在连续内存地址空间中排列对象(例如:数组)时很有帮助。 一些类型有以下两种有趣的属性:
例如,一个 再来看一个可以按位移动的非POD类型的例子,就是包含类对象引用的 最后,来看一个不可按位移动的非POD类型的例子,就是一个包含 不透明布局当一个对象的布局只有在运行时才可以确定时,这类对象的布局就叫做不透明的。例如,一个泛型对象,我们就无法在编译期确定对象的布局。再有,就是一种更具适应性的类型(resilient type),我们会在下一节描述这个概念。 对于一个具有不透明布局的对象来说,它的大小、对齐,是否是一个POD类型或者是否可以按位移动都是通过查询它的value witness table来确定的。我们会在value witness table这一节中深入讨论这个话题。数据成员的偏移是通过查询类型的metadata得到的,我们会在value metadata的章节中讨论。拥有不透明布局的对象必须通过间接的方式传递,我们会在函数底层签名(Function Signature Lowering)的章节中讨论。Swift运行时,通过一些指针和拥有不透明布局的对象进行交互,因此,这类对象必须是可以取地址的。我们会在抽象级别的章节中进一步进行描述。 在实践中,编译器可以在编译期对布局有部分的了解。例如,对于下面这样的 struct Type<T> { var number: Int var object: T } 在这种情况下,根据特定的布局算法,整数number的布局以及它在struct对象中的位置都是可以确定的。但是,泛型属性的存储却是不透明布局,因此,整个结构的大小和对齐都是不确定的。我们正在调研如何用更高效的方式布局这种“半透明”形式的组合SR-3722。这很可能会导致把不透明的部分放到布局的末尾以保证所有静态布局的部分可以正常计算偏移。 (To be continue...) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |