miri: avoid cloning AllocExtra · rust-lang/rust@bc4366b (original) (raw)

`@@ -993,11 +993,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {

`

993

993

` bytes

`

994

994

`}

`

995

995

``

996

``

`` -

/// Find leaked allocations. Allocations reachable from static_roots or a Global allocation

``

997

``

`` -

/// are not considered leaked, as well as leaks whose kind's may_leak() returns true.

``

998

``

`-

pub fn find_leaked_allocations(

`

999

``

`-

&self,

`

1000

``

`-

static_roots: &[AllocId],

`

``

996

`+

/// Find leaked allocations, remove them from memory and return them. Allocations reachable from

`

``

997

`` +

/// static_roots or a Global allocation are not considered leaked, as well as leaks whose

``

``

998

`` +

/// kind's may_leak() returns true.

``

``

999

`+

///

`

``

1000

`+

/// This is highly destructive, no more execution can happen after this!

`

``

1001

`+

pub fn take_leaked_allocations(

`

``

1002

`+

&mut self,

`

``

1003

`+

static_roots: impl FnOnce(&Self) -> &[AllocId],

`

1001

1004

`) -> Vec<(AllocId, MemoryKind<M::MemoryKind>, Allocation<M::Provenance, M::AllocExtra, M::Bytes>)>

`

1002

1005

`{

`

1003

1006

`` // Collect the set of allocations that are reachable from Global allocations.

``

`@@ -1008,7 +1011,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {

`

1008

1011

`self.memory.alloc_map.filter_map_collect(move |&id, &(kind, _)| {

`

1009

1012

`if Some(kind) == global_kind { Some(id) } else { None }

`

1010

1013

`});

`

1011

``

`-

todo.extend(static_roots);

`

``

1014

`+

todo.extend(static_roots(self));

`

1012

1015

`while let Some(id) = todo.pop() {

`

1013

1016

`if reachable.insert(id) {

`

1014

1017

`` // This is a new allocation, add the allocation it points to todo.

``

`@@ -1023,13 +1026,15 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {

`

1023

1026

`};

`

1024

1027

``

1025

1028

`` // All allocations that are not reachable and not may_leak are considered leaking.

``

1026

``

`-

self.memory.alloc_map.filter_map_collect(|id, (kind, alloc)| {

`

1027

``

`-

if kind.may_leak() || reachable.contains(id) {

`

1028

``

`-

None

`

1029

``

`-

} else {

`

1030

``

`-

Some((*id, *kind, alloc.clone()))

`

1031

``

`-

}

`

1032

``

`-

})

`

``

1029

`+

let leaked: Vec<_> = self.memory.alloc_map.filter_map_collect(|&id, &(kind, _)| {

`

``

1030

`+

if kind.may_leak() || reachable.contains(&id) { None } else { Some(id) }

`

``

1031

`+

});

`

``

1032

`+

let mut result = Vec::new();

`

``

1033

`+

for &id in leaked.iter() {

`

``

1034

`+

let (kind, alloc) = self.memory.alloc_map.remove(&id).unwrap();

`

``

1035

`+

result.push((id, kind, alloc));

`

``

1036

`+

}

`

``

1037

`+

result

`

1033

1038

`}

`

1034

1039

``

1035

1040

`/// Runs the closure in "validation" mode, which means the machine's memory read hooks will be

`