Skip to content

Commit b01fbc4

Browse files
committed
Simplify implementations of AllocRef for Global and System
1 parent 076ef66 commit b01fbc4

File tree

2 files changed

+143
-195
lines changed

2 files changed

+143
-195
lines changed

library/alloc/src/alloc.rs

Lines changed: 70 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -165,34 +165,33 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
165165
unsafe impl AllocRef for Global {
166166
#[inline]
167167
fn alloc(&mut self, layout: Layout) -> Result<MemoryBlock, AllocErr> {
168-
unsafe {
169-
let size = layout.size();
170-
if size == 0 {
171-
Ok(MemoryBlock { ptr: layout.dangling(), size: 0 })
172-
} else {
173-
let raw_ptr = alloc(layout);
174-
let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
175-
Ok(MemoryBlock { ptr, size })
176-
}
177-
}
168+
let size = layout.size();
169+
let ptr = if size == 0 {
170+
layout.dangling()
171+
} else {
172+
// SAFETY: `layout` is non-zero in size,
173+
unsafe { NonNull::new(alloc(layout)).ok_or(AllocErr)? }
174+
};
175+
Ok(MemoryBlock { ptr, size })
178176
}
179177

178+
#[inline]
180179
fn alloc_zeroed(&mut self, layout: Layout) -> Result<MemoryBlock, AllocErr> {
181-
unsafe {
182-
let size = layout.size();
183-
if size == 0 {
184-
Ok(MemoryBlock { ptr: layout.dangling(), size: 0 })
185-
} else {
186-
let raw_ptr = alloc_zeroed(layout);
187-
let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
188-
Ok(MemoryBlock { ptr, size })
189-
}
190-
}
180+
let size = layout.size();
181+
let ptr = if size == 0 {
182+
layout.dangling()
183+
} else {
184+
// SAFETY: `layout` is non-zero in size,
185+
unsafe { NonNull::new(alloc_zeroed(layout)).ok_or(AllocErr)? }
186+
};
187+
Ok(MemoryBlock { ptr, size })
191188
}
192189

193190
#[inline]
194191
unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
195192
if layout.size() != 0 {
193+
// SAFETY: `layout` is non-zero in size,
194+
// other conditions must be upheld by the caller
196195
unsafe { dealloc(ptr.as_ptr(), layout) }
197196
}
198197
}
@@ -204,59 +203,55 @@ unsafe impl AllocRef for Global {
204203
layout: Layout,
205204
new_size: usize,
206205
) -> Result<MemoryBlock, AllocErr> {
207-
let size = layout.size();
208206
debug_assert!(
209-
new_size >= size,
210-
"`new_size` must be greater than or equal to `memory.size()`"
207+
new_size >= layout.size(),
208+
"`new_size` must be greater than or equal to `layout.size()`"
211209
);
212210

213-
if size == new_size {
214-
return Ok(MemoryBlock { ptr, size });
215-
}
216-
217-
if layout.size() == 0 {
218-
let new_layout = unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) };
219-
self.alloc(new_layout)
220-
} else {
221-
// `realloc` probably checks for `new_size > size` or something similar.
222-
let ptr = unsafe {
223-
intrinsics::assume(new_size > size);
224-
realloc(ptr.as_ptr(), layout, new_size)
225-
};
226-
Ok(MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size })
211+
// SAFETY: `new_size` must be non-zero, which is checked in the match expression.
212+
// Other conditions must be upheld by the caller
213+
unsafe {
214+
match layout.size() {
215+
old_size if old_size == new_size => Ok(MemoryBlock { ptr, size: new_size }),
216+
0 => self.alloc(Layout::from_size_align_unchecked(new_size, layout.align())),
217+
old_size => {
218+
// `realloc` probably checks for `new_size > size` or something similar.
219+
intrinsics::assume(new_size > old_size);
220+
let raw_ptr = realloc(ptr.as_ptr(), layout, new_size);
221+
let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
222+
Ok(MemoryBlock { ptr, size: new_size })
223+
}
224+
}
227225
}
228226
}
229227

