@@ -17,6 +17,8 @@ use YuvImageDisplayItem;
1717use bincode;
1818use serde:: { Deserialize , Serialize , Serializer } ;
1919use serde:: ser:: { SerializeMap , SerializeSeq } ;
20+ use std:: io:: Write ;
21+ use std:: { io, ptr} ;
2022use std:: marker:: PhantomData ;
2123use time:: precise_time_ns;
2224
@@ -483,6 +485,72 @@ impl<'a, 'b> Serialize for DisplayItemRef<'a, 'b> {
483485 }
484486}
485487
488+ // This is a replacement for bincode::serialize_into(&vec)
489+ // The default implementation Write for Vec will basically
490+ // call extend_from_slice(). Serde ends up calling that for every
491+ // field of a struct that we're serializing. extend_from_slice()
492+ // does not get inlined and thus we end up calling a generic memcpy()
493+ // implementation. If we instead reserve enough room for the serialized
494+ // struct in the Vec ahead of time we can rely on that and use
495+ // the following UnsafeVecWriter to write into the vec without
496+ // any checks. This writer assumes that size returned by the
497+ // serialize function will not change between calls to serialize_into:
498+ //
499+ // For example, the following struct will cause memory unsafety when
500+ // used with UnsafeVecWriter.
501+ //
502+ // struct S {
503+ // first: Cell<bool>,
504+ // }
505+ //
506+ // impl Serialize for S {
507+ // fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
508+ // where S: Serializer
509+ // {
510+ // if self.first.get() {
511+ // self.first.set(false);
512+ // ().serialize(serializer)
513+ // } else {
514+ // 0.serialize(serializer)
515+ // }
516+ // }
517+ // }
518+ //
519+
520+ struct UnsafeVecWriter < ' a > ( & ' a mut Vec < u8 > ) ;
521+
522+ impl < ' a > Write for UnsafeVecWriter < ' a > {
523+ fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
524+ unsafe {
525+ let old_len = self . 0 . len ( ) ;
526+ self . 0 . set_len ( old_len + buf. len ( ) ) ;
527+ debug_assert ! ( self . 0 . len( ) <= self . 0 . capacity( ) ) ;
528+ ptr:: copy_nonoverlapping ( buf. as_ptr ( ) , self . 0 . as_mut_ptr ( ) . offset ( old_len as isize ) , buf. len ( ) ) ;
529+ }
530+ Ok ( buf. len ( ) )
531+ }
532+ fn flush ( & mut self ) -> io:: Result < ( ) > { Ok ( ( ) ) }
533+ }
534+
535+ struct SizeCounter ( usize ) ;
536+
537+ impl < ' a > Write for SizeCounter {
538+ fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
539+ self . 0 += buf. len ( ) ;
540+ Ok ( buf. len ( ) )
541+ }
542+ fn flush ( & mut self ) -> io:: Result < ( ) > { Ok ( ( ) ) }
543+ }
544+
545+ fn serialize_fast < T : Serialize > ( vec : & mut Vec < u8 > , e : & T ) {
546+ // manually counting the size is faster than vec.reserve(bincode::serialized_size(&e) as usize) for some reason
547+ let mut size = SizeCounter ( 0 ) ;
548+ bincode:: serialize_into ( & mut size, e , bincode:: Infinite ) . unwrap ( ) ;
549+ vec. reserve ( size. 0 ) ;
550+
551+ bincode:: serialize_into ( & mut UnsafeVecWriter ( vec) , e, bincode:: Infinite ) . unwrap ( ) ;
552+ }
553+
486554#[ derive( Clone ) ]
487555pub struct DisplayListBuilder {
488556 pub data : Vec < u8 > ,
@@ -541,28 +609,26 @@ impl DisplayListBuilder {
541609 }
542610
543611 fn push_item ( & mut self , item : SpecificDisplayItem , info : & LayoutPrimitiveInfo ) {
544- bincode :: serialize_into (
612+ serialize_fast (
545613 & mut self . data ,
546614 & DisplayItem {
547615 item,
548616 clip_and_scroll : * self . clip_stack . last ( ) . unwrap ( ) ,
549617 info : * info,
550618 } ,
551- bincode:: Infinite ,
552- ) . unwrap ( ) ;
619+ )
553620 }
554621
555622 fn push_new_empty_item ( & mut self , item : SpecificDisplayItem ) {
556623 let info = LayoutPrimitiveInfo :: new ( LayoutRect :: zero ( ) ) ;
557- bincode :: serialize_into (
624+ serialize_fast (
558625 & mut self . data ,
559626 & DisplayItem {
560627 item,
561628 clip_and_scroll : * self . clip_stack . last ( ) . unwrap ( ) ,
562629 info,
563- } ,
564- bincode:: Infinite ,
565- ) . unwrap ( ) ;
630+ }
631+ )
566632 }
567633
568634 fn push_iter < I > ( & mut self , iter : I )
@@ -575,10 +641,10 @@ impl DisplayListBuilder {
575641 let len = iter. len ( ) ;
576642 let mut count = 0 ;
577643
578- bincode :: serialize_into ( & mut self . data , & len, bincode :: Infinite ) . unwrap ( ) ;
644+ serialize_fast ( & mut self . data , & len) ;
579645 for elem in iter {
580646 count += 1 ;
581- bincode :: serialize_into ( & mut self . data , & elem, bincode :: Infinite ) . unwrap ( ) ;
647+ serialize_fast ( & mut self . data , & elem) ;
582648 }
583649
584650 debug_assert_eq ! ( len, count) ;
@@ -1149,8 +1215,8 @@ impl DisplayListBuilder {
11491215
11501216 // Append glyph data to the end
11511217 for ( ( font_key, color) , sub_glyphs) in glyphs {
1152- bincode :: serialize_into ( & mut self . data , & font_key, bincode :: Infinite ) . unwrap ( ) ;
1153- bincode :: serialize_into ( & mut self . data , & color, bincode :: Infinite ) . unwrap ( ) ;
1218+ serialize_fast ( & mut self . data , & font_key) ;
1219+ serialize_fast ( & mut self . data , & color) ;
11541220 self . push_iter ( sub_glyphs) ;
11551221 }
11561222
0 commit comments