diff options
| author | Andreas Molzer <andreas.molzer@gmx.de> | 2019-08-30 04:17:18 +0200 |
|---|---|---|
| committer | Andreas Molzer <andreas.molzer@gmx.de> | 2019-08-30 04:17:18 +0200 |
| commit | bee2d3748ef472e416b4a690af89543ed0edd302 (patch) | |
| tree | a846e4a842df99f7e75019bdcd9c4a3fde1c7950 /src/librustc | |
| parent | 6fe31fefd80cd1c4300b03b1e55c63de12134eed (diff) | |
| download | rust-bee2d3748ef472e416b4a690af89543ed0edd302.tar.gz rust-bee2d3748ef472e416b4a690af89543ed0edd302.zip | |
Move relocation range copies into allocation
Diffstat (limited to 'src/librustc')
| -rw-r--r-- | src/librustc/mir/interpret/allocation.rs | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index 75319a67831..8f47bf9d0fd 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -693,6 +693,56 @@ impl<Tag> DerefMut for Relocations<Tag> { } } +/// A partial, owned list of relocations to transfer into another allocation. +pub struct AllocationRelocations<Tag> { + relative_relocations: Vec<(Size, (Tag, AllocId))>, +} + +impl<Tag: Copy, Extra> Allocation<Tag, Extra> { + pub fn prepare_relocation_copy( + &self, + cx: &impl HasDataLayout, + src: Pointer<Tag>, + size: Size, + dest: Pointer<Tag>, + length: u64, + ) -> AllocationRelocations<Tag> { + let relocations = self.get_relocations(cx, src, size); + if relocations.is_empty() { + return AllocationRelocations { relative_relocations: Vec::new() }; + } + + let mut new_relocations = Vec::with_capacity(relocations.len() * (length as usize)); + + for i in 0..length { + new_relocations.extend( + relocations + .iter() + .map(|&(offset, reloc)| { + // compute offset for current repetition + let dest_offset = dest.offset + (i * size); + ( + // shift offsets from source allocation to destination allocation + offset + dest_offset - src.offset, + reloc, + ) + }) + ); + } + + AllocationRelocations { + relative_relocations: new_relocations, + } + } + + pub fn mark_relocation_range( + &mut self, + relocations: AllocationRelocations<Tag>, + ) { + self.relocations.insert_presorted(relocations.relative_relocations); + } +} + //////////////////////////////////////////////////////////////////////////////// // Undefined byte tracking //////////////////////////////////////////////////////////////////////////////// |
