1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// Copyright 2017 the authors. See the 'Copyright and license' section of the
// README.md file at the top-level directory of this repository.
//
// Licensed under the Apache License, Version 2.0 (the LICENSE file). This file
// may not be copied, modified, or distributed except according to those terms.

#![no_std]
#![feature(allocator_api)]
#![feature(alloc)]
#![feature(global_allocator)]
extern crate alloc;
#[macro_use]
extern crate lazy_static;
extern crate mmap_alloc;
mod bsalloc;
use bsalloc::{BsAlloc, ALLOC};
use self::alloc::allocator::{Alloc, AllocErr, Layout};
use core::cmp;
use core::ptr;

#[cfg(debug_assertions)]
fn assert_nonoverlapping(r1: (usize, usize), r2: (usize, usize)) {
    let (_, b) = cmp::min(r1, r2);
    let (c, _) = cmp::max(r1, r2);
    assert!(c >= b);
}

#[global_allocator]
static GLOBAL: BsAlloc = BsAlloc;

unsafe impl<'a> Alloc for &'a BsAlloc {
    unsafe fn alloc(&mut self, l: Layout) -> Result<*mut u8, AllocErr> {
        Ok((*ALLOC).alloc(l.size()))
    }

    unsafe fn dealloc(&mut self, item: *mut u8, l: Layout) {
        (*ALLOC).free(item, l.size())
    }

    unsafe fn realloc(
        &mut self,
        ptr: *mut u8,
        old_l: Layout,
        new_l: Layout,
    ) -> Result<*mut u8, AllocErr> {
        let old_size = old_l.size();
        let new_size = new_l.size();
        let new_memory = self.alloc(new_l).expect("alloc failed");
        #[cfg(debug_assertions)]
        {
            assert_nonoverlapping(
                (ptr as usize, ptr as usize + old_size),
                (new_memory as usize, new_memory as usize + new_size),
            );
        }
        ptr::copy_nonoverlapping(ptr, new_memory, cmp::min(old_size, new_size));
        self.dealloc(ptr, old_l);
        Ok(new_memory)
    }
}