| 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 Builder 工作的一部分,绑定现在会跟踪内存所有权,以简化用户创建对象的过程。具体而言,对于向量,计数字段的最高有效位 (MSB) 用于存储所有权信息(请参阅 vector_view.h)。此位在线性化期间归零,不会影响 FIDL 线格式,但会阻止 LLCPP 绑定将 MSB 用于计数值。
此 FTP 的目标是将向量计数字段的 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 个周期,对具有这么多元素的某个对象进行编码或解码将需要超过一秒的时间。大型原始数组可以更高效地编码,通常应使用 VMO 等替代机制而不是 FIDL 发送。不过,为绑定保留过多的位可能会限制未来的用例。作为一种折衷方案,为绑定保留 8 位,24 位未使用,32 位用于计数。这样一来,就可以根据需要进行未来的更改。
在先技术和参考文档
不适用