6363#![ deny( unsafe_op_in_unsafe_fn) ]
6464#![ stable( feature = "alloc_module" , since = "1.28.0" ) ]
6565
66- use core:: ptr:: NonNull ;
67- use core:: sync:: atomic:: { AtomicBool , AtomicPtr , Ordering } ;
68- use core:: { hint, mem, ptr} ;
69-
7066#[ stable( feature = "alloc_module" , since = "1.28.0" ) ]
7167#[ doc( inline) ]
7268pub use alloc_crate:: alloc:: * ;
7369
70+ use crate :: ptr:: NonNull ;
71+ use crate :: sync:: atomic:: { AtomicBool , AtomicPtr , Ordering } ;
72+ use crate :: sys:: alloc as imp;
73+ use crate :: { hint, mem, ptr} ;
74+
7475/// The default memory allocator provided by the operating system.
7576///
7677/// This is based on `malloc` on Unix platforms and `HeapAlloc` on Windows,
@@ -145,11 +146,7 @@ impl System {
145146 0 => Ok ( layout. dangling_ptr ( ) . cast_slice ( 0 ) ) ,
146147 // SAFETY: `layout` is non-zero in size,
147148 size => unsafe {
148- let raw_ptr = if zeroed {
149- GlobalAlloc :: alloc_zeroed ( self , layout)
150- } else {
151- GlobalAlloc :: alloc ( self , layout)
152- } ;
149+ let raw_ptr = if zeroed { imp:: alloc_zeroed ( layout) } else { imp:: alloc ( layout) } ;
153150 let ptr = NonNull :: new ( raw_ptr) . ok_or ( AllocError ) ?;
154151 Ok ( ptr. cast_slice ( size) )
155152 } ,
@@ -182,7 +179,7 @@ impl System {
182179 // `realloc` probably checks for `new_size >= old_layout.size()` or something similar.
183180 hint:: assert_unchecked ( new_size >= old_layout. size ( ) ) ;
184181
185- let raw_ptr = GlobalAlloc :: realloc ( self , ptr. as_ptr ( ) , old_layout, new_size) ;
182+ let raw_ptr = imp :: realloc ( ptr. as_ptr ( ) , old_layout, new_size) ;
186183 let ptr = NonNull :: new ( raw_ptr) . ok_or ( AllocError ) ?;
187184 if zeroed {
188185 raw_ptr. add ( old_size) . write_bytes ( 0 , new_size - old_size) ;
@@ -205,8 +202,8 @@ impl System {
205202 }
206203}
207204
208- // The Allocator impl checks the layout size to be non-zero and forwards to the GlobalAlloc impl,
209- // which is in `std::sys::*::alloc`.
205+ // The Allocator impl checks the layout size to be non-zero and forwards to the
206+ // platform functions in `std::sys::*::alloc`.
210207#[ unstable( feature = "allocator_api" , issue = "32838" ) ]
211208unsafe impl Allocator for System {
212209 #[ inline]
@@ -224,7 +221,7 @@ unsafe impl Allocator for System {
224221 if layout. size ( ) != 0 {
225222 // SAFETY: `layout` is non-zero in size,
226223 // other conditions must be upheld by the caller
227- unsafe { GlobalAlloc :: dealloc ( self , ptr. as_ptr ( ) , layout) }
224+ unsafe { imp :: dealloc ( ptr. as_ptr ( ) , layout) }
228225 }
229226 }
230227
@@ -274,7 +271,7 @@ unsafe impl Allocator for System {
274271 // `realloc` probably checks for `new_size <= old_layout.size()` or something similar.
275272 hint:: assert_unchecked ( new_size <= old_layout. size ( ) ) ;
276273
277- let raw_ptr = GlobalAlloc :: realloc ( self , ptr. as_ptr ( ) , old_layout, new_size) ;
274+ let raw_ptr = imp :: realloc ( ptr. as_ptr ( ) , old_layout, new_size) ;
278275 let ptr = NonNull :: new ( raw_ptr) . ok_or ( AllocError ) ?;
279276 Ok ( ptr. cast_slice ( new_size) )
280277 } ,
@@ -294,6 +291,9 @@ unsafe impl Allocator for System {
294291 }
295292}
296293
294+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
295+ unsafe impl GlobalAllocator for System { }
296+
297297static HOOK : AtomicPtr < ( ) > = AtomicPtr :: new ( ptr:: null_mut ( ) ) ;
298298
299299/// Registers a custom allocation error hook, replacing any that was previously registered.
@@ -435,7 +435,12 @@ pub fn rust_oom(layout: Layout) -> ! {
435435#[ allow( unused_attributes) ]
436436#[ unstable( feature = "alloc_internals" , issue = "none" ) ]
437437pub mod __default_lib_allocator {
438- use super :: { GlobalAlloc , Layout , System } ;
438+ use super :: Layout ;
439+ // We call the system functions directly to avoid any overheads introduced
440+ // by the roundtrip through `impl Allocator for System` and
441+ // `impl<A: GlobalAllocator> GlobalAlloc for A`.
442+ use crate :: sys:: alloc as imp;
443+
439444 // These magic symbol names are used as a fallback for implementing the
440445 // `__rust_alloc` etc symbols (see `src/liballoc/alloc.rs`) when there is
441446 // no `#[global_allocator]` attribute.
@@ -452,15 +457,15 @@ pub mod __default_lib_allocator {
452457 // `GlobalAlloc::alloc`.
453458 unsafe {
454459 let layout = Layout :: from_size_align_unchecked ( size, align) ;
455- System . alloc ( layout)
460+ imp :: alloc ( layout)
456461 }
457462 }
458463
459464 #[ rustc_std_internal_symbol]
460465 pub unsafe extern "C" fn __rdl_dealloc ( ptr : * mut u8 , size : usize , align : usize ) {
461466 // SAFETY: see the guarantees expected by `Layout::from_size_align` and
462467 // `GlobalAlloc::dealloc`.
463- unsafe { System . dealloc ( ptr, Layout :: from_size_align_unchecked ( size, align) ) }
468+ unsafe { imp :: dealloc ( ptr, Layout :: from_size_align_unchecked ( size, align) ) }
464469 }
465470
466471 #[ rustc_std_internal_symbol]
@@ -474,7 +479,7 @@ pub mod __default_lib_allocator {
474479 // `GlobalAlloc::realloc`.
475480 unsafe {
476481 let old_layout = Layout :: from_size_align_unchecked ( old_size, align) ;
477- System . realloc ( ptr, old_layout, new_size)
482+ imp :: realloc ( ptr, old_layout, new_size)
478483 }
479484 }
480485
@@ -484,7 +489,7 @@ pub mod __default_lib_allocator {
484489 // `GlobalAlloc::alloc_zeroed`.
485490 unsafe {
486491 let layout = Layout :: from_size_align_unchecked ( size, align) ;
487- System . alloc_zeroed ( layout)
492+ imp :: alloc_zeroed ( layout)
488493 }
489494 }
490495}
0 commit comments