address_map.rs 1.78 KB
Newer Older
Isaac Oscar Gariano's avatar
Isaac Oscar Gariano committed
1
// Copyright 2017 The Australian National University
qinsoon's avatar
qinsoon committed
2
//
Isaac Oscar Gariano's avatar
Isaac Oscar Gariano committed
3 4 5
// 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
qinsoon's avatar
qinsoon committed
6
//
Isaac Oscar Gariano's avatar
Isaac Oscar Gariano committed
7
//     http://www.apache.org/licenses/LICENSE-2.0
qinsoon's avatar
qinsoon committed
8
//
Isaac Oscar Gariano's avatar
Isaac Oscar Gariano committed
9 10 11 12 13 14
// 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.

15
use std::mem;
qinsoon's avatar
qinsoon committed
16
use utils::POINTER_SIZE;
qinsoon's avatar
qinsoon committed
17 18 19
use utils::LOG_POINTER_SIZE;
use utils::Address;
use heap::gc::malloc_zero;
20 21 22

#[derive(Clone)]
pub struct AddressMap<T: Copy> {
qinsoon's avatar
qinsoon committed
23 24 25 26
    start: Address,
    end: Address,

    pub ptr: *mut T,
27
    len: usize
28 29
}

qinsoon's avatar
qinsoon committed
30 31
impl<T> AddressMap<T>
where
32
    T: Copy
qinsoon's avatar
qinsoon committed
33
{
34
    pub fn new(start: Address, end: Address) -> AddressMap<T> {
35
        let len = (end - start) >> LOG_POINTER_SIZE;
qinsoon's avatar
qinsoon committed
36 37 38 39 40 41
        let ptr = unsafe { malloc_zero(mem::size_of::<T>() * len) } as *mut T;

        AddressMap {
            start: start,
            end: end,
            ptr: ptr,
42
            len: len
qinsoon's avatar
qinsoon committed
43
        }
44
    }
qinsoon's avatar
qinsoon committed
45 46

    pub fn init_all(&self, init: T) {
qinsoon's avatar
qinsoon committed
47
        let mut cursor = self.start;
qinsoon's avatar
qinsoon committed
48

qinsoon's avatar
qinsoon committed
49 50
        while cursor < self.end {
            self.set(cursor, init);
51
            cursor = cursor + POINTER_SIZE;
qinsoon's avatar
qinsoon committed
52 53
        }
    }
qinsoon's avatar
qinsoon committed
54

55 56
    #[inline(always)]
    pub fn set(&self, addr: Address, value: T) {
57
        let index = ((addr - self.start) >> LOG_POINTER_SIZE) as isize;
qinsoon's avatar
qinsoon committed
58
        unsafe { *self.ptr.offset(index) = value };
59 60 61 62
    }

    #[inline(always)]
    pub fn get(&self, addr: Address) -> T {
63
        let index = ((addr - self.start) >> LOG_POINTER_SIZE) as isize;
qinsoon's avatar
qinsoon committed
64
        unsafe { *self.ptr.offset(index) }
65
    }
66
}