44
55use core:: intrinsics:: { self , min_align_of_val, size_of_val} ;
66use core:: ptr:: { NonNull , Unique } ;
7- use core:: usize;
7+ use core:: { mem , usize} ;
88
99#[ stable( feature = "alloc_module" , since = "1.28.0" ) ]
1010#[ doc( inline) ]
@@ -165,102 +165,96 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
165165#[ unstable( feature = "allocator_api" , issue = "32838" ) ]
166166unsafe impl AllocRef for Global {
167167 #[ inline]
168- fn alloc ( & mut self , layout : Layout , init : AllocInit ) -> Result < ( NonNull < u8 > , usize ) , AllocErr > {
169- let new_size = layout. size ( ) ;
170- if new_size == 0 {
171- Ok ( ( layout. dangling ( ) , 0 ) )
172- } else {
173- unsafe {
168+ fn alloc ( & mut self , layout : Layout , init : AllocInit ) -> Result < MemoryBlock , AllocErr > {
169+ unsafe {
170+ if layout. size ( ) == 0 {
171+ Ok ( MemoryBlock :: new ( layout. dangling ( ) , layout) )
172+ } else {
174173 let raw_ptr = match init {
175174 AllocInit :: Uninitialized => alloc ( layout) ,
176175 AllocInit :: Zeroed => alloc_zeroed ( layout) ,
177176 } ;
178177 let ptr = NonNull :: new ( raw_ptr) . ok_or ( AllocErr ) ?;
179- Ok ( ( ptr, new_size ) )
178+ Ok ( MemoryBlock :: new ( ptr, layout ) )
180179 }
181180 }
182181 }
183182
184183 #[ inline]
185- unsafe fn dealloc ( & mut self , ptr : NonNull < u8 > , layout : Layout ) {
186- if layout . size ( ) != 0 {
187- dealloc ( ptr. as_ptr ( ) , layout)
184+ unsafe fn dealloc ( & mut self , memory : MemoryBlock ) {
185+ if memory . size ( ) != 0 {
186+ dealloc ( memory . ptr ( ) . as_ptr ( ) , memory . layout ( ) )
188187 }
189188 }
190189
191190 #[ inline]
192191 unsafe fn grow (
193192 & mut self ,
194- ptr : NonNull < u8 > ,
195- layout : Layout ,
193+ memory : & mut MemoryBlock ,
196194 new_size : usize ,
197195 placement : ReallocPlacement ,
198196 init : AllocInit ,
199- ) -> Result < ( NonNull < u8 > , usize ) , AllocErr > {
200- let old_size = layout . size ( ) ;
197+ ) -> Result < ( ) , AllocErr > {
198+ let old_size = memory . size ( ) ;
201199 debug_assert ! (
202200 new_size >= old_size,
203- "`new_size` must be greater than or equal to `layout .size()`"
201+ "`new_size` must be greater than or equal to `memory .size()`"
204202 ) ;
205203
206204 if old_size == new_size {
207- return Ok ( ( ptr , new_size ) ) ;
205+ return Ok ( ( ) ) ;
208206 }
209207
208+ let new_layout = Layout :: from_size_align_unchecked ( new_size, memory. align ( ) ) ;
210209 match placement {
210+ ReallocPlacement :: InPlace => return Err ( AllocErr ) ,
211+ ReallocPlacement :: MayMove if memory. size ( ) == 0 => {
212+ * memory = self . alloc ( new_layout, init) ?
213+ }
211214 ReallocPlacement :: MayMove => {
212- if old_size == 0 {
213- self . alloc ( Layout :: from_size_align_unchecked ( new_size, layout. align ( ) ) , init)
214- } else {
215- // `realloc` probably checks for `new_size > old_size` or something similar.
216- // `new_size` must be greater than or equal to `old_size` due to the safety constraint,
217- // and `new_size` == `old_size` was caught before
218- intrinsics:: assume ( new_size > old_size) ;
219- let ptr =
220- NonNull :: new ( realloc ( ptr. as_ptr ( ) , layout, new_size) ) . ok_or ( AllocErr ) ?;
221- let new_layout = Layout :: from_size_align_unchecked ( new_size, layout. align ( ) ) ;
222- init. initialize_offset ( ptr, new_layout, old_size) ;
223- Ok ( ( ptr, new_size) )
224- }
215+ // `realloc` probably checks for `new_size > old_size` or something similar.
216+ intrinsics:: assume ( new_size > old_size) ;
217+ let ptr = realloc ( memory. ptr ( ) . as_ptr ( ) , memory. layout ( ) , new_size) ;
218+ * memory = MemoryBlock :: new ( NonNull :: new ( ptr) . ok_or ( AllocErr ) ?, new_layout) ;
219+ memory. init_offset ( init, old_size) ;
225220 }
226- ReallocPlacement :: InPlace => Err ( AllocErr ) ,
227221 }
222+ Ok ( ( ) )
228223 }
229224
230225 #[ inline]
231226 unsafe fn shrink (
232227 & mut self ,
233- ptr : NonNull < u8 > ,
234- layout : Layout ,
228+ memory : & mut MemoryBlock ,
235229 new_size : usize ,
236230 placement : ReallocPlacement ,
237- ) -> Result < ( NonNull < u8 > , usize ) , AllocErr > {
238- let old_size = layout . size ( ) ;
231+ ) -> Result < ( ) , AllocErr > {
232+ let old_size = memory . size ( ) ;
239233 debug_assert ! (
240234 new_size <= old_size,
241- "`new_size` must be smaller than or equal to `layout .size()`"
235+ "`new_size` must be smaller than or equal to `memory .size()`"
242236 ) ;
243237
244238 if old_size == new_size {
245- return Ok ( ( ptr , new_size ) ) ;
239+ return Ok ( ( ) ) ;
246240 }
247241
242+ let new_layout = Layout :: from_size_align_unchecked ( new_size, memory. align ( ) ) ;
248243 match placement {
244+ ReallocPlacement :: InPlace => return Err ( AllocErr ) ,
245+ ReallocPlacement :: MayMove if new_size == 0 => {
246+ let new_memory = MemoryBlock :: new ( new_layout. dangling ( ) , new_layout) ;
247+ let old_memory = mem:: replace ( memory, new_memory) ;
248+ self . dealloc ( old_memory)
249+ }
249250 ReallocPlacement :: MayMove => {
250- let ptr = if new_size == 0 {
251- self . dealloc ( ptr, layout) ;
252- layout. dangling ( )
253- } else {
254- // `realloc` probably checks for `new_size > old_size` or something similar.
255- // `new_size` must be smaller than or equal to `old_size` due to the safety constraint,
256- // and `new_size` == `old_size` was caught before
257- intrinsics:: assume ( new_size < old_size) ;
258- NonNull :: new ( realloc ( ptr. as_ptr ( ) , layout, new_size) ) . ok_or ( AllocErr ) ?
259- } ;
260- Ok ( ( ptr, new_size) )
251+ // `realloc` probably checks for `new_size < old_size` or something similar.
252+ intrinsics:: assume ( new_size < old_size) ;
253+ let ptr = realloc ( memory. ptr ( ) . as_ptr ( ) , memory. layout ( ) , new_size) ;
254+ * memory = MemoryBlock :: new ( NonNull :: new ( ptr) . ok_or ( AllocErr ) ?, new_layout) ;
261255 }
262- ReallocPlacement :: InPlace => Err ( AllocErr ) ,
263256 }
257+ Ok ( ( ) )
264258 }
265259}
266260
@@ -272,7 +266,7 @@ unsafe impl AllocRef for Global {
272266unsafe fn exchange_malloc ( size : usize , align : usize ) -> * mut u8 {
273267 let layout = Layout :: from_size_align_unchecked ( size, align) ;
274268 match Global . alloc ( layout, AllocInit :: Uninitialized ) {
275- Ok ( ( ptr , _ ) ) => ptr. as_ptr ( ) ,
269+ Ok ( memory ) => memory . ptr ( ) . as_ptr ( ) ,
276270 Err ( _) => handle_alloc_error ( layout) ,
277271 }
278272}
@@ -288,7 +282,7 @@ pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
288282 let size = size_of_val ( ptr. as_ref ( ) ) ;
289283 let align = min_align_of_val ( ptr. as_ref ( ) ) ;
290284 let layout = Layout :: from_size_align_unchecked ( size, align) ;
291- Global . dealloc ( ptr. cast ( ) . into ( ) , layout)
285+ Global . dealloc ( MemoryBlock :: new ( ptr. cast ( ) . into ( ) , layout) )
292286}
293287
294288/// Abort on memory allocation error or failure.
0 commit comments