@@ -5,13 +5,139 @@ pub use core::alloc::GlobalAlloc;
55use core:: {
66 cmp,
77 fmt,
8+ intrinsics:: likely,
89 num:: NonZeroUsize ,
910 ptr:: { self , NonNull } ,
1011} ;
11- pub use liballoc:: alloc:: { alloc , alloc_zeroed , dealloc , handle_alloc_error , realloc , Layout } ;
12+ pub use liballoc:: alloc:: Layout ;
1213#[ cfg( feature = "std" ) ]
1314use std:: alloc:: System ;
1415
16+ /// Abort on memory allocation error or failure.
17+ ///
18+ /// Callers of memory allocation APIs wishing to abort computation
19+ /// in response to an allocation error are encouraged to call this function,
20+ /// rather than directly invoking `panic!` or similar.
21+ ///
22+ /// The default behavior of this function is to print a message to standard error
23+ /// and abort the process.
24+ /// It can be replaced with [`set_alloc_error_hook`] and [`take_alloc_error_hook`].
25+ ///
26+ /// [`set_alloc_error_hook`]: https://doc.rust-lang.org/nightly/std/alloc/fn.set_alloc_error_hook.html
27+ /// [`take_alloc_error_hook`]: https://doc.rust-lang.org/nightly/std/alloc/fn.take_alloc_error_hook.html
28+ #[ allow( clippy:: inline_always) ]
29+ #[ inline( always) ]
30+ #[ deprecated = "allocation functions returns an error, use that instead" ]
31+ pub fn handle_alloc_error ( layout : Layout ) -> ! {
32+ liballoc:: alloc:: handle_alloc_error ( layout)
33+ }
34+
35+ /// Allocate memory with the global allocator.
36+ ///
37+ /// This function forwards calls to the [`GlobalAlloc::alloc`] method
38+ /// of the allocator registered with the `#[global_allocator]` attribute
39+ /// if there is one, or the `std` crate’s default.
40+ ///
41+ /// # Safety
42+ ///
43+ /// See [`GlobalAlloc::alloc`].
44+ ///
45+ /// [`GlobalAlloc::alloc`]: GlobalAlloc::alloc
46+ ///
47+ /// # Examples
48+ ///
49+ /// ```
50+ /// use alloc_wg::alloc::{alloc, dealloc, Layout};
51+ ///
52+ /// unsafe {
53+ /// let layout = Layout::new::<u16>();
54+ /// let ptr = alloc(layout);
55+ ///
56+ /// *(ptr as *mut u16) = 42;
57+ /// assert_eq!(*(ptr as *mut u16), 42);
58+ ///
59+ /// dealloc(ptr, layout);
60+ /// }
61+ /// ```
62+ #[ allow( clippy:: inline_always) ]
63+ #[ inline( always) ]
64+ #[ must_use = "allocating is expected to be expensive" ]
65+ #[ deprecated = "Use `Global::alloc` instead" ]
66+ pub unsafe fn alloc ( layout : Layout ) -> * mut u8 {
67+ liballoc:: alloc:: alloc ( layout)
68+ }
69+
70+ /// Deallocate memory with the global allocator.
71+ ///
72+ /// This function forwards calls to the [`GlobalAlloc::dealloc`] method
73+ /// of the allocator registered with the `#[global_allocator]` attribute
74+ /// if there is one, or the `std` crate’s default.
75+ ///
76+ /// # Safety
77+ ///
78+ /// See [`GlobalAlloc::dealloc`].
79+ ///
80+ /// [`GlobalAlloc::dealloc`]: GlobalAlloc::dealloc
81+ #[ allow( clippy:: inline_always) ]
82+ #[ inline( always) ]
83+ #[ deprecated = "Use `Global::dealloc` instead" ]
84+ pub unsafe fn dealloc ( ptr : * mut u8 , layout : Layout ) {
85+ liballoc:: alloc:: dealloc ( ptr, layout)
86+ }
87+
88+ /// Reallocate memory with the global allocator.
89+ ///
90+ /// This function forwards calls to the [`GlobalAlloc::realloc`] method
91+ /// of the allocator registered with the `#[global_allocator]` attribute
92+ /// if there is one, or the `std` crate’s default.
93+ ///
94+ /// # Safety
95+ ///
96+ /// See [`GlobalAlloc::realloc`].
97+ ///
98+ /// [`GlobalAlloc::realloc`]: GlobalAlloc::realloc
99+ #[ allow( clippy:: inline_always) ]
100+ #[ inline( always) ]
101+ #[ must_use = "reallocating is expected to be expensive" ]
102+ #[ deprecated = "Use `Global::realloc` instead" ]
103+ pub unsafe fn realloc ( ptr : * mut u8 , layout : Layout , new_size : usize ) -> * mut u8 {
104+ liballoc:: alloc:: realloc ( ptr, layout, new_size)
105+ }
106+
107+ /// Allocate zero-initialized memory with the global allocator.
108+ ///
109+ /// This function forwards calls to the [`GlobalAlloc::alloc_zeroed`] method
110+ /// of the allocator registered with the `#[global_allocator]` attribute
111+ /// if there is one, or the `std` crate’s default.
112+ ///
113+ /// # Safety
114+ ///
115+ /// See [`GlobalAlloc::alloc_zeroed`].
116+ ///
117+ /// [`GlobalAlloc::alloc_zeroed`]: GlobalAlloc::alloc_zeroed
118+ ///
119+ /// # Examples
120+ ///
121+ /// ```
122+ /// use alloc_wg::alloc::{alloc_zeroed, dealloc, Layout};
123+ ///
124+ /// unsafe {
125+ /// let layout = Layout::new::<u16>();
126+ /// let ptr = alloc_zeroed(layout);
127+ ///
128+ /// assert_eq!(*(ptr as *mut u16), 0);
129+ ///
130+ /// dealloc(ptr, layout);
131+ /// }
132+ /// ```
133+ #[ allow( clippy:: inline_always) ]
134+ #[ inline( always) ]
135+ #[ must_use = "allocating is expected to be expensive" ]
136+ #[ deprecated = "Use `Global::alloc_zeroed` instead" ]
137+ pub unsafe fn alloc_zeroed ( layout : Layout ) -> * mut u8 {
138+ liballoc:: alloc:: alloc_zeroed ( layout)
139+ }
140+
15141#[ derive( Clone , PartialEq , Eq , Debug ) ]
16142pub struct CapacityOverflow ;
17143
@@ -212,6 +338,7 @@ impl DeallocRef for Global {
212338 }
213339
214340 unsafe fn dealloc ( & mut self , ptr : NonNull < u8 > , layout : NonZeroLayout ) {
341+ #[ allow( deprecated) ]
215342 dealloc ( ptr. as_ptr ( ) , layout. into ( ) )
216343 }
217344}
@@ -220,23 +347,31 @@ impl AllocRef for Global {
220347 type Error = AllocErr ;
221348
222349 fn alloc ( & mut self , layout : NonZeroLayout ) -> Result < NonNull < u8 > , Self :: Error > {
223- unsafe { NonNull :: new ( alloc ( layout. into ( ) ) ) . ok_or ( AllocErr ) }
350+ #[ allow( deprecated) ]
351+ unsafe {
352+ NonNull :: new ( alloc ( layout. into ( ) ) ) . ok_or ( AllocErr )
353+ }
224354 }
225355
226356 fn alloc_zeroed ( & mut self , layout : NonZeroLayout ) -> Result < NonNull < u8 > , Self :: Error > {
227- unsafe { NonNull :: new ( alloc_zeroed ( layout. into ( ) ) ) . ok_or ( AllocErr ) }
357+ #[ allow( deprecated) ]
358+ unsafe {
359+ NonNull :: new ( alloc_zeroed ( layout. into ( ) ) ) . ok_or ( AllocErr )
360+ }
228361 }
229362}
230363
231364impl ReallocRef for Global {
365+ // FIXME: Remove `else` branch. This is needed, as std provides old method.
232366 unsafe fn realloc (
233367 & mut self ,
234368 ptr : NonNull < u8 > ,
235369 old_layout : NonZeroLayout ,
236370 new_layout : NonZeroLayout ,
237371 ) -> Result < NonNull < u8 > , Self :: Error > {
238- // FIXME: Remove `else` branch. This is needed, as std provides old method.
239- if old_layout. align ( ) == new_layout. align ( ) {
372+ // TODO: Test if this is a well suited case for `likely`
373+ if likely ( old_layout. align ( ) == new_layout. align ( ) ) {
374+ #[ allow( deprecated) ]
240375 NonNull :: new ( realloc (
241376 ptr. as_ptr ( ) ,
242377 old_layout. into ( ) ,
@@ -284,7 +419,8 @@ impl ReallocRef for System {
284419 old_layout : NonZeroLayout ,
285420 new_layout : NonZeroLayout ,
286421 ) -> Result < NonNull < u8 > , Self :: Error > {
287- if old_layout. align ( ) == new_layout. align ( ) {
422+ // TODO: Test if this is a well suited case for `likely`
423+ if likely ( old_layout. align ( ) == new_layout. align ( ) ) {
288424 NonNull :: new ( GlobalAlloc :: realloc (
289425 self ,
290426 ptr. as_ptr ( ) ,
@@ -305,15 +441,12 @@ unsafe fn alloc_copy_dealloc<A: ReallocRef>(
305441 old_layout : NonZeroLayout ,
306442 new_layout : NonZeroLayout ,
307443) -> Result < NonNull < u8 > , A :: Error > {
308- let result = alloc. alloc ( new_layout) ;
309-
310- if let Ok ( new_ptr) = result {
311- ptr:: copy_nonoverlapping (
312- ptr. as_ptr ( ) ,
313- new_ptr. as_ptr ( ) ,
314- cmp:: min ( old_layout. size ( ) . get ( ) , new_layout. size ( ) . get ( ) ) ,
315- ) ;
316- alloc. dealloc ( ptr, old_layout) ;
317- }
318- result
444+ let new_ptr = alloc. alloc ( new_layout) ?;
445+ ptr:: copy_nonoverlapping (
446+ ptr. as_ptr ( ) ,
447+ new_ptr. as_ptr ( ) ,
448+ cmp:: min ( old_layout. size ( ) . get ( ) , new_layout. size ( ) . get ( ) ) ,
449+ ) ;
450+ alloc. dealloc ( ptr, old_layout) ;
451+ Ok ( new_ptr)
319452}
0 commit comments