      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
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100

    // Copyright 2015 The Ramp Developers
    //
    //    Licensed under the Apache License, Version 2.0 (the "License");
    //    you may not use this file except in compliance with the License.
    //    You may obtain a copy of the License at
    //
    //        http://www.apache.org/licenses/LICENSE-2.0
    //
    //    Unless required by applicable law or agreed to in writing, software
    //    distributed under the License is distributed on an "AS IS" BASIS,
    //    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //    See the License for the specific language governing permissions and
    //    limitations under the License.

    //! Memory management functions. The base functions align to a pointer-width, so they shouldn't
    //! be used for anything that requires an alignment greater than that.

    use alloc::heap;
    use std::mem;
    use std::intrinsics::abort;
    use std::io::{self, Write};
    use std::ptr;

    use ll::limb::Limb;
    use ll::limb_ptr::LimbsMut;

    pub unsafe fn allocate_bytes(size: usize) -> *mut u8 {
        let ret = heap::allocate(size, mem::align_of::<usize>());
        if ret.is_null() {
            let _ = writeln!(io::stderr(), "Failed to allocate memory (size={})", size);
            abort();
        }
        ptr::write_bytes(ret, 0, size);
        ret
    }

    pub unsafe fn deallocate_bytes(ptr: *mut u8, size: usize) {
        heap::deallocate(ptr, size, mem::align_of::<usize>());
    }

    /// Allocate for temporary storage. Ensures that the allocations are
    /// freed when the structure drops
    pub struct TmpAllocator {
        mark: *mut Marker
    }

    struct Marker {
        next: *mut Marker,
        size: usize
    }

    impl TmpAllocator {
        pub fn new() -> TmpAllocator {
            TmpAllocator {
                mark: ptr::null_mut()
            }
        }

        pub unsafe fn allocate_bytes(&mut self, size: usize) -> *mut u8 {
            let size = size + mem::size_of::<Marker>();
            let ptr = allocate_bytes(size);

            let mark = ptr as *mut Marker;
            (*mark).size = size;
            (*mark).next = self.mark;

            self.mark = mark;

            ptr.offset(mem::size_of::<Marker>() as isize)
        }

        /// Allocate space for n limbs
        pub unsafe fn allocate(&mut self, n: usize) -> LimbsMut {
            let ptr = self.allocate_bytes(n * mem::size_of::<Limb>()) as *mut Limb;
            LimbsMut::new(ptr, 0, n as i32)
        }

        /// Allocates space for n1+n2 limbs and returns a pair of pointers.
        pub unsafe fn allocate_2(&mut self, n1: usize, n2: usize) -> (LimbsMut, LimbsMut) {
            let mut x = self.allocate(n1 + n2);
            let mut y = x.offset(n1 as isize);
            (LimbsMut::new(&mut *x, 0, n1 as i32),
             LimbsMut::new(&mut *y, 0, n2 as i32))
        }
    }

    impl Drop for TmpAllocator {
        fn drop(&mut self) {
            unsafe {
                let mut next;
                let mut mark = self.mark;
                while !mark.is_null() {
                    next = (*mark).next;
                    let size = (*mark).size;
                    deallocate_bytes(mark as *mut u8, size);
                    mark = next;
                }
            }
        }
    }

# Help

## Keyboard Shortcuts

?
  Show this help dialog
S
  Focus the search field
⇤
  Move up in search results
⇥
  Move down in search results
⏎
  Go to active search result

## Search Tricks

Prefix searches with a type followed by a colon (e.g. `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g. `vec -> usize` or `* -> vec`)