Move group-free graphic and artboard headers at the promote

This commit is contained in:
Dennis Kobert
2026-09-01 22:51:18 +00:00
parent e415714b04
commit 1f860aae6a
2 changed files with 25 additions and 3 deletions
@@ -74,13 +74,24 @@ unsafe fn deep_repark_artboard(value: &(dyn std::any::Any + Send + Sync), dst: *
} }
/// The promote for `Artboard` elements: as for `Graphic`, content groups the /// The promote for `Artboard` elements: as for `Graphic`, content groups the
/// persistent region already holds are shared rather than copied. /// persistent region already holds are shared rather than copied, and
/// group-free content moves its header instead of copying its heap.
/// ///
/// # Safety /// # Safety
/// `src` must point at a live parked `Artboard` element field, and `dst` at /// `src` must point at a live parked `Artboard` element field, and `dst` at
/// the element field the promoted reference is written to. /// the element field the promoted reference is written to.
unsafe fn promote_artboard(src: *const u8, dst: *mut u8, promotion: &core_types::record::Promotion<'_>) -> Option<()> { unsafe fn promote_artboard(src: *const u8, dst: *mut u8, promotion: &core_types::record::Promotion<'_>) -> Option<()> {
let artboard = unsafe { core_types::record::borrow_element::<Artboard>(core_types::record::Rec::new(src)) }; let artboard = unsafe { core_types::record::borrow_element::<Artboard>(core_types::record::Rec::new(src)) };
if !crate::graphic::list_contains_groups(&artboard.0) {
// SAFETY: a parked element slot holds one reference at offset 0, and
// group-free content owns all of itself.
let header = unsafe { src.cast::<*const u8>().read() };
if let Some(moved) = unsafe { promotion.move_park::<Artboard>(header, 0) } {
// SAFETY: as above, into the promoted image's own element slot.
unsafe { dst.cast::<*const Artboard>().write(moved) };
return Some(());
}
}
let mut content = List::new(); let mut content = List::new();
for item in artboard.0.clone().into_iter() { for item in artboard.0.clone().into_iter() {
let (element, attributes) = item.into_parts(); let (element, attributes) = item.into_parts();
@@ -1220,13 +1220,24 @@ pub fn map_groups_to_persistent<'p>(graphic: &Graphic<'_>, promotion: &core_type
/// The promote for `Graphic` elements: the generic path would deep-copy every /// The promote for `Graphic` elements: the generic path would deep-copy every
/// interior through an owned intermediate, while this shares the interiors the /// interior through an owned intermediate, while this shares the interiors the
/// persistent region already holds. /// persistent region already holds. A group-free graphic references nothing the
/// evaluation owns, so its header moves and its heap is never copied.
/// ///
/// # Safety /// # Safety
/// `src` must point at a live parked `Graphic` element field, and `dst` at the /// `src` must point at a live parked `Graphic` element field, and `dst` at the
/// element field the promoted reference is written to. /// element field the promoted reference is written to.
unsafe fn promote_graphic(src: *const u8, dst: *mut u8, promotion: &core_types::record::Promotion<'_>) -> Option<()> { unsafe fn promote_graphic(src: *const u8, dst: *mut u8, promotion: &core_types::record::Promotion<'_>) -> Option<()> {
let graphic = unsafe { core_types::record::borrow_element::<Graphic>(core_types::record::Rec::new(src)) }; let graphic = unsafe { core_types::record::borrow_element::<Graphic>(core_types::record::Rec::new(src)) };
if !graphic_contains_groups(graphic) {
// SAFETY: a parked element slot holds one reference at offset 0, and a
// group-free graphic owns all of its content.
let header = unsafe { src.cast::<*const u8>().read() };
if let Some(moved) = unsafe { promotion.move_park::<Graphic<'static>>(header, graphic_retained_heap(graphic)) } {
// SAFETY: as above, into the promoted image's own element slot.
unsafe { dst.cast::<*const Graphic<'static>>().write(moved) };
return Some(());
}
}
let promoted = map_groups_to_persistent(graphic, promotion)?; let promoted = map_groups_to_persistent(graphic, promotion)?;
let retained = graphic_retained_heap(&promoted); let retained = graphic_retained_heap(&promoted);
unsafe { core_types::record::write_element_sized(dst, promoted, promotion.persistent(), retained) } unsafe { core_types::record::write_element_sized(dst, promoted, promotion.persistent(), retained) }
@@ -1263,7 +1274,7 @@ fn graphic_contains_groups(graphic: &Graphic) -> bool {
} }
} }
fn list_contains_groups(list: &List<Graphic>) -> bool { pub(crate) fn list_contains_groups(list: &List<Graphic>) -> bool {
(0..list.len()).any(|index| list.element(index).is_some_and(graphic_contains_groups)) (0..list.len()).any(|index| list.element(index).is_some_and(graphic_contains_groups))
} }