@@ -81,23 +81,36 @@ fn common_array_layout(
8181 header_align : u32 ,
8282 expected_array_length_offset : u32 ,
8383) -> GcArrayLayout {
84+ use core:: mem;
85+
8486 assert ! ( header_size >= crate :: VM_GC_HEADER_SIZE ) ;
8587 assert ! ( header_align >= crate :: VM_GC_HEADER_ALIGN ) ;
8688
8789 let mut size = header_size;
8890 let mut align = header_align;
8991
90- let length_field_offset = field ( & mut size, & mut align, 4 ) ;
92+ let length_field_size = u32:: try_from ( mem:: size_of :: < u32 > ( ) ) . unwrap ( ) ;
93+ let length_field_offset = field ( & mut size, & mut align, length_field_size) ;
9194 assert_eq ! ( length_field_offset, expected_array_length_offset) ;
9295
9396 let elem_size = byte_size_of_wasm_ty_in_gc_heap ( & ty. 0 . element_type ) ;
9497 let elems_offset = align_up ( & mut size, & mut align, elem_size) ;
9598 assert_eq ! ( elems_offset, size) ;
9699
100+ let elems_are_gc_refs = ty. 0 . element_type . is_vmgcref_type_and_not_i31 ( ) ;
101+ if elems_are_gc_refs {
102+ debug_assert_eq ! (
103+ length_field_offset + length_field_size,
104+ elems_offset,
105+ "DRC collector relies on GC ref elements appearing directly after the length field, without any padding" ,
106+ ) ;
107+ }
108+
97109 GcArrayLayout {
98110 base_size : size,
99111 align,
100112 elem_size,
113+ elems_are_gc_refs,
101114 }
102115}
103116
@@ -127,7 +140,9 @@ fn common_struct_layout(
127140 . iter ( )
128141 . map ( |f| {
129142 let field_size = byte_size_of_wasm_ty_in_gc_heap ( & f. element_type ) ;
130- field ( & mut size, & mut align, field_size)
143+ let offset = field ( & mut size, & mut align, field_size) ;
144+ let is_gc_ref = f. element_type . is_vmgcref_type_and_not_i31 ( ) ;
145+ GcStructLayoutField { offset, is_gc_ref }
131146 } )
132147 . collect ( ) ;
133148
@@ -241,6 +256,9 @@ pub struct GcArrayLayout {
241256
242257 /// The size and natural alignment of each element in this array.
243258 pub elem_size : u32 ,
259+
260+ /// Whether or not the elements of this array are GC references or not.
261+ pub elems_are_gc_refs : bool ,
244262}
245263
246264impl GcArrayLayout {
@@ -283,9 +301,9 @@ pub struct GcStructLayout {
283301 /// The alignment (in bytes) of this struct.
284302 pub align : u32 ,
285303
286- /// The fields of this struct. The `i`th entry is the `i`th struct field's
287- /// offset (in bytes) in the struct .
288- pub fields : Vec < u32 > ,
304+ /// The fields of this struct. The `i`th entry contains information about
305+ /// the `i`th struct field's layout .
306+ pub fields : Vec < GcStructLayoutField > ,
289307}
290308
291309impl GcStructLayout {
@@ -297,6 +315,20 @@ impl GcStructLayout {
297315 }
298316}
299317
318+ /// A field in a `GcStructLayout`.
319+ #[ derive( Clone , Copy , Debug ) ]
320+ pub struct GcStructLayoutField {
321+ /// The offset (in bytes) of this field inside instances of this type.
322+ pub offset : u32 ,
323+
324+ /// Whether or not this field might contain a reference to another GC
325+ /// object.
326+ ///
327+ /// Note: it is okay for this to be `false` for `i31ref`s, since they never
328+ /// actually reference another GC object.
329+ pub is_gc_ref : bool ,
330+ }
331+
300332/// The kind of an object in a GC heap.
301333///
302334/// Note that this type is accessed from Wasm JIT code.
0 commit comments