Skip to content

Commit 370ff2f

Browse files
committed
WIP: Improve deserialization performance
1 parent 94e88a5 commit 370ff2f

File tree

1 file changed

+55
-4
lines changed

1 file changed

+55
-4
lines changed

webrender_api/src/display_list.rs

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use YuvImageDisplayItem;
1717
use bincode;
1818
use serde::{Deserialize, Serialize, Serializer};
1919
use serde::ser::{SerializeMap, SerializeSeq};
20-
use std::io::Write;
20+
use std::io::{Read, Write};
2121
use std::{io, ptr};
2222
use std::marker::PhantomData;
2323
use time::precise_time_ns;
@@ -179,6 +179,57 @@ fn skip_slice<T: for<'de> Deserialize<'de>>(
179179
(range, count)
180180
}
181181

182+
struct UnsafeReader<'a: 'b, 'b> {
183+
buf: *const u8,
184+
end: *const u8,
185+
slice: &'b mut &'a [u8]
186+
}
187+
188+
impl<'a, 'b> UnsafeReader<'a, 'b> {
189+
fn new(buf: &'b mut &'a [u8]) -> UnsafeReader<'a, 'b> {
190+
unsafe {
191+
let end = buf.as_ptr().offset(buf.len() as isize);
192+
let start = buf.as_ptr();
193+
UnsafeReader { buf: start, end, slice: buf }
194+
}
195+
}
196+
}
197+
198+
use std::slice;
199+
200+
impl<'a, 'b> Drop for UnsafeReader<'a, 'b> {
201+
fn drop(&mut self) {
202+
unsafe {
203+
*self.slice = slice::from_raw_parts(self.buf, (self.end as usize) - (self.buf as usize));
204+
}
205+
}
206+
}
207+
208+
impl<'a, 'b> Read for UnsafeReader<'a, 'b> {
209+
#[inline(always)]
210+
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
211+
unsafe {
212+
if self.buf.offset(buf.len() as isize) > self.end {
213+
panic!();
214+
}
215+
ptr::copy_nonoverlapping(self.buf, buf.as_mut_ptr(), buf.len());
216+
self.buf = self.buf.offset(buf.len() as isize);
217+
}
218+
Ok(buf.len())
219+
}
220+
#[inline(always)]
221+
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
222+
unsafe {
223+
if self.buf.offset(buf.len() as isize) > self.end {
224+
panic!();
225+
}
226+
ptr::copy_nonoverlapping(self.buf, buf.as_mut_ptr(), buf.len());
227+
self.buf = self.buf.offset(buf.len() as isize);
228+
}
229+
Ok(())
230+
}
231+
}
232+
182233
impl<'a> BuiltDisplayListIter<'a> {
183234
pub fn new(list: &'a BuiltDisplayList) -> Self {
184235
Self::new_with_list_and_data(list, list.item_slice())
@@ -229,7 +280,7 @@ impl<'a> BuiltDisplayListIter<'a> {
229280
return None;
230281
}
231282

232-
self.cur_item = bincode::deserialize_from(&mut self.data, bincode::Infinite)
283+
self.cur_item = bincode::deserialize_from(&mut UnsafeReader::new(&mut self.data), bincode::Infinite)
233284
.expect("MEH: malicious process?");
234285

235286
match self.cur_item.item {
@@ -371,7 +422,7 @@ impl<'de, 'a, T: Deserialize<'de>> AuxIter<'a, T> {
371422
let size: usize = if data.len() == 0 {
372423
0 // Accept empty ItemRanges pointing anywhere
373424
} else {
374-
bincode::deserialize_from(&mut data, bincode::Infinite).expect("MEH: malicious input?")
425+
bincode::deserialize_from(&mut UnsafeReader::new(&mut data), bincode::Infinite).expect("MEH: malicious input?")
375426
};
376427

377428
AuxIter {
@@ -391,7 +442,7 @@ impl<'a, T: for<'de> Deserialize<'de>> Iterator for AuxIter<'a, T> {
391442
} else {
392443
self.size -= 1;
393444
Some(
394-
bincode::deserialize_from(&mut self.data, bincode::Infinite)
445+
bincode::deserialize_from(&mut UnsafeReader::new(&mut self.data), bincode::Infinite)
395446
.expect("MEH: malicious input?"),
396447
)
397448
}

0 commit comments

Comments
 (0)