@@ -563,22 +563,12 @@ impl<Tag, Extra> Allocation<Tag, Extra> {
563
563
564
564
let mut ranges = smallvec:: SmallVec :: < [ u64 ; 1 ] > :: new ( ) ;
565
565
let initial = self . init_mask . get ( range. start ) ;
566
- let mut cur_len = 1 ;
567
- let mut cur = initial;
568
566
569
- for i in 1 ..range. size . bytes ( ) {
570
- // FIXME: optimize to bitshift the current uninitialized block's bits and read the top bit.
571
- if self . init_mask . get ( range. start + Size :: from_bytes ( i) ) == cur {
572
- cur_len += 1 ;
573
- } else {
574
- ranges. push ( cur_len) ;
575
- cur_len = 1 ;
576
- cur = !cur;
577
- }
567
+ for chunk in self . init_mask . range_as_init_chunks ( range. start , range. end ( ) ) {
568
+ let len = chunk. range ( ) . end . bytes ( ) - chunk. range ( ) . start . bytes ( ) ;
569
+ ranges. push ( len) ;
578
570
}
579
571
580
- ranges. push ( cur_len) ;
581
-
582
572
InitMaskCompressed { ranges, initial }
583
573
}
584
574
@@ -830,45 +820,65 @@ impl InitMask {
830
820
}
831
821
}
832
822
823
+ /// A contiguous chunk of initialized or uninitialized memory.
824
+ pub enum InitChunk {
825
+ Init ( Range < Size > ) ,
826
+ Uninit ( Range < Size > ) ,
827
+ }
828
+
829
+ impl InitChunk {
830
+ #[ inline]
831
+ pub fn range ( & self ) -> Range < Size > {
832
+ match self {
833
+ Self :: Init ( r) => r. clone ( ) ,
834
+ Self :: Uninit ( r) => r. clone ( ) ,
835
+ }
836
+ }
837
+ }
838
+
833
839
/// Yields [`InitChunk`]s. See [`InitMask::range_as_init_chunks`].
834
840
pub struct InitChunkIter < ' a > {
835
841
init_mask : & ' a InitMask ,
842
+ /// Whether the last chunk was initialized.
843
+ is_init : bool ,
836
844
/// The current byte index into `init_mask`.
837
845
start : Size ,
838
846
/// The end byte index into `init_mask`.
839
847
end : Size ,
840
848
}
841
849
842
- /// A contiguous chunk of initialized or uninitialized memory.
843
- pub enum InitChunk {
844
- Init ( Range < Size > ) ,
845
- Uninit ( Range < Size > ) ,
846
- }
847
-
848
850
impl < ' a > InitChunkIter < ' a > {
851
+ #[ inline]
849
852
fn new ( init_mask : & ' a InitMask , start : Size , end : Size ) -> Self {
850
853
assert ! ( start <= end) ;
851
854
assert ! ( end <= init_mask. len) ;
852
- Self { init_mask, start, end }
855
+
856
+ let is_init = if start < end { init_mask. get ( start) } else { false } ;
857
+
858
+ Self { init_mask, is_init, start, end }
853
859
}
854
860
}
855
861
856
862
impl < ' a > Iterator for InitChunkIter < ' a > {
857
863
type Item = InitChunk ;
858
864
865
+ #[ inline]
859
866
fn next ( & mut self ) -> Option < Self :: Item > {
860
867
if self . start >= self . end {
861
868
return None ;
862
869
}
863
870
864
- let is_init = self . init_mask . get ( self . start ) ;
865
871
let end_of_chunk =
866
- find_bit ( & self . init_mask , self . start , self . end , !is_init) . unwrap_or ( self . end ) ;
872
+ find_bit ( & self . init_mask , self . start , self . end , !self . is_init ) . unwrap_or ( self . end ) ;
867
873
let range = self . start ..end_of_chunk;
868
874
875
+ let ret =
876
+ Some ( if self . is_init { InitChunk :: Init ( range) } else { InitChunk :: Uninit ( range) } ) ;
877
+
878
+ self . is_init = !self . is_init ;
869
879
self . start = end_of_chunk;
870
880
871
- Some ( if is_init { InitChunk :: Init ( range ) } else { InitChunk :: Uninit ( range ) } )
881
+ ret
872
882
}
873
883
}
874
884
0 commit comments