Skip to content

Commit e86d9e7

Browse files
committed
fix big-allocs perf
1 parent 9f1047e commit e86d9e7

File tree

2 files changed

+13
-30
lines changed

2 files changed

+13
-30
lines changed

src/alloc/discrete_alloc.rs

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ pub struct MachineAlloc {
1212
/// the global allocator.
1313
pages: Vec<*mut u8>,
1414
/// Pointers to multi-page-sized allocations. These must also be page-aligned,
15-
/// with a size of `page_size * count` (where `count` is the second element
16-
/// of the vector).
15+
/// with their size stored as the second element of the vector.
1716
huge_allocs: Vec<(*mut u8, usize)>,
1817
/// Metadata about which bytes have been allocated on each page. The length
1918
/// of this vector must be the same as that of `pages`, and the length of the
@@ -45,7 +44,7 @@ impl MachineAlloc {
4544
huge_allocs: Vec::new(),
4645
allocated: Vec::new(),
4746
page_size: 4096,
48-
enabled: false,
47+
enabled: true,
4948
}
5049
}
5150

@@ -79,15 +78,6 @@ impl MachineAlloc {
7978
(size, align)
8079
}
8180

82-
/// If a requested allocation is greater than one page, we simply allocate
83-
/// a fixed number of pages for it.
84-
#[inline]
85-
fn huge_normalized_layout(&self, layout: Layout) -> (usize, usize) {
86-
let size = layout.size().next_multiple_of(self.page_size);
87-
let align = std::cmp::max(layout.align(), self.page_size);
88-
(size, align)
89-
}
90-
9181
/// Allocates memory as described in `Layout`. If `MachineAlloc::enable()`
9282
/// has *not* been called yet, this is just a wrapper for `(alloc::alloc(),
9383
/// true)`. Otherwise, it will allocate from its own memory pool and
@@ -100,7 +90,7 @@ impl MachineAlloc {
10090
let mut alloc = ALLOCATOR.lock().unwrap();
10191
unsafe {
10292
if alloc.enabled {
103-
(alloc.alloc_inner(layout), false)
93+
(alloc.alloc_inner(layout, alloc::alloc), false)
10494
} else {
10595
(alloc::alloc(layout), true)
10696
}
@@ -115,12 +105,7 @@ impl MachineAlloc {
115105
pub unsafe fn alloc_zeroed(layout: Layout) -> (*mut u8, bool) {
116106
let mut alloc = ALLOCATOR.lock().unwrap();
117107
if alloc.enabled {
118-
let ptr = unsafe { alloc.alloc_inner(layout) };
119-
if !ptr.is_null() {
120-
unsafe {
121-
ptr.write_bytes(0, layout.size());
122-
}
123-
}
108+
let ptr = unsafe { alloc.alloc_inner(layout, alloc::alloc_zeroed) };
124109
(ptr, false)
125110
} else {
126111
unsafe { (alloc::alloc_zeroed(layout), true) }
@@ -129,11 +114,13 @@ impl MachineAlloc {
129114

130115
/// SAFETY: The allocator must have been `enable()`d already and
131116
/// the `layout` must be valid.
132-
unsafe fn alloc_inner(&mut self, layout: Layout) -> *mut u8 {
117+
unsafe fn alloc_inner(&mut self, layout: Layout, sys_allocator: unsafe fn(Layout) -> *mut u8) -> *mut u8 {
133118
let (size, align) = MachineAlloc::normalized_layout(layout);
134119

135120
if align > self.page_size || size > self.page_size {
136-
unsafe { self.alloc_multi_page(layout) }
121+
unsafe {
122+
self.alloc_multi_page(layout, sys_allocator)
123+
}
137124
} else {
138125
for (page, pinfo) in std::iter::zip(&mut self.pages, &mut self.allocated) {
139126
for idx in (0..self.page_size).step_by(align) {
@@ -157,18 +144,15 @@ impl MachineAlloc {
157144

158145
// We get here only if there's no space in our existing pages
159146
self.add_page();
160-
unsafe { self.alloc_inner(layout) }
147+
unsafe { self.alloc_inner(layout, sys_allocator) }
161148
}
162149
}
163150

164151
/// SAFETY: Same as `alloc_inner()` with the added requirement that `layout`
165152
/// must ask for a size larger than the host pagesize.
166-
unsafe fn alloc_multi_page(&mut self, layout: Layout) -> *mut u8 {
167-
let (size, align) = self.huge_normalized_layout(layout);
168-
169-
let layout = unsafe { Layout::from_size_align_unchecked(size, align) };
170-
let ret = unsafe { alloc::alloc(layout) };
171-
self.huge_allocs.push((ret, size));
153+
unsafe fn alloc_multi_page(&mut self, layout: Layout, sys_allocator: unsafe fn(Layout) -> *mut u8) -> *mut u8 {
154+
let ret = unsafe { sys_allocator(layout) };
155+
self.huge_allocs.push((ret, layout.size()));
172156
ret
173157
}
174158

@@ -236,9 +220,7 @@ impl MachineAlloc {
236220
.find(|pg| ptr.addr() == pg.1.0.addr())
237221
.expect("Freeing unallocated pages");
238222
let ptr = self.huge_allocs.remove(idx).0;
239-
let (size, align) = self.huge_normalized_layout(layout);
240223
unsafe {
241-
let layout = Layout::from_size_align_unchecked(size, align);
242224
alloc::dealloc(ptr, layout);
243225
}
244226
}

src/alloc/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#[cfg(target_os = "linux")]
12
mod alloc_bytes;
23
pub mod discrete_alloc;
34

0 commit comments

Comments
 (0)