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



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

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

我找不到太多:

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

这是我到目前为止发现的:

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))
}
...
}

此函数又在几个地方使用:

  • librustc_codegen_llvm::operand::store_unsized()用于在堆栈上分配足够的存储空间来存储未装箱的值。
  • 实现size_of_val()内在librustc_codegen_llvm::intrinsic::codegen_intrinsic_call()
  • 实现min_align_of_val()内在librustc_codegen_llvm::intrinsic::codegen_intrinsic_call()

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