Rust's trait objects are fat pointers that contain 2 regular pointers: to data and to a vtable. The vtable is a structure containing a destructor function pointer, all trait method pointers and finally the size and alignment of the data.
What are the size and alignment fields for?
I couldn't find much:
Box
store location, size and alignment of its allocation? Every size variant of every DST can't get its own version of a vtable, can it?)Here's what I've found so far:
The size & alignment properties in a vtable are loaded in the librustc_codegen_llvm::glue::size_and_align_of_dst()
function which returns the size and alignment of a dynamically sized type. For ty::Dynamic(..)
values (the compiler's internal way of describing trait objects), the size and alignment are read from the 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))
}
...
}
This function in turn is used in several places:
librustc_codegen_llvm::operand::store_unsized()
for allocating enough storage space on the stack for the storing the unboxed value. librustc_codegen_llvm::intrinsic::codegen_intrinsic_call()
for implementing the size_of_val()
intrinsiclibrustc_codegen_llvm::intrinsic::codegen_intrinsic_call()
for implementing the min_align_of_val()
intrinsicI didn't spot any places where these values are currently fed into the Rust deallocation function (__rust_dealloc()
), but they could certainly be used for that in the future.