RFC-0059:矢量、字符串和数组计数字段中的预留位 | |
---|---|
状态 | 已接受 |
区域 |
|
说明 | 此 FTP 提出了一些更改。向量、字符串和数组计数最多为 32 位(最大值为 232-1)。矢量和字符串计数字段的上 8 位预留给绑定以供在内存中使用。在线路上,这些字段必须填充为零。接下来的 24 位矢量/字符串计数字段已预留,但未使用,并且必须在线路上填充 0。它们无法由绑定使用,并且可能会在未来的 FTP 中重新分配。 |
作者 | |
提交日期(年-月-日) | 2020-03-16 |
审核日期(年-月-日) | 2020-03-19 |
摘要
FIDL 矢量(和字符串)使用 64 位计数字段来表示编码字节数。此 FTP 提出了一些更改:
矢量、字符串和数组计数上限为 32 位(最大值为 232-1)。
矢量/字符串计数字段的上 8 位预留给绑定以供在内存中使用。在线路上,这些字段必须填充为零。
接下来的 24 位矢量/字符串计数字段已预留,但未使用,并且必须在线路上填充零。它们无法由绑定使用,并且可能会在未来的 FTP 中重新分配。
直观呈现现有 64 位计数字段的细分情况。
这会将向量、字符串和数组编码的最大大小从 18.45 艾字节缩减到 4.29 千兆字节。
设计初衷
LLCPP 绑定支持对对象进行原地编码。作为 LLCPP Builder 工作计划的一部分,绑定现在会跟踪内存所有权,以便为用户简化对象创建。具体而言,对于矢量,count 字段的最高有效位 (MSB) 用于存储所有权信息(请参阅 vector_view.h)。此位在线性化期间会设为零,并且不会影响 FIDL 线格格式,但会阻止 LLCPP 绑定使用 MSB 作为计数值。
这样做的目的是正式预留矢量计数字段的 MSB,以供绑定使用,并将预留扩展到上 8 位。
此外,绑定之间的最大计数存在一些不一致之处。C++ 语言绑定和编译器的各个部分都假定大小上限为 32 位,但此大小从未正式化,并且其他绑定也不遵循此大小。此 FTP 正式规定了矢量/字符串/数组计数的大小上限为 32 位。
设计
64 位矢量(和字符串)计数字段的上 8 位预留给绑定在内存中使用。通过线缆发送时,高 8 位必须为零。
此外,接下来的 24 位(32-55 位)是保留的,绑定不得使用这些位。它们在线路上也必须为零。
ABI 保持不变。
实施策略
每个绑定中的编码和解码逻辑都将更新,以验证计数不超过 2^32-1。这包括验证高位是否为零。如果在解码过程中违反此约束条件,相应通道将关闭。
工效学设计
不适用
文档和示例
线格式文档将更新为显示预留位。
向后兼容性
每个消息的通道字节大小上限为 65536 字节(16 位),因此通过 FIDL 编码为通道消息的系统部分不会有任何兼容性问题。此外,代码的某些部分已假定矢量/字符串/数组的最大计数为 232-1。
性能
对性能的影响微不足道。唯一的实现变更是额外的验证检查。
安全
这应该不会带来任何安全风险。count 字段在线路上将具有相同的值,并且现在还进行了额外的验证检查。
测试
每个绑定实现都负责测试其功能实现,包括测试验证检查。
缺点
完成此 FTP 后,绑定可以将计数字段的上 8 位用于任何用途。因此,很难或根本无法将这些位用于新用途,因为这需要详尽地验证每个绑定是否会使这些位处于未使用的状态,并可能将它们迁移到不使用这些位。
替代方案
您可以将矢量所有权信息存储在矢量的指针字段中,而不是在 count 字段中。
两种可能的方法:
假设对齐度至少为 2 字节,并在最低有效位中存储所有权布尔值。这种方法的问题在于,2 字节对齐的假设很难强制执行,并且通常不正确。在代码库中,有些位置会从缓冲区中的任意偏移量读取字节。
使用地址空间的属性将未使用的位分配给存储内存所有权信息。这样做的问题在于,无法保证内存空间中的位是未使用的。即使目前如此,地址值清理工具等工具往往会将信息存储在指针的可用位中,并且这些工具和 LLCPP 之间可能会发生冲突。
此外,我们还讨论了应为绑定预留多少位数以及向量数量应有多大。支持增加矢量数量的论点是,很难预测未来的需求,并且其他系统在遇到任意大小限制时会遇到问题。尽管如此,写入大于 4.29 GB 的 FIDL 对象的实际用例很少。假设当前 CPU 上的每个元素需要 1/cycle 的时间来编码或解码,那么编码或解码如此多元素的对象将需要超过 1 秒的时间。大型基元数组可以更高效地编码,通常应使用 VMOs 等替代机制(而非 FIDL)进行发送。不过,为绑定预留过多位可能会限制未来的使用情形。作为折衷,系统会预留 8 位用于绑定,24 位未使用,32 位用于计数。这样,您日后就可以根据需要进行更改。
在先技术和参考文档
不适用