diff --git a/components/servo_arc/lib.rs b/components/servo_arc/lib.rs index 5d91c9bc44f..8c3c033a8de 100644 --- a/components/servo_arc/lib.rs +++ b/components/servo_arc/lib.rs @@ -481,6 +481,8 @@ impl Arc> { // // To avoid alignment issues, we allocate words rather than bytes, // rounding up to the nearest word size. + assert!(mem::align_of::() <= mem::align_of::(), + "We don't handle over-aligned types"); let words_to_allocate = divide_rounding_up(size, size_of::()); let mut vec = Vec::::with_capacity(words_to_allocate); vec.set_len(words_to_allocate); @@ -496,6 +498,9 @@ impl Arc> { ptr = fake_slice as *mut [T] as *mut ArcInner>; // Write the data. + // + // Note that any panics here (i.e. from the iterator) are safe, since + // we'll just leak the uninitialized memory. ptr::write(&mut ((*ptr).count), atomic::AtomicUsize::new(1)); ptr::write(&mut ((*ptr).data.header), header); let mut current: *mut T = &mut (*ptr).data.slice[0]; @@ -536,8 +541,9 @@ impl HeaderWithLength { } } +type HeaderSliceWithLength = HeaderSlice, T>; pub struct ThinArc { - ptr: *mut ArcInner, [T; 1]>>, + ptr: *mut ArcInner>, } unsafe impl Send for ThinArc {} @@ -546,15 +552,15 @@ unsafe impl Sync for ThinArc {} // Synthesize a fat pointer from a thin pointer. // // See the comment around the analogous operation in from_header_and_iter. -fn thin_to_thick(thin: *mut ArcInner, [T; 1]>>) - -> *mut ArcInner, [T]>> +fn thin_to_thick(thin: *mut ArcInner>) + -> *mut ArcInner> { let len = unsafe { (*thin).data.header.length }; let fake_slice: *mut [T] = unsafe { slice::from_raw_parts_mut(thin as *mut T, len) }; - fake_slice as *mut ArcInner, [T]>> + fake_slice as *mut ArcInner> } impl ThinArc { @@ -562,7 +568,7 @@ impl ThinArc { /// provided callback. The refcount is not modified. #[inline(always)] pub fn with_arc(&self, f: F) -> U - where F: FnOnce(&Arc, [T]>>) -> U + where F: FnOnce(&Arc>) -> U { // Synthesize transient Arc, which never touches the refcount of the ArcInner. let transient = NoDrop::new(Arc { @@ -581,7 +587,7 @@ impl ThinArc { } impl Deref for ThinArc { - type Target = HeaderSlice, [T]>; + type Target = HeaderSliceWithLength; fn deref(&self) -> &Self::Target { unsafe { &(*thin_to_thick(self.ptr)).data } } @@ -599,17 +605,17 @@ impl Drop for ThinArc { } } -impl Arc, [T]>> { +impl Arc> { /// Converts an Arc into a ThinArc. This consumes the Arc, so the refcount /// is not modified. pub fn into_thin(a: Self) -> ThinArc { assert!(a.header.length == a.slice.len(), "Length needs to be correct for ThinArc to work"); - let fat_ptr: *mut ArcInner, [T]>> = a.ptr; + let fat_ptr: *mut ArcInner> = a.ptr; mem::forget(a); let thin_ptr = fat_ptr as *mut [usize] as *mut usize; ThinArc { - ptr: thin_ptr as *mut ArcInner, [T; 1]>> + ptr: thin_ptr as *mut ArcInner> } } @@ -649,13 +655,7 @@ mod tests { impl Drop for Canary { fn drop(&mut self) { - unsafe { - match *self { - Canary(c) => { - (*c).fetch_add(1, SeqCst); - } - } - } + unsafe { (*self.0).fetch_add(1, SeqCst); } } }