From 94e88a5723d15c03824a7af7bb90d8d940fe4c9c Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Fri, 6 Oct 2017 19:10:09 -0400 Subject: [PATCH] Make the writer even more unsafe. Instead of changing the length every write we just adjust the pointer. This avoids https://github.com/rust-lang/rust/issues/45068. However we now need to ensure that we set the length when we are done. With this patch only 1.2% of WebRender display list building is spent in serialization. --- webrender_api/src/display_list.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/webrender_api/src/display_list.rs b/webrender_api/src/display_list.rs index f7f772afbb..0aa7783a93 100644 --- a/webrender_api/src/display_list.rs +++ b/webrender_api/src/display_list.rs @@ -492,15 +492,13 @@ impl<'a, 'b> Serialize for DisplayItemRef<'a, 'b> { // } // -struct UnsafeVecWriter<'a>(&'a mut Vec); +struct UnsafeVecWriter(*mut u8); -impl<'a> Write for UnsafeVecWriter<'a> { +impl Write for UnsafeVecWriter { fn write(&mut self, buf: &[u8]) -> io::Result { unsafe { - let old_len = self.0.len(); - self.0.set_len(old_len + buf.len()); - debug_assert!(self.0.len() <= self.0.capacity()); - ptr::copy_nonoverlapping(buf.as_ptr(), self.0.as_mut_ptr().offset(old_len as isize), buf.len()); + ptr::copy_nonoverlapping(buf.as_ptr(), self.0, buf.len()); + self.0 = self.0.offset(buf.len() as isize); } Ok(buf.len()) } @@ -523,7 +521,16 @@ fn serialize_fast(vec: &mut Vec, e: &T) { bincode::serialize_into(&mut size,e , bincode::Infinite).unwrap(); vec.reserve(size.0); - bincode::serialize_into(&mut UnsafeVecWriter(vec), e, bincode::Infinite).unwrap(); + let old_len = vec.len(); + let ptr = unsafe { vec.as_mut_ptr().offset(old_len as isize) }; + let mut w = UnsafeVecWriter(ptr); + bincode::serialize_into(&mut w, e, bincode::Infinite).unwrap(); + + // fix up the length + unsafe { vec.set_len(old_len + size.0); } + + // make sure we wrote the right amount + debug_assert!(((w.0 as usize) - (vec.as_ptr() as usize)) == vec.len()); } #[derive(Clone)]