|
4 | 4 |
|
5 | 5 | use core::intrinsics::{self, min_align_of_val, size_of_val}; |
6 | 6 | use core::ptr::{NonNull, Unique}; |
7 | | -use core::{mem, usize}; |
| 7 | +use core::usize; |
8 | 8 |
|
9 | 9 | #[stable(feature = "alloc_module", since = "1.28.0")] |
10 | 10 | #[doc(inline)] |
@@ -167,94 +167,94 @@ unsafe impl AllocRef for Global { |
167 | 167 | #[inline] |
168 | 168 | fn alloc(&mut self, layout: Layout, init: AllocInit) -> Result<MemoryBlock, AllocErr> { |
169 | 169 | unsafe { |
170 | | - if layout.size() == 0 { |
171 | | - Ok(MemoryBlock::new(layout.dangling(), layout)) |
| 170 | + let size = layout.size(); |
| 171 | + if size == 0 { |
| 172 | + Ok(MemoryBlock::new(layout.dangling(), 0)) |
172 | 173 | } else { |
173 | 174 | let raw_ptr = match init { |
174 | 175 | AllocInit::Uninitialized => alloc(layout), |
175 | 176 | AllocInit::Zeroed => alloc_zeroed(layout), |
176 | 177 | }; |
177 | 178 | let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?; |
178 | | - Ok(MemoryBlock::new(ptr, layout)) |
| 179 | + Ok(MemoryBlock::new(ptr, size)) |
179 | 180 | } |
180 | 181 | } |
181 | 182 | } |
182 | 183 |
|
183 | 184 | #[inline] |
184 | | - unsafe fn dealloc(&mut self, memory: MemoryBlock) { |
185 | | - if memory.size() != 0 { |
186 | | - dealloc(memory.ptr().as_ptr(), memory.layout()) |
| 185 | + unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) { |
| 186 | + if layout.size() != 0 { |
| 187 | + dealloc(ptr.as_ptr(), layout) |
187 | 188 | } |
188 | 189 | } |
189 | 190 |
|
190 | 191 | #[inline] |
191 | 192 | unsafe fn grow( |
192 | 193 | &mut self, |
193 | | - memory: &mut MemoryBlock, |
| 194 | + ptr: NonNull<u8>, |
| 195 | + layout: Layout, |
194 | 196 | new_size: usize, |
195 | 197 | placement: ReallocPlacement, |
196 | 198 | init: AllocInit, |
197 | | - ) -> Result<(), AllocErr> { |
198 | | - let old_size = memory.size(); |
| 199 | + ) -> Result<MemoryBlock, AllocErr> { |
| 200 | + let old_size = layout.size(); |
199 | 201 | debug_assert!( |
200 | 202 | new_size >= old_size, |
201 | 203 | "`new_size` must be greater than or equal to `memory.size()`" |
202 | 204 | ); |
203 | 205 |
|
204 | 206 | if old_size == new_size { |
205 | | - return Ok(()); |
| 207 | + return Ok(MemoryBlock::new(ptr, old_size)); |
206 | 208 | } |
207 | 209 |
|
208 | | - let new_layout = Layout::from_size_align_unchecked(new_size, memory.align()); |
209 | 210 | match placement { |
210 | | - ReallocPlacement::InPlace => return Err(AllocErr), |
211 | | - ReallocPlacement::MayMove if memory.size() == 0 => { |
212 | | - *memory = self.alloc(new_layout, init)? |
| 211 | + ReallocPlacement::InPlace => Err(AllocErr), |
| 212 | + ReallocPlacement::MayMove if layout.size() == 0 => { |
| 213 | + let new_layout = Layout::from_size_align_unchecked(new_size, layout.align()); |
| 214 | + self.alloc(new_layout, init) |
213 | 215 | } |
214 | 216 | ReallocPlacement::MayMove => { |
215 | 217 | // `realloc` probably checks for `new_size > old_size` or something similar. |
216 | 218 | 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 | + let ptr = realloc(ptr.as_ptr(), layout, new_size); |
| 220 | + let mut memory = MemoryBlock::new(NonNull::new(ptr).ok_or(AllocErr)?, new_size); |
219 | 221 | memory.init_offset(init, old_size); |
| 222 | + Ok(memory) |
220 | 223 | } |
221 | 224 | } |
222 | | - Ok(()) |
223 | 225 | } |
224 | 226 |
|
225 | 227 | #[inline] |
226 | 228 | unsafe fn shrink( |
227 | 229 | &mut self, |
228 | | - memory: &mut MemoryBlock, |
| 230 | + ptr: NonNull<u8>, |
| 231 | + layout: Layout, |
229 | 232 | new_size: usize, |
230 | 233 | placement: ReallocPlacement, |
231 | | - ) -> Result<(), AllocErr> { |
232 | | - let old_size = memory.size(); |
| 234 | + ) -> Result<MemoryBlock, AllocErr> { |
| 235 | + let old_size = layout.size(); |
233 | 236 | debug_assert!( |
234 | 237 | new_size <= old_size, |
235 | 238 | "`new_size` must be smaller than or equal to `memory.size()`" |
236 | 239 | ); |
237 | 240 |
|
238 | 241 | if old_size == new_size { |
239 | | - return Ok(()); |
| 242 | + return Ok(MemoryBlock::new(ptr, old_size)); |
240 | 243 | } |
241 | 244 |
|
242 | | - let new_layout = Layout::from_size_align_unchecked(new_size, memory.align()); |
243 | 245 | match placement { |
244 | | - ReallocPlacement::InPlace => return Err(AllocErr), |
| 246 | + ReallocPlacement::InPlace => Err(AllocErr), |
245 | 247 | 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) |
| 248 | + self.dealloc(ptr, layout); |
| 249 | + Ok(MemoryBlock::new(layout.dangling(), 0)) |
249 | 250 | } |
250 | 251 | ReallocPlacement::MayMove => { |
251 | 252 | // `realloc` probably checks for `new_size < old_size` or something similar. |
252 | 253 | 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); |
| 254 | + let ptr = realloc(ptr.as_ptr(), layout, new_size); |
| 255 | + Ok(MemoryBlock::new(NonNull::new(ptr).ok_or(AllocErr)?, new_size)) |
255 | 256 | } |
256 | 257 | } |
257 | | - Ok(()) |
258 | 258 | } |
259 | 259 | } |
260 | 260 |
|
@@ -282,7 +282,7 @@ pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) { |
282 | 282 | let size = size_of_val(ptr.as_ref()); |
283 | 283 | let align = min_align_of_val(ptr.as_ref()); |
284 | 284 | let layout = Layout::from_size_align_unchecked(size, align); |
285 | | - Global.dealloc(MemoryBlock::new(ptr.cast().into(), layout)) |
| 285 | + Global.dealloc(ptr.cast().into(), layout) |
286 | 286 | } |
287 | 287 |
|
288 | 288 | /// Abort on memory allocation error or failure. |
|
0 commit comments