@@ -362,7 +362,9 @@ pub enum MicroOp {
362362 imm : Box < [ u8 ; 32 ] > ,
363363 } ,
364364
365- /// Copy 8 bytes from `src` to `dst`.
365+ /// Copy 8 bytes from `src` to `dst`. Neither slot need be 8-aligned: a
366+ /// size-8 aggregate (e.g. `{u32, u32}`, align 4) can sit at a 4-aligned
367+ /// field offset.
366368 Move8 {
367369 dst : FrameOffset ,
368370 src : FrameOffset ,
@@ -953,6 +955,25 @@ pub enum MicroOp {
953955 size : u32 ,
954956 } ,
955957
958+ /// Read within a heap object at a static offset: `obj_ref` is a fat pointer
959+ /// whose target holds the heap object pointer; copies `size` bytes at byte
960+ /// `offset` within the object into `dst`.
961+ HeapReadOffset {
962+ dst : FrameOffset ,
963+ obj_ref : FrameOffset ,
964+ offset : u32 ,
965+ size : u32 ,
966+ } ,
967+
968+ /// Write within a heap object at a static offset: copies `size` bytes
969+ /// from `src` to byte `offset` within the object.
970+ HeapWriteOffset {
971+ obj_ref : FrameOffset ,
972+ offset : u32 ,
973+ src : FrameOffset ,
974+ size : u32 ,
975+ } ,
976+
956977 /// Copies the 16-byte fat pointer from `src_ref` to `dst_ref`, while
957978 /// adding `offset` to the offset part of the fat pointer.
958979 ///
@@ -1012,6 +1033,9 @@ pub enum MicroOp {
10121033 } ,
10131034
10141035 /// Copy 8 bytes from a heap object at `heap_ptr + offset` into `dst`.
1036+ /// Neither `dst` nor `heap_ptr + offset` need be 8-aligned: a size-8
1037+ /// aggregate (e.g. `{u32, u32}`, align 4) can sit at a 4-aligned slot
1038+ /// or field offset.
10151039 HeapMoveFrom8 {
10161040 dst : FrameOffset ,
10171041 heap_ptr : FrameOffset ,
@@ -1027,13 +1051,17 @@ pub enum MicroOp {
10271051 } ,
10281052
10291053 /// Copy 8 bytes from `src` into a heap object at `heap_ptr + offset`.
1054+ /// Neither `src` nor `heap_ptr + offset` need be 8-aligned: a size-8
1055+ /// aggregate (e.g. `{u32, u32}`, align 4) can sit at a 4-aligned slot
1056+ /// or field offset.
10301057 HeapMoveTo8 {
10311058 heap_ptr : FrameOffset ,
10321059 offset : u32 ,
10331060 src : FrameOffset ,
10341061 } ,
10351062
10361063 /// Write an immediate u64 into a heap object at `heap_ptr + offset`.
1064+ /// `heap_ptr + offset` need not be 8-aligned (see `HeapMoveTo8`).
10371065 HeapMoveToImm8 {
10381066 heap_ptr : FrameOffset ,
10391067 offset : u32 ,
@@ -1177,12 +1205,13 @@ pub enum MicroOp {
11771205 /// If `None` (the runtime variant does not declare the field), aborts with
11781206 /// a variant mismatch (expected Move semantics).
11791207 ///
1180- /// `off` is the full object-relative offset (already includes
1181- /// `ENUM_DATA_OFFSET`); indexing by tag handles a field shared across
1182- /// variants that sits at different byte offsets in each. An access whose
1183- /// handle covers every variant, all placing the field at one fixed offset,
1184- /// uses the static `enum_borrow` (`HeapBorrow`) fast path instead.
1185- EnumBorrowVariantField {
1208+ /// Each `off` is measured from the object's start — the `ENUM_DATA_OFFSET`
1209+ /// tag skip is folded in when the op is constructed. Indexing by tag
1210+ /// handles a field shared across variants that sits at different byte
1211+ /// offsets in each. An access whose handle covers every variant, all
1212+ /// placing the field at one fixed offset, uses the [`MicroOp::HeapBorrow`]
1213+ /// fast path instead.
1214+ EnumBorrowVariantFieldByTag {
11861215 dst : FrameOffset ,
11871216 enum_ref : FrameOffset ,
11881217 // TODO(perf): the boxed slice is a separate allocation and a
@@ -1215,38 +1244,33 @@ pub enum MicroOp {
12151244 variant : VariantTag ,
12161245 } ,
12171246
1218- /// Read a variant field by value through an enum reference at a static
1219- /// object-relative `offset`. The uniform-offset fast path: the access's
1220- /// handle covers every variant, all placing the field at the same offset,
1221- /// so no runtime tag dispatch or mismatch check is needed. Derefs the
1222- /// 16-byte `enum_ref` fat pointer to the heap object (a double deref), then
1223- /// copies `size` bytes from `obj + offset` into `dst`. Fuses the
1224- /// `HeapBorrow` + `ReadRef` (the divergent path still routes through a
1225- /// scratch reference).
1226- ///
1227- // TODO(cleanup): nothing here is enum-specific — this reads any field through a
1228- // reference at a static offset. Rename to a non-enum-specific name as part
1229- // of a naming-consistency pass.
1230- EnumReadVariantField {
1247+ /// Read a variant field by value through an enum reference, selecting the
1248+ /// field's object byte offset by the runtime variant tag: derefs the
1249+ /// 16-byte `enum_ref` fat pointer to the heap object, reads the tag, and
1250+ /// if `offsets[tag]` is `Some(off)` copies `size` bytes at byte `off`
1251+ /// within the object into `dst`; a `None` hole (the runtime variant does
1252+ /// not declare the field) aborts with a variant mismatch. Each `off` is
1253+ /// measured from the object's start — the `ENUM_DATA_OFFSET` tag skip is
1254+ /// folded in when the op is constructed. When every variant places the
1255+ /// field at one offset, [`MicroOp::HeapReadOffset`] is used instead.
1256+ EnumReadVariantFieldByTag {
12311257 dst : FrameOffset ,
12321258 enum_ref : FrameOffset ,
1233- offset : u32 ,
1259+ // See `EnumBorrowVariantFieldByTag::offsets` for the boxed-slice rationale
1260+ // and the `size_of::<MicroOp>() == 48` constraint.
1261+ offsets : Box < [ Option < u32 > ] > ,
12341262 size : u32 ,
12351263 } ,
12361264
1237- /// Write a variant field by value through an enum reference at a static
1238- /// object-relative `offset` (uniform-offset fast path; see
1239- /// [`MicroOp::EnumReadVariantField`]). Derefs the 16-byte `enum_ref` fat
1240- /// pointer to the heap object, then copies `size` bytes from `src` into
1241- /// `obj + offset`. Fuses `HeapBorrow` + `WriteRef` (the divergent path
1242- /// still routes through a scratch reference).
1243- ///
1244- // TODO(cleanup): nothing here is enum-specific — this writes any field through a
1245- // reference at a static offset, and is reusable when fusing. Rename to a
1246- // non-enum-specific name as part of a naming-consistency pass.
1247- EnumWriteVariantField {
1265+ /// Write a variant field by value through an enum reference, selecting the
1266+ /// field's object byte offset by the runtime variant tag (symmetric
1267+ /// counterpart to [`MicroOp::EnumReadVariantFieldByTag`]). Aborts with a
1268+ /// variant mismatch when `offsets[tag]` is `None`. When every variant
1269+ /// places the field at one offset, [`MicroOp::HeapWriteOffset`] is used
1270+ /// instead.
1271+ EnumWriteVariantFieldByTag {
12481272 enum_ref : FrameOffset ,
1249- offset : u32 ,
1273+ offsets : Box < [ Option < u32 > ] > ,
12501274 src : FrameOffset ,
12511275 size : u32 ,
12521276 } ,
@@ -1944,14 +1968,14 @@ impl fmt::Display for MicroOp {
19441968 dst. 0 , enum_ref. 0 , variant
19451969 )
19461970 } ,
1947- MicroOp :: EnumBorrowVariantField {
1971+ MicroOp :: EnumBorrowVariantFieldByTag {
19481972 dst,
19491973 enum_ref,
19501974 offsets,
19511975 } => {
19521976 write ! (
19531977 f,
1954- "EnumBorrowVariantField [{}] <- &(*[{}]) by tag {:?}" ,
1978+ "EnumBorrowVariantFieldByTag [{}] <- &(*[{}]) by tag {:?}" ,
19551979 dst. 0 , enum_ref. 0 , offsets
19561980 )
19571981 } ,
@@ -1973,28 +1997,52 @@ impl fmt::Display for MicroOp {
19731997 dst. 0 , descriptor_id, variant
19741998 )
19751999 } ,
1976- MicroOp :: EnumReadVariantField {
2000+ MicroOp :: HeapReadOffset {
19772001 dst,
1978- enum_ref ,
2002+ obj_ref ,
19792003 offset,
19802004 size,
19812005 } => {
19822006 write ! (
19832007 f,
1984- "EnumReadVariantField ({}) [{}] <- (*[{}]).{}" ,
1985- size, dst. 0 , enum_ref . 0 , offset
2008+ "HeapReadOffset ({}) [{}] <- (*[{}]).{}" ,
2009+ size, dst. 0 , obj_ref . 0 , offset
19862010 )
19872011 } ,
1988- MicroOp :: EnumWriteVariantField {
1989- enum_ref ,
2012+ MicroOp :: HeapWriteOffset {
2013+ obj_ref ,
19902014 offset,
19912015 src,
19922016 size,
19932017 } => {
19942018 write ! (
19952019 f,
1996- "EnumWriteVariantField({}) (*[{}]).{} <- [{}]" ,
1997- size, enum_ref. 0 , offset, src. 0
2020+ "HeapWriteOffset({}) (*[{}]).{} <- [{}]" ,
2021+ size, obj_ref. 0 , offset, src. 0
2022+ )
2023+ } ,
2024+ MicroOp :: EnumReadVariantFieldByTag {
2025+ dst,
2026+ enum_ref,
2027+ offsets,
2028+ size,
2029+ } => {
2030+ write ! (
2031+ f,
2032+ "EnumReadVariantFieldByTag({}) [{}] <- (*[{}]) by tag {:?}" ,
2033+ size, dst. 0 , enum_ref. 0 , offsets
2034+ )
2035+ } ,
2036+ MicroOp :: EnumWriteVariantFieldByTag {
2037+ enum_ref,
2038+ offsets,
2039+ src,
2040+ size,
2041+ } => {
2042+ write ! (
2043+ f,
2044+ "EnumWriteVariantFieldByTag({}) (*[{}]) <- [{}] by tag {:?}" ,
2045+ size, enum_ref. 0 , src. 0 , offsets
19982046 )
19992047 } ,
20002048 MicroOp :: DeepCopyHeapPtrs { base, offsets } => {
@@ -2267,10 +2315,12 @@ impl MicroOp {
22672315 | MicroOp :: BoolAnd { .. }
22682316 | MicroOp :: BoolOr { .. }
22692317 | MicroOp :: EnumTestTag { .. }
2270- | MicroOp :: EnumBorrowVariantField { .. }
2318+ | MicroOp :: EnumBorrowVariantFieldByTag { .. }
22712319 | MicroOp :: EnumCheckVariant { .. }
2272- | MicroOp :: EnumReadVariantField { .. }
2273- | MicroOp :: EnumWriteVariantField { .. } => false ,
2320+ | MicroOp :: HeapReadOffset { .. }
2321+ | MicroOp :: HeapWriteOffset { .. }
2322+ | MicroOp :: EnumReadVariantFieldByTag { .. }
2323+ | MicroOp :: EnumWriteVariantFieldByTag { .. } => false ,
22742324 }
22752325 }
22762326
@@ -2343,24 +2393,30 @@ impl MicroOp {
23432393 }
23442394 }
23452395
2396+ /// Shift each present data-region-relative offset by [`ENUM_DATA_OFFSET`] to
2397+ /// a full object-relative offset; `None` holes (variants lacking the field)
2398+ /// pass through.
2399+ fn to_object_relative_offsets ( data_relative_offsets : & [ Option < u32 > ] ) -> Box < [ Option < u32 > ] > {
2400+ data_relative_offsets
2401+ . iter ( )
2402+ . map ( |maybe_offset| maybe_offset. map ( |offset| ENUM_DATA_OFFSET as u32 + offset) )
2403+ . collect ( )
2404+ }
2405+
23462406 /// Tag-dispatched variant-field borrow. `data_relative_offsets[tag]` is the
23472407 /// field's data-region-relative offset in that variant, or `None` if the
23482408 /// variant does not declare the field (borrowing it aborts). Offsets are
23492409 /// shifted by `ENUM_DATA_OFFSET` to full object-relative offsets, matching
23502410 /// `enum_borrow`.
2351- pub fn enum_borrow_variant_field (
2411+ pub fn enum_borrow_variant_field_by_tag (
23522412 enum_ref : FrameOffset ,
23532413 data_relative_offsets : & [ Option < u32 > ] ,
23542414 dst : FrameOffset ,
23552415 ) -> Self {
2356- let offsets = data_relative_offsets
2357- . iter ( )
2358- . map ( |maybe_offset| maybe_offset. map ( |offset| ENUM_DATA_OFFSET as u32 + offset) )
2359- . collect ( ) ;
2360- MicroOp :: EnumBorrowVariantField {
2416+ MicroOp :: EnumBorrowVariantFieldByTag {
23612417 dst,
23622418 enum_ref,
2363- offsets,
2419+ offsets : Self :: to_object_relative_offsets ( data_relative_offsets ) ,
23642420 }
23652421 }
23662422
@@ -2380,14 +2436,14 @@ impl MicroOp {
23802436 /// data-region-relative and shifted by `ENUM_DATA_OFFSET` to a full
23812437 /// object-relative offset, matching [`MicroOp::enum_borrow`].
23822438 pub fn enum_read_variant_field (
2383- enum_ref : FrameOffset ,
2439+ obj_ref : FrameOffset ,
23842440 field_offset : u32 ,
23852441 dst : FrameOffset ,
23862442 size : u32 ,
23872443 ) -> Self {
2388- MicroOp :: EnumReadVariantField {
2444+ MicroOp :: HeapReadOffset {
23892445 dst,
2390- enum_ref ,
2446+ obj_ref ,
23912447 offset : ENUM_DATA_OFFSET as u32 + field_offset,
23922448 size,
23932449 }
@@ -2396,19 +2452,54 @@ impl MicroOp {
23962452 /// Uniform-offset variant-field write by value; offset handling mirrors
23972453 /// [`MicroOp::enum_read_variant_field`].
23982454 pub fn enum_write_variant_field (
2399- enum_ref : FrameOffset ,
2455+ obj_ref : FrameOffset ,
24002456 field_offset : u32 ,
24012457 src : FrameOffset ,
24022458 size : u32 ,
24032459 ) -> Self {
2404- MicroOp :: EnumWriteVariantField {
2405- enum_ref ,
2460+ MicroOp :: HeapWriteOffset {
2461+ obj_ref ,
24062462 offset : ENUM_DATA_OFFSET as u32 + field_offset,
24072463 src,
24082464 size,
24092465 }
24102466 }
24112467
2468+ /// Tag-dispatched variant-field read by value. `data_relative_offsets[tag]`
2469+ /// is the field's data-region-relative offset in that variant, or `None`
2470+ /// when the variant lacks the field (reading it aborts). Offsets are shifted
2471+ /// by `ENUM_DATA_OFFSET` to full object-relative offsets, matching
2472+ /// [`MicroOp::enum_borrow_variant_field_by_tag`].
2473+ pub fn enum_read_variant_field_by_tag (
2474+ enum_ref : FrameOffset ,
2475+ data_relative_offsets : & [ Option < u32 > ] ,
2476+ dst : FrameOffset ,
2477+ size : u32 ,
2478+ ) -> Self {
2479+ MicroOp :: EnumReadVariantFieldByTag {
2480+ dst,
2481+ enum_ref,
2482+ offsets : Self :: to_object_relative_offsets ( data_relative_offsets) ,
2483+ size,
2484+ }
2485+ }
2486+
2487+ /// Tag-dispatched variant-field write by value; offset handling mirrors
2488+ /// [`MicroOp::enum_read_variant_field_by_tag`].
2489+ pub fn enum_write_variant_field_by_tag (
2490+ enum_ref : FrameOffset ,
2491+ data_relative_offsets : & [ Option < u32 > ] ,
2492+ src : FrameOffset ,
2493+ size : u32 ,
2494+ ) -> Self {
2495+ MicroOp :: EnumWriteVariantFieldByTag {
2496+ enum_ref,
2497+ offsets : Self :: to_object_relative_offsets ( data_relative_offsets) ,
2498+ src,
2499+ size,
2500+ }
2501+ }
2502+
24122503 /// Deep-copy the owned heap pointers at the given byte offsets within the
24132504 /// value at `base`, making a freshly byte-copied value independent.
24142505 pub fn deep_copy_heap_ptrs ( base : FrameOffset , offsets : Box < [ u32 ] > ) -> Self {
0 commit comments