为什么特征对象虚表包含大小和对齐方式?

问题描述 投票:0回答:2

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

尺寸和对齐字段的用途是什么?

我找不到太多:

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

这是我迄今为止发现的:

vtable 中的大小和对齐属性加载到

librustc_codegen_llvm::glue::size_and_align_of_dst()
函数中,该函数返回动态大小类型的大小和对齐方式。对于
ty::Dynamic(..)
值(编译器描述特征对象的内部方式),大小和对齐方式是从 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()
),但它们将来肯定可以用于此目的。


0
投票

为了演示为什么 vtable 必须存储值的对齐方式,我们可以查看

Rc::<dyn Trait>::as_ref
关联函数(即将
Rc::<dyn Trait>
解引用为
&dyn Trait
)。

Rc<dyn Trait>
类型的值本质上是两个地址:
RcBox
(这是一个包含引用计数和对象值的结构体)的地址和对象值对应的vtable的地址。为了获得对象值的地址,我们需要将
RcBox
的地址偏移到引用计数之后(两个 8 字节数字,假设是 64 位机器)。但是,如果对象值的对齐方式大于 16,则必须进一步偏移(以满足其对齐方式)。这意味着要获取对象值的地址,我们必须知道该值的对齐方式。

© www.soinside.com 2019 - 2024. All rights reserved.