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

View File

@@ -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
/// 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
/// `src` must point at a live parked `Artboard` element field, and `dst` at
/// 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<()> {
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();
for item in artboard.0.clone().into_iter() {
let (element, attributes) = item.into_parts();

View File

@@ -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
/// 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
/// `src` must point at a live parked `Graphic` element field, and `dst` at the
/// element field the promoted reference is written to.
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)) };
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 retained = graphic_retained_heap(&promoted);
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))
}