228+
#[inline]
230229
unsafe fn grow_zeroed(
231230
&mut self,
232231
ptr: NonNull<u8>,
233232
layout: Layout,
234233
new_size: usize,
235234
) -> Result<MemoryBlock, AllocErr> {
236-
let size = layout.size();
237235
debug_assert!(
238-
new_size >= size,
239-
"`new_size` must be greater than or equal to `memory.size()`"
236+
new_size >= layout.size(),
237+
"`new_size` must be greater than or equal to `layout.size()`"
240238
);
241239

242-
if size == new_size {
243-
return Ok(MemoryBlock { ptr, size });
244-
}
245-
246-
if layout.size() == 0 {
247-
let new_layout = unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) };
248-
self.alloc(new_layout)
249-
} else {
250-
// `realloc` probably checks for `new_size > size` or something similar.
251-
let ptr = unsafe {
252-
intrinsics::assume(new_size > size);
253-
realloc(ptr.as_ptr(), layout, new_size)
254-
};
255-
let memory = MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size };
256-
unsafe {
257-
memory.ptr.as_ptr().add(size).write_bytes(0, memory.size - size);
240+
// SAFETY: `new_size` must be non-zero, which is checked in the match expression.
241+
// Other conditions must be upheld by the caller
242+
unsafe {
243+
match layout.size() {
244+
old_size if old_size == new_size => Ok(MemoryBlock { ptr, size: new_size }),
245+
0 => self.alloc_zeroed(Layout::from_size_align_unchecked(new_size, layout.align())),
246+
old_size => {
247+
// `realloc` probably checks for `new_size > size` or something similar.
248+
intrinsics::assume(new_size > old_size);
249+
let raw_ptr = realloc(ptr.as_ptr(), layout, new_size);
250+
raw_ptr.add(old_size).write_bytes(0, new_size - old_size);
251+
let ptr = NonNull::new(raw_ptr).ok_or(AllocErr)?;
252+
Ok(MemoryBlock { ptr, size: new_size })
253+
}
258254
}
259-
Ok(memory)
260255
}
261256
}
262257

@@ -267,29 +262,33 @@ unsafe impl AllocRef for Global {
267262
layout: Layout,
268263
new_size: usize,
269264
) -> Result<MemoryBlock, AllocErr> {
270-
let size = layout.size();
265+
let old_size = layout.size();
271266
debug_assert!(
272-
new_size <= size,
273-
"`new_size` must be smaller than or equal to `memory.size()`"
267+
new_size <= old_size,
268+
"`new_size` must be smaller than or equal to `layout.size()`"
274269
);
275270

276-
if size == new_size {
277-
return Ok(MemoryBlock { ptr, size });
278-
}
279-
280-
if new_size == 0 {
271+
let ptr = if new_size == old_size {
272+
ptr
273+
} else if new_size == 0 {
274+
// SAFETY: `layout` is non-zero in size as `old_size` != `new_size`
275+
// Other conditions must be upheld by the caller
281276
unsafe {
282277
self.dealloc(ptr, layout);
283278
}
284-
Ok(MemoryBlock { ptr: layout.dangling(), size: 0 })
279+
layout.dangling()
285280
} else {
286-
// `realloc` probably checks for `new_size < size` or something similar.
287-
let ptr = unsafe {
288-
intrinsics::assume(new_size < size);
281+
// SAFETY: new_size is not zero,
282+
// Other conditions must be upheld by the caller
283+
let raw_ptr = unsafe {
284+
// `realloc` probably checks for `new_size < old_size` or something similar.
285+
intrinsics::assume(new_size < old_size);
289286
realloc(ptr.as_ptr(), layout, new_size)
290287
};
291-
Ok(MemoryBlock { ptr: NonNull::new(ptr).ok_or(AllocErr)?, size: new_size })
292-
}
288+
NonNull::new(raw_ptr).ok_or(AllocErr)?
289+
};
290+
291+
Ok(MemoryBlock { ptr, size: new_size })
293292
}
294293
}
295294

0 commit comments

Comments
 (0)