# HG changeset patch # User alfadur # Date 1569529411 -10800 # Node ID a027e60d7820cfde736b4bbd2bb394167c7e05be # Parent a6699f4a3d16bca4d9a7f2296d15290132a0d2f2 fix alignments of the component slices diff -r a6699f4a3d16 -r a027e60d7820 rust/hwphysics/src/data.rs --- a/rust/hwphysics/src/data.rs Thu Sep 26 22:31:06 2019 +0300 +++ b/rust/hwphysics/src/data.rs Thu Sep 26 23:23:31 2019 +0300 @@ -3,7 +3,7 @@ any::TypeId, fmt::{Debug, Error, Formatter}, marker::PhantomData, - mem::{size_of, MaybeUninit}, + mem::{align_of, size_of, MaybeUninit}, num::NonZeroU16, ptr::{copy_nonoverlapping, null_mut, NonNull}, slice, @@ -117,26 +117,39 @@ } impl DataBlock { - fn new(mask: u64, element_sizes: &[u16]) -> Self { + fn new(mask: u64, element_sizes: &[u16], element_alignments: &[u8]) -> Self { + let total_padding: usize = element_alignments.iter().map(|x| *x as usize).sum(); let total_size: u16 = element_sizes .iter() .enumerate() .filter(|(i, _)| mask & (1 << *i as u64) != 0) .map(|(_, size)| *size) .sum(); - let max_elements = (BLOCK_SIZE / (total_size as usize + size_of::())) as u16; + let max_elements = + ((BLOCK_SIZE - total_padding) / (total_size as usize + size_of::())) as u16; + //ensure the block memory is aligned to GearId + let tmp_data: Box<[GearId; BLOCK_SIZE / size_of::()]> = + Box::new(unsafe { MaybeUninit::uninit().assume_init() }); let mut data: Box<[u8; BLOCK_SIZE]> = - Box::new(unsafe { MaybeUninit::uninit().assume_init() }); + unsafe { Box::from_raw(Box::into_raw(tmp_data) as *mut [u8; BLOCK_SIZE]) }; + let mut blocks = [None; 64]; - let mut offset = size_of::() * max_elements as usize; + let mut address = unsafe { + data.as_mut_ptr() + .add(size_of::() * max_elements as usize) + }; for i in 0..element_sizes.len() { if mask & (1 << i as u64) != 0 { - blocks[i] = Some(NonNull::new(data[offset..].as_mut_ptr()).unwrap()); - offset += element_sizes[i] as usize * max_elements as usize; + unsafe { + address = address.add(address.align_offset(element_alignments[i] as usize)); + blocks[i] = Some(NonNull::new_unchecked(address)); + address = address.add(element_sizes[i] as usize * max_elements as usize) + }; } } + Self { elements_count: 0, max_elements, @@ -216,6 +229,7 @@ blocks: Vec, block_masks: Vec, element_sizes: Box<[u16; 64]>, + element_alignments: Box<[u8; 64]>, lookup: Box<[LookupEntry]>, } @@ -227,6 +241,7 @@ blocks: vec![], block_masks: vec![], element_sizes: Box::new([0; 64]), + element_alignments: Box::new([0; 64]), lookup: vec![LookupEntry::default(); u16::max_value() as usize].into_boxed_slice(), } } @@ -388,6 +403,7 @@ self.blocks.push(DataBlock::new( mask.type_mask, &self.element_sizes[0..self.types.len()], + &self.element_alignments[0..self.types.len()], )); self.block_masks.push(mask); (self.blocks.len() - 1) as u16 @@ -482,6 +498,7 @@ if !self.types.contains(&id) { debug_assert!(self.types.len() <= 64); self.element_sizes[self.types.len()] = size_of::() as u16; + self.element_alignments[self.types.len()] = align_of::() as u8; self.types.push(id); } }