about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndreas Molzer <andreas.molzer@gmx.de>2019-08-30 04:17:18 +0200
committerAndreas Molzer <andreas.molzer@gmx.de>2019-08-30 04:17:18 +0200
commitbee2d3748ef472e416b4a690af89543ed0edd302 (patch)
treea846e4a842df99f7e75019bdcd9c4a3fde1c7950
parent6fe31fefd80cd1c4300b03b1e55c63de12134eed (diff)
downloadrust-bee2d3748ef472e416b4a690af89543ed0edd302.tar.gz
rust-bee2d3748ef472e416b4a690af89543ed0edd302.zip
Move relocation range copies into allocation
-rw-r--r--src/librustc/mir/interpret/allocation.rs50
-rw-r--r--src/librustc_mir/interpret/memory.rs30
2 files changed, 53 insertions, 27 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
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 26b3f0be8c2..6e0d77235fe 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -808,32 +808,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         // since we don't want to keep any relocations at the target.
         // (`get_bytes_with_undef_and_ptr` below checks that there are no
         // relocations overlapping the edges; those would not be handled correctly).
-        let relocations = {
-            let relocations = self.get(src.alloc_id)?.get_relocations(self, src, size);
-            if relocations.is_empty() {
-                // nothing to copy, ignore even the `length` loop
-                Vec::new()
-            } else {
-                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,
-                            )
-                        })
-                    );
-                }
-
-                new_relocations
-            }
-        };
+        let relocations = self.get(src.alloc_id)?
+            .prepare_relocation_copy(self, src, size, dest, length);
 
         let tcx = self.tcx.tcx;
 
@@ -880,7 +856,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         // copy definedness to the destination
         self.copy_undef_mask(src, dest, size, length)?;
         // copy the relocations to the destination
-        self.get_mut(dest.alloc_id)?.relocations.insert_presorted(relocations);
+        self.get_mut(dest.alloc_id)?.mark_relocation_range(relocations);
 
         Ok(())
     }