]> git.lizzy.rs Git - rust.git/blob - src/libstd/heap.rs
rustc: Implement the #[global_allocator] attribute
[rust.git] / src / libstd / heap.rs
1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! dox
12
13 #![unstable(issue = "32838", feature = "allocator_api")]
14
15 pub use alloc::heap::{Heap, Alloc, Layout, Excess, CannotReallocInPlace, AllocErr};
16 #[cfg(not(stage0))]
17 pub use alloc_system::System;
18
19 #[cfg(all(not(stage0), not(test)))]
20 #[doc(hidden)]
21 pub mod __default_lib_allocator {
22     use super::{System, Layout, Alloc, AllocErr};
23     use ptr;
24
25     // for symbol names src/librustc/middle/allocator.rs
26     // for signatures src/librustc_allocator/lib.rs
27
28     // linkage directives are provided as part of the current compiler allocator
29     // ABI
30
31     #[no_mangle]
32     pub unsafe extern fn __rdl_alloc(size: usize,
33                                      align: usize,
34                                      err: *mut u8) -> *mut u8 {
35         let layout = Layout::from_size_align_unchecked(size, align);
36         match System.alloc(layout) {
37             Ok(p) => p,
38             Err(e) => {
39                 ptr::write(err as *mut AllocErr, e);
40                 0 as *mut u8
41             }
42         }
43     }
44
45     #[no_mangle]
46     pub unsafe extern fn __rdl_oom(err: *const u8) -> ! {
47         System.oom((*(err as *const AllocErr)).clone())
48     }
49
50     #[no_mangle]
51     pub unsafe extern fn __rdl_dealloc(ptr: *mut u8,
52                                        size: usize,
53                                        align: usize) {
54         System.dealloc(ptr, Layout::from_size_align_unchecked(size, align))
55     }
56
57     #[no_mangle]
58     pub unsafe extern fn __rdl_usable_size(layout: *const u8,
59                                            min: *mut usize,
60                                            max: *mut usize) {
61         let pair = System.usable_size(&*(layout as *const Layout));
62         *min = pair.0;
63         *max = pair.1;
64     }
65
66     #[no_mangle]
67     pub unsafe extern fn __rdl_realloc(ptr: *mut u8,
68                                        old_size: usize,
69                                        old_align: usize,
70                                        new_size: usize,
71                                        new_align: usize,
72                                        err: *mut u8) -> *mut u8 {
73         let old_layout = Layout::from_size_align_unchecked(old_size, old_align);
74         let new_layout = Layout::from_size_align_unchecked(new_size, new_align);
75         match System.realloc(ptr, old_layout, new_layout) {
76             Ok(p) => p,
77             Err(e) => {
78                 ptr::write(err as *mut AllocErr, e);
79                 0 as *mut u8
80             }
81         }
82     }
83
84     #[no_mangle]
85     pub unsafe extern fn __rdl_alloc_zeroed(size: usize,
86                                             align: usize,
87                                             err: *mut u8) -> *mut u8 {
88         let layout = Layout::from_size_align_unchecked(size, align);
89         match System.alloc_zeroed(layout) {
90             Ok(p) => p,
91             Err(e) => {
92                 ptr::write(err as *mut AllocErr, e);
93                 0 as *mut u8
94             }
95         }
96     }
97
98     #[no_mangle]
99     pub unsafe extern fn __rdl_alloc_excess(size: usize,
100                                             align: usize,
101                                             excess: *mut usize,
102                                             err: *mut u8) -> *mut u8 {
103         let layout = Layout::from_size_align_unchecked(size, align);
104         match System.alloc_excess(layout) {
105             Ok(p) => {
106                 *excess = p.1;
107                 p.0
108             }
109             Err(e) => {
110                 ptr::write(err as *mut AllocErr, e);
111                 0 as *mut u8
112             }
113         }
114     }
115
116     #[no_mangle]
117     pub unsafe extern fn __rdl_realloc_excess(ptr: *mut u8,
118                                               old_size: usize,
119                                               old_align: usize,
120                                               new_size: usize,
121                                               new_align: usize,
122                                               excess: *mut usize,
123                                               err: *mut u8) -> *mut u8 {
124         let old_layout = Layout::from_size_align_unchecked(old_size, old_align);
125         let new_layout = Layout::from_size_align_unchecked(new_size, new_align);
126         match System.realloc_excess(ptr, old_layout, new_layout) {
127             Ok(p) => {
128                 *excess = p.1;
129                 p.0
130             }
131             Err(e) => {
132                 ptr::write(err as *mut AllocErr, e);
133                 0 as *mut u8
134             }
135         }
136     }
137
138     #[no_mangle]
139     pub unsafe extern fn __rdl_grow_in_place(ptr: *mut u8,
140                                              old_size: usize,
141                                              old_align: usize,
142                                              new_size: usize,
143                                              new_align: usize) -> u8 {
144         let old_layout = Layout::from_size_align_unchecked(old_size, old_align);
145         let new_layout = Layout::from_size_align_unchecked(new_size, new_align);
146         match System.grow_in_place(ptr, old_layout, new_layout) {
147             Ok(()) => 1,
148             Err(_) => 0,
149         }
150     }
151
152     #[no_mangle]
153     pub unsafe extern fn __rdl_shrink_in_place(ptr: *mut u8,
154                                                old_size: usize,
155                                                old_align: usize,
156                                                new_size: usize,
157                                                new_align: usize) -> u8 {
158         let old_layout = Layout::from_size_align_unchecked(old_size, old_align);
159         let new_layout = Layout::from_size_align_unchecked(new_size, new_align);
160         match System.shrink_in_place(ptr, old_layout, new_layout) {
161             Ok(()) => 1,
162             Err(_) => 0,
163         }
164     }
165 }