@@ -191,27 +191,24 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
191191 // # Pointer-sized provenances
192192 // Get the provenances that are entirely within this range.
193193 // (Different from `range_get_ptrs` which asks if they overlap the range.)
194- let ptrs = if src. size < ptr_size {
195- // This isn't even large enough to contain a pointer.
196- & [ ]
197- } else {
198- let adjusted_end =
199- Size :: from_bytes ( src. end ( ) . bytes ( ) . saturating_sub ( ptr_size. bytes ( ) - 1 ) ) ;
200- self . ptrs . range ( src. start ..adjusted_end)
194+ // Only makes sense if we are copying at least one pointer worth of bytes.
195+ let mut dest_ptrs = Vec :: new ( ) ;
196+ if src. size >= ptr_size {
197+ let adjusted_end = Size :: from_bytes ( src. end ( ) . bytes ( ) - ( ptr_size. bytes ( ) - 1 ) ) ;
198+ let ptrs = self . ptrs . range ( src. start ..adjusted_end) ;
199+ dest_ptrs. reserve_exact ( ptrs. len ( ) * ( count as usize ) ) ;
200+ // If `count` is large, this is rather wasteful -- we are allocating a big array here, which
201+ // is mostly filled with redundant information since it's just N copies of the same `Prov`s
202+ // at slightly adjusted offsets. The reason we do this is so that in `mark_provenance_range`
203+ // we can use `insert_presorted`. That wouldn't work with an `Iterator` that just produces
204+ // the right sequence of provenance for all N copies.
205+ // Basically, this large array would have to be created anyway in the target allocation.
206+ for i in 0 ..count {
207+ dest_ptrs
208+ . extend ( ptrs. iter ( ) . map ( |& ( offset, reloc) | ( shift_offset ( i, offset) , reloc) ) ) ;
209+ }
201210 } ;
202211
203- // Buffer for the new list.
204- let mut dest_ptrs = Vec :: with_capacity ( ptrs. len ( ) * ( count as usize ) ) ;
205- // If `count` is large, this is rather wasteful -- we are allocating a big array here, which
206- // is mostly filled with redundant information since it's just N copies of the same `Prov`s
207- // at slightly adjusted offsets. The reason we do this is so that in `mark_provenance_range`
208- // we can use `insert_presorted`. That wouldn't work with an `Iterator` that just produces
209- // the right sequence of provenance for all N copies.
210- // Basically, this large array would have to be created anyway in the target allocation.
211- for i in 0 ..count {
212- dest_ptrs. extend ( ptrs. iter ( ) . map ( |& ( offset, reloc) | ( shift_offset ( i, offset) , reloc) ) ) ;
213- }
214-
215212 // # Byte-sized provenances
216213 let mut bytes = Vec :: new ( ) ;
217214 // First, if there is a part of a pointer at the start, add that.
@@ -261,10 +258,16 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
261258 trace ! ( "byte provenances: {bytes:?}" ) ;
262259
263260 // And again a buffer for the new list on the target side.
264- let mut dest_bytes = Vec :: with_capacity ( bytes. len ( ) * ( count as usize ) ) ;
265- for i in 0 ..count {
266- dest_bytes
267- . extend ( bytes. iter ( ) . map ( |& ( offset, reloc) | ( shift_offset ( i, offset) , reloc) ) ) ;
261+ let mut dest_bytes = Vec :: new ( ) ;
262+ if Prov :: OFFSET_IS_ADDR {
263+ dest_bytes. reserve_exact ( bytes. len ( ) * ( count as usize ) ) ;
264+ for i in 0 ..count {
265+ dest_bytes
266+ . extend ( bytes. iter ( ) . map ( |& ( offset, reloc) | ( shift_offset ( i, offset) , reloc) ) ) ;
267+ }
268+ } else {
269+ // There can't be any bytewise provenance when OFFSET_IS_ADDR is false.
270+ debug_assert ! ( bytes. is_empty( ) ) ;
268271 }
269272
270273 Ok ( ProvenanceCopy { dest_ptrs, dest_bytes } )
0 commit comments