@@ -100,8 +100,7 @@ impl AllocationExtra<(), ()> for () {
100
100
impl < Tag , Extra > Allocation < Tag , Extra > {
101
101
/// Creates a read-only allocation initialized by the given bytes
102
102
pub fn from_bytes ( slice : & [ u8 ] , align : Align , extra : Extra ) -> Self {
103
- let mut undef_mask = UndefMask :: new ( Size :: ZERO ) ;
104
- undef_mask. grow ( Size :: from_bytes ( slice. len ( ) as u64 ) , true ) ;
103
+ let undef_mask = UndefMask :: new ( Size :: from_bytes ( slice. len ( ) as u64 ) , true ) ;
105
104
Self {
106
105
bytes : slice. to_owned ( ) ,
107
106
relocations : Relocations :: new ( ) ,
@@ -121,7 +120,7 @@ impl<Tag, Extra> Allocation<Tag, Extra> {
121
120
Allocation {
122
121
bytes : vec ! [ 0 ; size. bytes( ) as usize ] ,
123
122
relocations : Relocations :: new ( ) ,
124
- undef_mask : UndefMask :: new ( size) ,
123
+ undef_mask : UndefMask :: new ( size, false ) ,
125
124
align,
126
125
mutability : Mutability :: Mutable ,
127
126
extra,
@@ -625,12 +624,12 @@ impl_stable_hash_for!(struct mir::interpret::UndefMask{blocks, len});
625
624
impl UndefMask {
626
625
pub const BLOCK_SIZE : u64 = 64 ;
627
626
628
- pub fn new ( size : Size ) -> Self {
627
+ pub fn new ( size : Size , state : bool ) -> Self {
629
628
let mut m = UndefMask {
630
629
blocks : vec ! [ ] ,
631
630
len : Size :: ZERO ,
632
631
} ;
633
- m. grow ( size, false ) ;
632
+ m. grow ( size, state ) ;
634
633
m
635
634
}
636
635
@@ -667,25 +666,40 @@ impl UndefMask {
667
666
let ( blocka, bita) = bit_index ( start) ;
668
667
let ( blockb, bitb) = bit_index ( end) ;
669
668
if blocka == blockb {
670
- // within a single block
671
- for i in bita .. bitb {
672
- self . set_bit ( blocka, i, new_state) ;
669
+ // first set all bits but the first `bita`
670
+ // then unset the last `64 - bitb` bits
671
+ let range = if bitb == 0 {
672
+ u64:: max_value ( ) << bita
673
+ } else {
674
+ ( u64:: max_value ( ) << bita) & ( u64:: max_value ( ) >> ( 64 - bitb) )
675
+ } ;
676
+ if new_state {
677
+ self . blocks [ blocka] |= range;
678
+ } else {
679
+ self . blocks [ blocka] &= !range;
673
680
}
674
681
return ;
675
682
}
676
683
// across block boundaries
677
- for i in bita .. Self :: BLOCK_SIZE as usize {
678
- self . set_bit ( blocka, i, new_state) ;
679
- }
680
- for i in 0 .. bitb {
681
- self . set_bit ( blockb, i, new_state) ;
682
- }
683
- // fill in all the other blocks (much faster than one bit at a time)
684
684
if new_state {
685
+ // set bita..64 to 1
686
+ self . blocks [ blocka] |= u64:: max_value ( ) << bita;
687
+ // set 0..bitb to 1
688
+ if bitb != 0 {
689
+ self . blocks [ blockb] |= u64:: max_value ( ) >> ( 64 - bitb) ;
690
+ }
691
+ // fill in all the other blocks (much faster than one bit at a time)
685
692
for block in ( blocka + 1 ) .. blockb {
686
693
self . blocks [ block] = u64:: max_value ( ) ;
687
694
}
688
695
} else {
696
+ // set bita..64 to 0
697
+ self . blocks [ blocka] &= !( u64:: max_value ( ) << bita) ;
698
+ // set 0..bitb to 0
699
+ if bitb != 0 {
700
+ self . blocks [ blockb] &= !( u64:: max_value ( ) >> ( 64 - bitb) ) ;
701
+ }
702
+ // fill in all the other blocks (much faster than one bit at a time)
689
703
for block in ( blocka + 1 ) .. blockb {
690
704
self . blocks [ block] = 0 ;
691
705
}
@@ -695,7 +709,7 @@ impl UndefMask {
695
709
#[ inline]
696
710
pub fn get ( & self , i : Size ) -> bool {
697
711
let ( block, bit) = bit_index ( i) ;
698
- ( self . blocks [ block] & 1 << bit) != 0
712
+ ( self . blocks [ block] & ( 1 << bit) ) != 0
699
713
}
700
714
701
715
#[ inline]
@@ -714,6 +728,9 @@ impl UndefMask {
714
728
}
715
729
716
730
pub fn grow ( & mut self , amount : Size , new_state : bool ) {
731
+ if amount. bytes ( ) == 0 {
732
+ return ;
733
+ }
717
734
let unused_trailing_bits = self . blocks . len ( ) as u64 * Self :: BLOCK_SIZE - self . len . bytes ( ) ;
718
735
if amount. bytes ( ) > unused_trailing_bits {
719
736
let additional_blocks = amount. bytes ( ) / Self :: BLOCK_SIZE + 1 ;
0 commit comments