11use  std:: alloc:: Layout ; 
22use  std:: borrow:: Cow ; 
33use  std:: { alloc,  slice} ; 
4+ #[ cfg( target_os = "linux" ) ]  
5+ use  std:: { cell:: RefCell ,  rc:: Rc } ; 
46
57use  rustc_abi:: { Align ,  Size } ; 
68use  rustc_middle:: mir:: interpret:: AllocBytes ; 
79
10+ #[ cfg( target_os = "linux" ) ]  
11+ use  crate :: alloc:: isolated_alloc:: IsolatedAlloc ; 
812use  crate :: helpers:: ToU64  as  _; 
913
14+ #[ derive( Clone ,  Debug ) ]  
15+ pub  enum  MiriAllocParams  { 
16+     Global , 
17+     #[ cfg( target_os = "linux" ) ]  
18+     Isolated ( Rc < RefCell < IsolatedAlloc > > ) , 
19+ } 
20+ 
1021/// Allocation bytes that explicitly handle the layout of the data they're storing. 
1122/// This is necessary to interface with native code that accesses the program store in Miri. 
1223#[ derive( Debug ) ]  
@@ -18,13 +29,16 @@ pub struct MiriAllocBytes {
1829/// * If `self.layout.size() == 0`, then `self.ptr` was allocated with the equivalent layout with size 1. 
1930/// * Otherwise, `self.ptr` points to memory allocated with `self.layout`. 
2031ptr :  * mut  u8 , 
32+     /// Whether this instance of `MiriAllocBytes` had its allocation created by calling `alloc::alloc()` 
33+ /// (`Global`) or the discrete allocator (`Isolated`) 
34+ params :  MiriAllocParams , 
2135} 
2236
2337impl  Clone  for  MiriAllocBytes  { 
2438    fn  clone ( & self )  -> Self  { 
2539        let  bytes:  Cow < ' _ ,  [ u8 ] >  = Cow :: Borrowed ( self ) ; 
2640        let  align = Align :: from_bytes ( self . layout . align ( ) . to_u64 ( ) ) . unwrap ( ) ; 
27-         MiriAllocBytes :: from_bytes ( bytes,  align,  ( ) ) 
41+         MiriAllocBytes :: from_bytes ( bytes,  align,  self . params . clone ( ) ) 
2842    } 
2943} 
3044
@@ -37,8 +51,16 @@ impl Drop for MiriAllocBytes {
3751        }  else  { 
3852            self . layout 
3953        } ; 
54+ 
4055        // SAFETY: Invariant, `self.ptr` points to memory allocated with `self.layout`. 
41-         unsafe  {  alloc:: dealloc ( self . ptr ,  alloc_layout)  } 
56+         unsafe  { 
57+             match  self . params . clone ( )  { 
58+                 MiriAllocParams :: Global  => alloc:: dealloc ( self . ptr ,  alloc_layout) , 
59+                 #[ cfg( target_os = "linux" ) ]  
60+                 MiriAllocParams :: Isolated ( alloc)  =>
61+                     alloc. borrow_mut ( ) . dealloc ( self . ptr ,  alloc_layout) , 
62+             } 
63+         } 
4264    } 
4365} 
4466
@@ -67,35 +89,45 @@ impl MiriAllocBytes {
6789fn  alloc_with ( 
6890        size :  u64 , 
6991        align :  u64 , 
70-         alloc_fn :  impl  FnOnce ( Layout )  -> * mut  u8 , 
92+         params :  MiriAllocParams , 
93+         alloc_fn :  impl  FnOnce ( Layout ,  & MiriAllocParams )  -> * mut  u8 , 
7194    )  -> Result < MiriAllocBytes ,  ( ) >  { 
7295        let  size = usize:: try_from ( size) . map_err ( |_| ( ) ) ?; 
7396        let  align = usize:: try_from ( align) . map_err ( |_| ( ) ) ?; 
7497        let  layout = Layout :: from_size_align ( size,  align) . map_err ( |_| ( ) ) ?; 
7598        // When size is 0 we allocate 1 byte anyway, to ensure each allocation has a unique address. 
7699        let  alloc_layout =
77100            if  size == 0  {  Layout :: from_size_align ( 1 ,  align) . unwrap ( )  }  else  {  layout } ; 
78-         let  ptr = alloc_fn ( alloc_layout) ; 
101+         let  ptr = alloc_fn ( alloc_layout,   & params ) ; 
79102        if  ptr. is_null ( )  { 
80103            Err ( ( ) ) 
81104        }  else  { 
82105            // SAFETY: All `MiriAllocBytes` invariants are fulfilled. 
83-             Ok ( Self  {  ptr,  layout } ) 
106+             Ok ( Self  {  ptr,  layout,  params  } ) 
84107        } 
85108    } 
86109} 
87110
88111impl  AllocBytes  for  MiriAllocBytes  { 
89-     /// Placeholder! 
90- type  AllocParams  = ( ) ; 
112+     type  AllocParams  = MiriAllocParams ; 
91113
92-     fn  from_bytes < ' a > ( slice :  impl  Into < Cow < ' a ,  [ u8 ] > > ,  align :  Align ,  _params :  ( ) )  -> Self  { 
114+     fn  from_bytes < ' a > ( 
115+         slice :  impl  Into < Cow < ' a ,  [ u8 ] > > , 
116+         align :  Align , 
117+         params :  MiriAllocParams , 
118+     )  -> Self  { 
93119        let  slice = slice. into ( ) ; 
94120        let  size = slice. len ( ) ; 
95121        let  align = align. bytes ( ) ; 
96122        // SAFETY: `alloc_fn` will only be used with `size != 0`. 
97-         let  alloc_fn = |layout| unsafe  {  alloc:: alloc ( layout)  } ; 
98-         let  alloc_bytes = MiriAllocBytes :: alloc_with ( size. to_u64 ( ) ,  align,  alloc_fn) 
123+         let  alloc_fn = |layout,  params :  & MiriAllocParams | unsafe  { 
124+             match  params { 
125+                 MiriAllocParams :: Global  => alloc:: alloc ( layout) , 
126+                 #[ cfg( target_os = "linux" ) ]  
127+                 MiriAllocParams :: Isolated ( alloc)  => alloc. borrow_mut ( ) . alloc ( layout) , 
128+             } 
129+         } ; 
130+         let  alloc_bytes = MiriAllocBytes :: alloc_with ( size. to_u64 ( ) ,  align,  params,  alloc_fn) 
99131            . unwrap_or_else ( |( ) | { 
100132                panic ! ( "Miri ran out of memory: cannot create allocation of {size} bytes" ) 
101133            } ) ; 
@@ -105,12 +137,18 @@ impl AllocBytes for MiriAllocBytes {
105137        alloc_bytes
106138    } 
107139
108-     fn  zeroed ( size :  Size ,  align :  Align ,  _params :   ( ) )  -> Option < Self >  { 
140+     fn  zeroed ( size :  Size ,  align :  Align ,  params :   MiriAllocParams )  -> Option < Self >  { 
109141        let  size = size. bytes ( ) ; 
110142        let  align = align. bytes ( ) ; 
111143        // SAFETY: `alloc_fn` will only be used with `size != 0`. 
112-         let  alloc_fn = |layout| unsafe  {  alloc:: alloc_zeroed ( layout)  } ; 
113-         MiriAllocBytes :: alloc_with ( size,  align,  alloc_fn) . ok ( ) 
144+         let  alloc_fn = |layout,  params :  & MiriAllocParams | unsafe  { 
145+             match  params { 
146+                 MiriAllocParams :: Global  => alloc:: alloc_zeroed ( layout) , 
147+                 #[ cfg( target_os = "linux" ) ]  
148+                 MiriAllocParams :: Isolated ( alloc)  => alloc. borrow_mut ( ) . alloc_zeroed ( layout) , 
149+             } 
150+         } ; 
151+         MiriAllocBytes :: alloc_with ( size,  align,  params,  alloc_fn) . ok ( ) 
114152    } 
115153
116154    fn  as_mut_ptr ( & mut  self )  -> * mut  u8  { 
0 commit comments