【问题标题】:Why do trait object vtables contain size and alignment?为什么特征对象 vtable 包含大小和对齐方式?
【发布时间】:2018-08-24 20:22:54
【问题描述】:

Rust 的 trait 对象是包含 2 个常规指针的胖指针:指向数据和指向 vtable。 vtable 是一个结构,包含一个析构函数指针、所有 trait 方法指针,最后是数据的大小和对齐方式。

大小和对齐字段的用途是什么?

我找不到太多:

  • Blog post A:它用于释放内存,但今天没有使用,可能会被一些未来更灵活的机制使用(它可能是什么?是否存在?)
  • Blog post B:它用于释放类型擦除的装箱值,因此它们知道如何释放内存(Box 不存储其分配的位置、大小和对齐方式?每个 DST 的每个大小变体都无法获得自己的版本一个 vtable,可以吗?)

【问题讨论】:

    标签: dynamic rust vtable


    【解决方案1】:

    这是我目前发现的:

    vtable 中的大小和对齐属性在librustc_codegen_llvm::glue::size_and_align_of_dst() 函数中加载,该函数返回动态大小类型的大小和对齐方式。对于ty::Dynamic(..) 值(编译器内部描述 trait 对象的方式),从 vtable 中读取大小和对齐方式:

    match t.sty {
        ty::Dynamic(..) => {
            // load size/align from vtable
            let vtable = info.unwrap();
            (meth::SIZE.get_usize(bx, vtable), meth::ALIGN.get_usize(bx, vtable))
        }
        ...
    }
    

    这个函数又用在几个地方:

    目前我没有发现将这些值输入到 Rust 释放函数 (__rust_dealloc()) 的任何地方,但它们肯定可以在未来用于此目的。

    【讨论】:

    • 可能是为了向前兼容。
    • @PeterHall 是的。了解数据的大小和对齐方式是如此基础和有用,没有理由不包含它,特别是考虑到每个类型 vtable 的存储开销是一次,而它只有两个 usizes。
    • 感谢您提供如此全面的回答!我还有 1 个问题:Rustonomicon states DST 几乎可以归结为切片。切片在编译时大小未知。 vtables 如何处理不同长度切片的大小字段? 2 u32s 的切片是否有来自 3 u32s 的切片的其他 vtable?毕竟一个大小为 16,另一个大小为 24(简化)。
    • @CodeSandwich Rustonomicon 可能不清楚。某些 DST 类似于切片 - 具有几个大小字段的结构,然后切片(或其他 DST)作为最终字段。指向任何 DST 的指针必须以额外的usize 的形式携带额外的信息。对于切片或类似切片的 DST,额外信息是切片的大小。对于 trait 对象,它是一个指向 vtable 的指针。
    • 这就是为什么不能将不同的特征对象、切片对象和组合的 DST 转换为特征对象的原因。
    猜你喜欢
    • 1970-01-01
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-13
    • 2016-08-05
    • 2015-02-18
    相关资源
    最近更新 更多