Search code examples
dynamicrustvtable

Why do trait object vtables contain size and alignment?


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:

  • Blog post A: it's for deallocating memory, but not used today, may be used by some future, more flexible mechanisms (What could it be? Does any exist yet?)
  • Blog post B: it's for deallocating type-erased boxed values, so they know how to release memory (Doesn't 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?)

Solution

  • 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:

    I 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.