RFC-0059:矢量、字符串和数组计数字段中的保留位 | |
---|---|
状态 | 已接受 |
领域 |
|
说明 | 此 FTP 提出了几项更改建议。向量、字符串和数组的计数上限为 32 位(最大值为 232-1)。矢量和字符串计数字段的前 8 位已预留,供绑定使用,以用于内存中。它们的导线上必须填入零。接下来的 24 位的矢量/字符串计数字段已预留,但未使用的,必须在线上填充为零。它们不能通过绑定使用,并且可能会在未来的 FTP 中重新分配。 |
作者 | |
提交日期(年-月-日) | 2020-03-16 |
审核日期(年-月-日) | 2020-03-19 |
总结
FIDL 矢量(和字符串)使用 64 位计数字段表示编码字节数。此 FTP 提出了几项更改建议:
向量、字符串和数组的上限为 32 位(最大值为 232-1)。
矢量/字符串计数字段的前 8 位预留,供绑定使用,供内存中使用。它们的导线上必须填入零。
接下来的 24 位矢量/字符串计数字段已预留,但未使用的,必须在线上填充为零。它们不能通过绑定使用,并且可能会在未来的 FTP 中重新分配。
现有 64 位计数字段细分的可视化。
这会将矢量、字符串和数组编码的最大大小从 18.45 EB 减少到 4.29 GB。
设计初衷
LLCPP 绑定支持对对象进行原地编码。作为 LLCPP 构建器工作的一部分,绑定现在会跟踪内存所有权,以简化用户对象的创建。具体而言,对于矢量,计数字段的最高有效位 (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。
性能
对性能的影响微乎其微。唯一的实现变化是额外的验证检查。
安全性
这应该不会带来任何安全风险。通过网络,计数字段将具有相同的值,并且现在需要进行额外的验证检查。
测试
每个绑定实现都负责测试其功能的实现,包括测试验证检查。
缺点
在此 FTP 之后,绑定能够出于任何目的使用计数字段的高 8 位。因此,很难或无法出于新目的回收这些位,而是需要详尽地验证每个绑定是否会使这些位未使用,并可能停止使用这些位。
替代选项
矢量所有权信息可以存储在矢量的指针字段内,而不是存储在计数字段中。
两种可能的方法:
假设对齐大于 2 字节,并在最低有效位中存储所有权布尔值。这种方法的问题在于,2 字节对齐的假设很难强制执行,并且通常并非如此。在代码库中的某些位置,系统会从缓冲区中的任意偏移量读取字节。
使用地址空间的属性来分配未使用的位来保存内存所有权信息。这样做的问题是无法保证内存空间中不会使用位。即使目前情况也是如此,但地址排错程序等工具往往会将信息存储在指针的可用位中,而这些工具和 LLCPP 之间可能会发生冲突。
另外,我们还讨论了为绑定预留的位数以及向量数量应该有多大。矢量数较大的一个理由是,很难预测未来的需求,并且其他系统遇到了任意大小限制的问题。也就是说,写入大小超过 4.29 GB 的 FIDL 对象的实际用例很少。在当前 CPU 上,对于每个元素 1 个周期,使用这么多元素对对象进行编码或解码需要花费 1 秒钟的时间。可以更高效地编码的大型基元数组通常应通过 VMO 等替代机制(而非 FIDL)发送。不过,为绑定预留太多位可能会对未来的用例造成限制。为妥协,系统会为绑定预留 8 位,不使用 24 位,为计数预留 32 位。这样可以满足未来需要进行的更改。
早期技术和参考资料
不适用