Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This commit introduces a proper thread-safe bump allocator to bh_alloc. The previous allocator is now moved to the `fuzz` sub-module. This work was inspired by a Reddit [conversation](https://www.reddit.com/r/rust/comments/9twam5/jemalloc_was_just_removed_from_the_standard/e902qnh/). I felt pretty bad that my poor fuzzy allocator got held up to demonstrate a general purpose bump allocator. :) Anyway, the only dicey bit here is the AtomicUsize. I haven't done any stress testing on an ARM machine, which should be done. x86 has stricter memory ordering, hiding bugs that only turn up under ARM. Signed-off-by: Brian L. Troutwine <brian@troutwine.us>
- Loading branch information
Showing
5 changed files
with
139 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
//! Allocators suitable for fuzzing environments | ||
//! | ||
//! The allocators available in this sub-crate are intended to be used in | ||
//! fuzzing targets. The number of branches are kept intentionally low and | ||
//! suitability for threaded environments are a non-priority. | ||
|
||
extern crate libc; | ||
|
||
use self::libc::{_exit, EXIT_SUCCESS}; | ||
|
||
use std::alloc::{GlobalAlloc, Layout}; | ||
use std::cell::UnsafeCell; | ||
|
||
/// Total number of bytes that [`BumpAlloc`] will have available to it. | ||
pub const TOTAL_BYTES: usize = 500_000_000; // 500 MB | ||
static mut HEAP: [u8; TOTAL_BYTES] = [0; TOTAL_BYTES]; | ||
|
||
/// Bump allocator for *single* core systems | ||
/// | ||
/// A bump allocator keeps a single pointer to the start of the unitialized | ||
/// heap. When an allocation happens this pointer is 'bumped' sufficiently to | ||
/// fit the allocation. Deallocations have no effect on the pointer, meaning | ||
/// that memory is allocated at program start and never freed. This is very | ||
/// fast. | ||
/// | ||
/// BumpAlloc has an additional feature. When all its heap memory is exhausted | ||
/// `libc::_exit(EXIT_SUCCESS)` is called. This behaviour aids in the production | ||
/// of fuzzers. | ||
pub struct BumpAlloc { | ||
offset: UnsafeCell<usize>, | ||
} | ||
|
||
unsafe impl Sync for BumpAlloc {} | ||
|
||
// thanks, wee_alloc | ||
trait ConstInit { | ||
const INIT: Self; | ||
} | ||
|
||
impl ConstInit for BumpAlloc { | ||
const INIT: BumpAlloc = BumpAlloc { | ||
offset: UnsafeCell::new(0), | ||
}; | ||
} | ||
|
||
impl BumpAlloc { | ||
/// Initialization for [`BumpAlloc`] | ||
/// | ||
/// See the binaries in this repository for full examples. | ||
pub const INIT: Self = <Self as ConstInit>::INIT; | ||
} | ||
|
||
unsafe impl GlobalAlloc for BumpAlloc { | ||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 { | ||
let offset = self.offset.get(); | ||
let byte_size: usize = layout.size() as usize; | ||
|
||
let end = *offset + byte_size; | ||
|
||
if end >= TOTAL_BYTES { | ||
_exit(EXIT_SUCCESS); | ||
} else { | ||
let p = HEAP[*offset..end].as_mut_ptr() as *mut u8; | ||
*offset = end; | ||
p | ||
} | ||
} | ||
|
||
unsafe fn dealloc(&self, _: *mut u8, _: Layout) { | ||
// never deallocate | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters