Skip to content

Commit e0afa31

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

File tree

1 file changed

+43
-4
lines changed

1 file changed

+43
-4
lines changed

webrender_api/src/display_list.rs

Lines changed: 43 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,45 @@ 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+
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
210+
unsafe {
211+
if self.buf.offset(buf.len() as isize) > self.end {
212+
panic!();
213+
}
214+
ptr::copy_nonoverlapping(self.buf, buf.as_mut_ptr(), buf.len());
215+
self.buf = self.buf.offset(buf.len() as isize);
216+
}
217+
Ok(buf.len())
218+
}
219+
}
220+
182221
impl<'a> BuiltDisplayListIter<'a> {
183222
pub fn new(list: &'a BuiltDisplayList) -> Self {
184223
Self::new_with_list_and_data(list, list.item_slice())
@@ -229,7 +268,7 @@ impl<'a> BuiltDisplayListIter<'a> {
229268
return None;
230269
}
231270

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

235274
match self.cur_item.item {
@@ -371,7 +410,7 @@ impl<'de, 'a, T: Deserialize<'de>> AuxIter<'a, T> {
371410
let size: usize = if data.len() == 0 {
372411
0 // Accept empty ItemRanges pointing anywhere
373412
} else {
374-
bincode::deserialize_from(&mut data, bincode::Infinite).expect("MEH: malicious input?")
413+
bincode::deserialize_from(&mut UnsafeReader::new(&mut data), bincode::Infinite).expect("MEH: malicious input?")
375414
};
376415

377416
AuxIter {
@@ -391,7 +430,7 @@ impl<'a, T: for<'de> Deserialize<'de>> Iterator for AuxIter<'a, T> {
391430
} else {
392431
self.size -= 1;
393432
Some(
394-
bincode::deserialize_from(&mut self.data, bincode::Infinite)
433+
bincode::deserialize_from(&mut UnsafeReader::new(&mut self.data), bincode::Infinite)
395434
.expect("MEH: malicious input?"),
396435
)
397436
}

0 commit comments

Comments
 (0)