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 })

`