use crate::region::Region;
use crate::relocator::ForwardingTable;
pub fn fixup_roots(
forwarding: &ForwardingTable,
trace_roots: &mut dyn FnMut(&mut dyn FnMut(*mut u8, &mut *mut u8)),
) {
trace_roots(&mut |old_ptr, slot| {
if let Some(new_ptr) = forwarding.lookup(old_ptr) {
*slot = new_ptr;
}
});
}
pub fn fixup_region(region: &mut Region, _forwarding: &ForwardingTable) {
region.for_each_object_mut(|header, _obj_ptr| {
if header.size == 0 {
return;
}
});
}
#[inline]
pub fn fixup_ptr(ptr: *mut u8, forwarding: &ForwardingTable) -> *mut u8 {
if let Some(new) = forwarding.lookup(ptr) {
new
} else {
ptr
}
}
#[inline]
pub fn fixup_nanboxed_bits(bits: &mut u64, forwarding: &ForwardingTable) {
const TAG_BASE: u64 = 0xFFF8_0000_0000_0000;
const PAYLOAD_MASK: u64 = 0x0000_FFFF_FFFF_FFFF;
const TAG_MASK: u64 = 0x0007_0000_0000_0000;
const TAG_SHIFT: u32 = 48;
const TAG_HEAP: u64 = 0b000;
let is_tagged = (*bits & TAG_BASE) == TAG_BASE;
if !is_tagged {
return;
}
let tag = (*bits & TAG_MASK) >> TAG_SHIFT;
if tag != TAG_HEAP {
return;
}
const HEAP_PTR_MASK: u64 = !1;
let owned_bit = *bits & 1;
let old_ptr = (*bits & PAYLOAD_MASK & HEAP_PTR_MASK) as *mut u8;
if old_ptr.is_null() {
return;
}
if let Some(new_ptr) = forwarding.lookup(old_ptr) {
let new_payload = ((new_ptr as u64) & PAYLOAD_MASK) | owned_bit;
*bits = (*bits & !PAYLOAD_MASK) | new_payload;
}
}