@@ -17,6 +17,8 @@ use YuvImageDisplayItem;
17
17
use bincode;
18
18
use serde:: { Deserialize , Serialize , Serializer } ;
19
19
use serde:: ser:: { SerializeMap , SerializeSeq } ;
20
+ use std:: io:: Write ;
21
+ use std:: { io, ptr} ;
20
22
use std:: marker:: PhantomData ;
21
23
use time:: precise_time_ns;
22
24
@@ -483,6 +485,72 @@ impl<'a, 'b> Serialize for DisplayItemRef<'a, 'b> {
483
485
}
484
486
}
485
487
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
+
486
554
#[ derive( Clone ) ]
487
555
pub struct DisplayListBuilder {
488
556
pub data : Vec < u8 > ,
@@ -541,28 +609,26 @@ impl DisplayListBuilder {
541
609
}
542
610
543
611
fn push_item ( & mut self , item : SpecificDisplayItem , info : & LayoutPrimitiveInfo ) {
544
- bincode :: serialize_into (
612
+ serialize_fast (
545
613
& mut self . data ,
546
614
& DisplayItem {
547
615
item,
548
616
clip_and_scroll : * self . clip_stack . last ( ) . unwrap ( ) ,
549
617
info : * info,
550
618
} ,
551
- bincode:: Infinite ,
552
- ) . unwrap ( ) ;
619
+ )
553
620
}
554
621
555
622
fn push_new_empty_item ( & mut self , item : SpecificDisplayItem ) {
556
623
let info = LayoutPrimitiveInfo :: new ( LayoutRect :: zero ( ) ) ;
557
- bincode :: serialize_into (
624
+ serialize_fast (
558
625
& mut self . data ,
559
626
& DisplayItem {
560
627
item,
561
628
clip_and_scroll : * self . clip_stack . last ( ) . unwrap ( ) ,
562
629
info,
563
- } ,
564
- bincode:: Infinite ,
565
- ) . unwrap ( ) ;
630
+ }
631
+ )
566
632
}
567
633
568
634
fn push_iter < I > ( & mut self , iter : I )
@@ -575,10 +641,10 @@ impl DisplayListBuilder {
575
641
let len = iter. len ( ) ;
576
642
let mut count = 0 ;
577
643
578
- bincode :: serialize_into ( & mut self . data , & len, bincode :: Infinite ) . unwrap ( ) ;
644
+ serialize_fast ( & mut self . data , & len) ;
579
645
for elem in iter {
580
646
count += 1 ;
581
- bincode :: serialize_into ( & mut self . data , & elem, bincode :: Infinite ) . unwrap ( ) ;
647
+ serialize_fast ( & mut self . data , & elem) ;
582
648
}
583
649
584
650
debug_assert_eq ! ( len, count) ;
@@ -1149,8 +1215,8 @@ impl DisplayListBuilder {
1149
1215
1150
1216
// Append glyph data to the end
1151
1217
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) ;
1154
1220
self . push_iter ( sub_glyphs) ;
1155
1221
}
1156
1222
0 commit comments