Skip to content

Commit c66f9d4

Browse files
committed
Implement the GlobalAlloc trait, upgrade to nightly-2018-04-15
CC rust-lang/rust#49669
1 parent e9c2722 commit c66f9d4

File tree

4 files changed

+75
-131
lines changed

4 files changed

+75
-131
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "jemallocator"
3-
version = "0.1.4"
3+
version = "0.1.5"
44
authors = ["Alex Crichton <alex@alexcrichton.com>"]
55
license = "MIT/Apache-2.0"
66
readme = "README.md"

src/lib.rs

+71-128
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@
1515
//! `Alloc` trait and is suitable both as a memory allocator and as a
1616
//! global allocator.
1717
18-
#![feature(allocator_api)]
18+
#![feature(allocator_api, nonnull_cast)]
1919
#![deny(missing_docs)]
2020

2121
extern crate jemalloc_sys;
2222
extern crate libc;
2323

2424
use std::mem;
25-
use std::ptr;
26-
use std::heap::{Alloc, Layout, Excess, CannotReallocInPlace, AllocErr, System};
25+
use std::ptr::{self, NonNull};
26+
use std::heap::{GlobalAlloc, Alloc, Layout, Opaque, Excess, CannotReallocInPlace, AllocErr, System};
2727

2828
use libc::{c_int, c_void};
2929

@@ -45,16 +45,16 @@ const MIN_ALIGN: usize = 8;
4545
target_arch = "sparc64")))]
4646
const MIN_ALIGN: usize = 16;
4747

