diff options
| -rw-r--r-- | compiler/rustc_data_structures/src/sorted_map.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs | 26 |
2 files changed, 17 insertions, 11 deletions
diff --git a/compiler/rustc_data_structures/src/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs index c3c173b3fc4..15e3e6ea4c3 100644 --- a/compiler/rustc_data_structures/src/sorted_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map.rs @@ -249,7 +249,7 @@ impl<K: Ord, V> SortedMap<K, V> { } }; - // Insert the rest + // Insert the rest. This is super inefficicent since each insertion copies the entire tail. for (k, v) in elements { self.insert(k, v); } diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs index 46f28328aeb..67baf63bbfa 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs @@ -376,18 +376,24 @@ impl<Prov: Provenance> ProvenanceMap<Prov> { pub fn apply_copy(&mut self, copy: ProvenanceCopy<Prov>, range: AllocRange, repeat: u64) { let shift_offset = |idx: u64, offset: Size| offset + range.start + idx * range.size; if !copy.ptrs.is_empty() { - for i in 0..repeat { - self.ptrs.insert_presorted( - copy.ptrs.iter().map(|&(offset, reloc)| (shift_offset(i, offset), reloc)), - ); - } + // We want to call `insert_presorted` only once so that, if possible, the entries + // after the range we insert are moved back only once. + let chunk_len = copy.ptrs.len() as u64; + self.ptrs.insert_presorted((0..chunk_len * repeat).map(|i| { + let chunk = i / chunk_len; + let (offset, reloc) = copy.ptrs[(i % chunk_len) as usize]; + (shift_offset(chunk, offset), reloc) + })); } if !copy.bytes.is_empty() { - for i in 0..repeat { - self.bytes.get_or_insert_with(Box::default).insert_presorted( - copy.bytes.iter().map(|&(offset, reloc)| (shift_offset(i, offset), reloc)), - ); - } + let chunk_len = copy.bytes.len() as u64; + self.bytes.get_or_insert_with(Box::default).insert_presorted( + (0..chunk_len * repeat).map(|i| { + let chunk = i / chunk_len; + let (offset, reloc) = copy.bytes[(i % chunk_len) as usize]; + (shift_offset(chunk, offset), reloc) + }), + ); } } } |
