differentiate between layout and alloc_layout · rust-lang/rust@1b374df (original) (raw)
`@@ -13,7 +13,10 @@ pub struct MiriAllocBytes {
`
13
13
`/// Stored layout information about the allocation.
`
14
14
`layout: alloc::Layout,
`
15
15
`/// Pointer to the allocation contents.
`
16
``
`` -
/// Invariant: self.ptr
points to memory allocated with self.layout
.
``
``
16
`+
/// Invariant:
`
``
17
`` +
/// * If self.layout.size() == 0
, then self.ptr
is some suitably aligned pointer
``
``
18
`` +
/// that was allocated with the same layout but size == 1
.
``
``
19
`` +
/// * Otherwise, self.ptr
points to memory allocated with self.layout
.
``
17
20
`ptr: *mut u8,
`
18
21
`}
`
19
22
``
`@@ -27,8 +30,13 @@ impl Clone for MiriAllocBytes {
`
27
30
``
28
31
`impl Drop for MiriAllocBytes {
`
29
32
`fn drop(&mut self) {
`
``
33
`+
let alloc_layout = if self.layout.size() == 0 {
`
``
34
`+
Layout::from_size_align(1, self.layout.align()).unwrap()
`
``
35
`+
} else {
`
``
36
`+
self.layout
`
``
37
`+
};
`
30
38
`` // SAFETY: Invariant, self.ptr
points to memory allocated with self.layout
.
``
31
``
`-
unsafe { alloc::dealloc(self.ptr, self.layout) }
`
``
39
`+
unsafe { alloc::dealloc(self.ptr, alloc_layout) }
`
32
40
`}
`
33
41
`}
`
34
42
``
`@@ -51,21 +59,21 @@ impl std::ops::DerefMut for MiriAllocBytes {
`
51
59
`}
`
52
60
``
53
61
`impl MiriAllocBytes {
`
54
``
`` -
/// This method factors out how a MiriAllocBytes
object is allocated,
``
55
``
`` -
/// specifically given an allocation function alloc_fn
.
``
56
``
`` -
/// alloc_fn
is only used with size != 0
.
``
57
``
`` -
/// Returns Err(layout)
if the allocation function returns a ptr
where ptr.is_null()
.
``
``
62
`` +
/// This method factors out how a MiriAllocBytes
object is allocated, given a specific allocation function.
``
``
63
`` +
/// If size == 0
we allocate using a different alloc_layout
with size = 1
, to ensure each allocation has a unique address.
``
``
64
`` +
/// Returns Err(alloc_layout)
if the allocation function returns a ptr
where ptr.is_null()
.
``
58
65
`fn alloc_with(
`
59
66
`size: usize,
`
60
67
`align: usize,
`
61
68
`alloc_fn: impl FnOnce(Layout) -> *mut u8,
`
62
69
`) -> Result<MiriAllocBytes, Layout> {
`
63
``
`-
// When size is 0 we allocate 1 byte anyway, so addresses don't possibly overlap.
`
64
``
`-
let size = if size == 0 { 1 } else { size };
`
65
70
`let layout = Layout::from_size_align(size, align).unwrap();
`
66
``
`-
let ptr = alloc_fn(layout);
`
``
71
`+
// When size is 0 we allocate 1 byte anyway, to ensure each allocation has a unique address.
`
``
72
`+
let alloc_layout =
`
``
73
`+
if size == 0 { Layout::from_size_align(1, align).unwrap() } else { layout };
`
``
74
`+
let ptr = alloc_fn(alloc_layout);
`
67
75
`if ptr.is_null() {
`
68
``
`-
Err(layout)
`
``
76
`+
Err(alloc_layout)
`
69
77
`} else {
`
70
78
`` // SAFETY: All MiriAllocBytes
invariants are fulfilled.
``
71
79
`Ok(Self { ptr, layout })
`