@@ -191,27 +191,24 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
191
191
// # Pointer-sized provenances
192
192
// Get the provenances that are entirely within this range.
193
193
// (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
+ }
201
210
} ;
202
211
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
-
215
212
// # Byte-sized provenances
216
213
let mut bytes = Vec :: new ( ) ;
217
214
// First, if there is a part of a pointer at the start, add that.
@@ -261,10 +258,16 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
261
258
trace ! ( "byte provenances: {bytes:?}" ) ;
262
259
263
260
// 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( ) ) ;
268
271
}
269
272
270
273
Ok ( ProvenanceCopy { dest_ptrs, dest_bytes } )
0 commit comments