48-
fn layout_to_flags(layout: &Layout) -> c_int {
48+
fn layout_to_flags(align: usize, size: usize) -> c_int {
4949
// If our alignment is less than the minimum alignment they we may not
5050
// have to pass special flags asking for a higher alignment. If the
5151
// alignment is greater than the size, however, then this hits a sort of odd
5252
// case where we still need to ask for a custom alignment. See #25 for more
5353
// info.
54-
if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
54+
if align <= MIN_ALIGN && align <= size {
5555
0
5656
} else {
57-
ffi::MALLOCX_ALIGN(layout.align())
57+
ffi::MALLOCX_ALIGN(align)
5858
}
5959
}
6060

@@ -66,160 +66,106 @@ fn layout_to_flags(layout: &Layout) -> c_int {
6666
/// allocator.
6767
pub struct Jemalloc;
6868

69-
unsafe impl Alloc for Jemalloc {
70-
#[inline]
71-
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
72-
(&*self).alloc(layout)
73-
}
74-
75-
#[inline]
76-
unsafe fn alloc_zeroed(&mut self, layout: Layout)
77-
-> Result<*mut u8, AllocErr>
78-
{
79-
(&*self).alloc_zeroed(layout)
80-
}
81-
69+
unsafe impl GlobalAlloc for Jemalloc {
8270
#[inline]
83-
unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
84-
(&*self).dealloc(ptr, layout)
71+
unsafe fn alloc(&self, layout: Layout) -> *mut Opaque {
72+
let flags = layout_to_flags(layout.align(), layout.size());
73+
let ptr = ffi::mallocx(layout.size(), flags);
74+
ptr as *mut Opaque
8575
}
8676

8777
#[inline]
88-
unsafe fn realloc(&mut self,
89-
ptr: *mut u8,
90-
old_layout: Layout,
91-
new_layout: Layout) -> Result<*mut u8, AllocErr> {
92-
(&*self).realloc(ptr, old_layout, new_layout)
93-
}
94-
95-
fn oom(&mut self, err: AllocErr) -> ! {
96-
(&*self).oom(err)
78+
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Opaque {
79+
let ptr = if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
80+
ffi::calloc(1, layout.size())
81+
} else {
82+
let flags = layout_to_flags(layout.align(), layout.size()) | ffi::MALLOCX_ZERO;
83+
ffi::mallocx(layout.size(), flags)
84+
};
85+
ptr as *mut Opaque
9786
}
9887

9988
#[inline]
100-
fn usable_size(&self, layout: &Layout) -> (usize, usize) {
101-
(&self).usable_size(layout)
89+
unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout) {
90+
let flags = layout_to_flags(layout.align(), layout.size());
91+
ffi::sdallocx(ptr as *mut c_void, layout.size(), flags)
10292
}
10393

10494
#[inline]
105-
unsafe fn alloc_excess(&mut self, layout: Layout) -> Result<Excess, AllocErr> {
106-
(&*self).alloc_excess(layout)
95+
unsafe fn realloc(&self,
96+
ptr: *mut Opaque,
97+
layout: Layout,
98+
new_size: usize) -> *mut Opaque {
99+
let flags = layout_to_flags(layout.align(), new_size);
100+
let ptr = ffi::rallocx(ptr as *mut c_void, new_size, flags);
101+
ptr as *mut Opaque
107102
}
108103

109104
#[inline]
110-
unsafe fn realloc_excess(&mut self,
111-
ptr: *mut u8,
112-
layout: Layout,
113-
new_layout: Layout) -> Result<Excess, AllocErr> {
114-
(&*self).realloc_excess(ptr, layout, new_layout)
105+
fn oom(&self) -> ! {
106+
System.oom()
115107
}
108+
}
116109

110+
unsafe impl Alloc for Jemalloc {
117111
#[inline]
118-
unsafe fn grow_in_place(&mut self,
119-
ptr: *mut u8,
120-
layout: Layout,
121-
new_layout: Layout) -> Result<(), CannotReallocInPlace> {
122-
(&*self).grow_in_place(ptr, layout, new_layout)
112+
unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<Opaque>, AllocErr> {
113+
NonNull::new(GlobalAlloc::alloc(self, layout)).ok_or(AllocErr)
123114
}
124115

125116
#[inline]
126-
unsafe fn shrink_in_place(&mut self,
127-
ptr: *mut u8,
128-
layout: Layout,
129-
new_layout: Layout) -> Result<(), CannotReallocInPlace> {
130-
(&*self).shrink_in_place(ptr, layout, new_layout)
117+
unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<Opaque>, AllocErr> {
118+
NonNull::new(GlobalAlloc::alloc_zeroed(self, layout)).ok_or(AllocErr)
131119
}
132-
}
133120

134-
unsafe impl<'a> Alloc for &'a Jemalloc {
135121
#[inline]
136-
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
137-
let flags = layout_to_flags(&layout);
138-
let ptr = ffi::mallocx(layout.size(), flags);
139-
if ptr.is_null() {
140-
Err(AllocErr::Exhausted { request: layout })
141-
} else {
142-
Ok(ptr as *mut u8)
143-
}
122+
unsafe fn dealloc(&mut self, ptr: NonNull<Opaque>, layout: Layout) {
123+
GlobalAlloc::dealloc(self, ptr.as_ptr(), layout)
144124
}
145125

146126
#[inline]
147-
unsafe fn alloc_zeroed(&mut self, layout: Layout)
148-
-> Result<*mut u8, AllocErr>
149-
{
150-
let ptr = if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
151-
ffi::calloc(1, layout.size())
152-
} else {
153-
let flags = layout_to_flags(&layout) | ffi::MALLOCX_ZERO;
154-
ffi::mallocx(layout.size(), flags)
155-
};
156-
if ptr.is_null() {
157-
Err(AllocErr::Exhausted { request: layout })
158-
} else {
159-
Ok(ptr as *mut u8)
160-
}
127+
unsafe fn realloc(&mut self,
128+
ptr: NonNull<Opaque>,
129+
layout: Layout,
130+
new_size: usize) -> Result<NonNull<Opaque>, AllocErr> {
131+
NonNull::new(GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size)).ok_or(AllocErr)
161132
}
162133

163134
#[inline]
164135
unsafe fn alloc_excess(&mut self, layout: Layout) -> Result<Excess, AllocErr> {
165-
let flags = layout_to_flags(&layout);
136+
let flags = layout_to_flags(layout.align(), layout.size());
166137
let ptr = ffi::mallocx(layout.size(), flags);
167-
if ptr.is_null() {
168-
Err(AllocErr::Exhausted { request: layout })
169-
} else {
138+
if let Some(nonnull) = NonNull::new(ptr as *mut Opaque) {
170139
let excess = ffi::nallocx(layout.size(), flags);
171-
Ok(Excess(ptr as *mut u8, excess))
172-
}
173-
}
174-
175-
#[inline]
176-
unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
177-
let flags = layout_to_flags(&layout);
178-
ffi::sdallocx(ptr as *mut c_void, layout.size(), flags)
179-
}
180-
181-
#[inline]
182-
unsafe fn realloc(&mut self,
183-
ptr: *mut u8,
184-
old_layout: Layout,
185-
new_layout: Layout) -> Result<*mut u8, AllocErr> {
186-
if old_layout.align() != new_layout.align() {
187-
return Err(AllocErr::Unsupported { details: "cannot change align" })
188-
}
189-
let flags = layout_to_flags(&new_layout);
190-
let ptr = ffi::rallocx(ptr as *mut c_void, new_layout.size(), flags);
191-
if ptr.is_null() {
192-
Err(AllocErr::Exhausted { request: new_layout })
140+
Ok(Excess(nonnull, excess))
193141
} else {
194-
Ok(ptr as *mut u8)
142+
Err(AllocErr)
195143
}
196144
}
197145

198146
#[inline]
199147
unsafe fn realloc_excess(&mut self,
200-
ptr: *mut u8,
201-
old_layout: Layout,
202-
new_layout: Layout) -> Result<Excess, AllocErr> {
203-
if old_layout.align() != new_layout.align() {
204-
return Err(AllocErr::Unsupported { details: "cannot change align" })
205-
}
206-
let flags = layout_to_flags(&new_layout);
207-
let ptr = ffi::rallocx(ptr as *mut c_void, new_layout.size(), flags);
208-
if ptr.is_null() {
209-
Err(AllocErr::Exhausted { request: new_layout })
148+
ptr: NonNull<Opaque>,
149+
layout: Layout,
150+
new_size: usize) -> Result<Excess, AllocErr> {
151+
let flags = layout_to_flags(layout.align(), new_size);
152+
let ptr = ffi::rallocx(ptr.cast().as_ptr(), new_size, flags);
153+
if let Some(nonnull) = NonNull::new(ptr as *mut Opaque) {
154+
let excess = ffi::nallocx(new_size, flags);
155+
Ok(Excess(nonnull, excess))
210156
} else {
211-
let excess = ffi::nallocx(new_layout.size(), flags);
212-
Ok(Excess(ptr as *mut u8, excess))
157+
Err(AllocErr)
213158
}
214159
}
215160

216-
fn oom(&mut self, err: AllocErr) -> ! {
217-
System.oom(err)
161+
#[inline]
162+
fn oom(&mut self) -> ! {
163+
System.oom()
218164
}
219165

220166
#[inline]
221167
fn usable_size(&self, layout: &Layout) -> (usize, usize) {
222-
let flags = layout_to_flags(&layout);
168+
let flags = layout_to_flags(layout.align(), layout.size());
223169
unsafe {
224170
let max = ffi::nallocx(layout.size(), flags);
225171
(layout.size(), max)
@@ -228,23 +174,20 @@ unsafe impl<'a> Alloc for &'a Jemalloc {
228174

229175
#[inline]
230176
unsafe fn grow_in_place(&mut self,
231-
ptr: *mut u8,
232-
old_layout: Layout,
233-
new_layout: Layout) -> Result<(), CannotReallocInPlace> {
234-
self.shrink_in_place(ptr, old_layout, new_layout)
177+
ptr: NonNull<Opaque>,
178+
layout: Layout,
179+
new_size: usize) -> Result<(), CannotReallocInPlace> {
180+
self.shrink_in_place(ptr, layout, new_size)
235181
}
236182

237183
#[inline]
238184
unsafe fn shrink_in_place(&mut self,
239-
ptr: *mut u8,
240-
old_layout: Layout,
241-
new_layout: Layout) -> Result<(), CannotReallocInPlace> {
242-
if old_layout.align() != new_layout.align() {
243-
return Err(CannotReallocInPlace)
244-
}
245-
let flags = layout_to_flags(&new_layout);
246-
let size = ffi::xallocx(ptr as *mut c_void, new_layout.size(), 0, flags);
247-
if size >= new_layout.size() {
185+
ptr: NonNull<Opaque>,
186+
layout: Layout,
187+
new_size: usize) -> Result<(), CannotReallocInPlace> {
188+
let flags = layout_to_flags(layout.align(), new_size);
189+
let size = ffi::xallocx(ptr.cast().as_ptr(), new_size, 0, flags);
190+
if size >= new_size {
248191
Err(CannotReallocInPlace)
249192
} else {
250193
Ok(())

tests/malloctl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ static A: Jemalloc = Jemalloc;
1313
fn smoke() {
1414
let layout = Layout::from_size_align(100, 8).unwrap();
1515
unsafe {
16-
let ptr = Jemalloc.alloc(layout.clone()).unwrap_or_else(|e| Jemalloc.oom(e));
16+
let ptr = Jemalloc.alloc(layout.clone()).unwrap_or_else(|_| Jemalloc.oom());
1717
Jemalloc.dealloc(ptr, layout);
1818
}
1919
}

tests/smoke.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ fn overaligned() {
2525
Jemalloc.alloc(Layout::from_size_align(size, align).unwrap()).unwrap()
2626
}).collect();
2727
for &ptr in &pointers {
28-
assert_eq!((ptr as usize) % align, 0, "Got a pointer less aligned than requested")
28+
assert_eq!((ptr.as_ptr() as usize) % align, 0,
29+
"Got a pointer less aligned than requested")
2930
}
3031

3132
// Clean up

0 commit comments

Comments
 (0)