GitLab will be upgraded on June 2nd 2020 at 2.00 pm (AEDT) to 3.00 pm (AEDT) due to Critical Security Patch Availability. During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to local Gitlab admin team.

Commit c95de6d9 authored by John Zhang's avatar John Zhang

Merge branch 'master' of gitlab.anu.edu.au:mu/mu-impl-fast

parents 9fb3ab73 ecf4a191
use utils::Address;
use heap::immix;
use heap::gc;
use aligned_alloc;
use std::collections::LinkedList;
use std::sync::Arc;
use std::sync::RwLock;
pub struct FreeListSpace {
current_nodes : LinkedList<Box<FreeListNode>>,
node_id: usize,
size : usize,
used_bytes : usize
}
impl FreeListSpace {
pub fn new(size: usize) -> FreeListSpace {
FreeListSpace {
current_nodes: LinkedList::new(),
node_id: 0,
size: size,
used_bytes: 0
}
}
#[allow(unused_variables)]
pub fn mark(&mut self, obj: Address) {
}
pub fn alloc(&mut self, size: usize, align: usize) -> Option<Address> {
if self.used_bytes + size > self.size {
None
} else {
let ret = aligned_alloc::aligned_alloc(size, align);
let addr = Address::from_ptr::<()>(ret);
self.current_nodes.push_front(Box::new(FreeListNode{id: self.node_id, start: addr, size: size, mark: NodeMark::FreshAlloc}));
self.node_id += 1;
self.used_bytes += size;
Some(addr)
}
}
pub fn sweep(&mut self) {
let (new_nodes, new_used_bytes) = {
let mut ret = LinkedList::new();
let nodes = &mut self.current_nodes;
let mut used_bytes = 0;
while !nodes.is_empty() {
let mut node = nodes.pop_front().unwrap();
match node.mark {
NodeMark::Live => {
node.set_mark(NodeMark::PrevLive);
used_bytes += node.size;
ret.push_back(node);
},
NodeMark::PrevLive | NodeMark::FreshAlloc => {
let ptr = node.start.to_ptr::<()>() as *mut ();
// free the memory
unsafe {aligned_alloc::aligned_free(ptr);}
// do not add this node into new linked list
}
}
}
(ret, used_bytes)
};
self.current_nodes = new_nodes;
self.used_bytes = new_used_bytes;
}
pub fn current_nodes(&self) -> &LinkedList<Box<FreeListNode>> {
&self.current_nodes
}
pub fn current_nodes_mut(&mut self) -> &mut LinkedList<Box<FreeListNode>> {
&mut self.current_nodes
}
}
pub struct FreeListNode {
id: usize,
start : Address,
size : usize,
mark : NodeMark
}
impl FreeListNode {
pub fn set_mark(&mut self, mark: NodeMark) {
self.mark = mark;
}
}
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum NodeMark {
FreshAlloc,
PrevLive,
Live,
}
unsafe impl Sync for NodeMark {}
#[inline(never)]
pub fn alloc_large(size: usize, align: usize, mutator: &mut immix::ImmixMutatorLocal, space: Arc<RwLock<FreeListSpace>>) -> Address {
loop {
mutator.yieldpoint();
let ret_addr = {
let mut lo_space_lock = space.write().unwrap();
lo_space_lock.alloc(size, align)
};
match ret_addr {
Some(addr) => {
return addr;
},
None => {
gc::trigger_gc();
}
}
}
}
use std::fmt;
impl fmt::Display for FreeListSpace {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "FreeListSpace\n").unwrap();
write!(f, "{} used, {} total\n", self.used_bytes, self.size).unwrap();
write!(f, "nodes:\n").unwrap();
for node in self.current_nodes() {
write!(f, " {}\n", node).unwrap();
}
write!(f, "done\n")
}
}
impl fmt::Display for FreeListNode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "FreeListNode#{}(start={:#X}, size={}, state={:?})", self.id, self.start, self.size, self.mark)
}
}
\ No newline at end of file
use utils::Address;
use heap::immix;
use heap::gc;
use aligned_alloc;
mod malloc_list;
mod treadmill;
use std::collections::LinkedList;
use std::sync::Arc;
use std::sync::RwLock;
pub struct FreeListSpace {
current_nodes : LinkedList<Box<FreeListNode>>,
node_id: usize,
size : usize,
used_bytes : usize
}
impl FreeListSpace {
pub fn new(size: usize) -> FreeListSpace {
FreeListSpace {
current_nodes: LinkedList::new(),
node_id: 0,
size: size,
used_bytes: 0
}
}
#[allow(unused_variables)]
pub fn mark(&mut self, obj: Address) {
}
pub fn alloc(&mut self, size: usize, align: usize) -> Option<Address> {
if self.used_bytes + size > self.size {
None
} else {
let ret = aligned_alloc::aligned_alloc(size, align);
let addr = Address::from_ptr::<()>(ret);
self.current_nodes.push_front(Box::new(FreeListNode{id: self.node_id, start: addr, size: size, mark: NodeMark::FreshAlloc}));
self.node_id += 1;
self.used_bytes += size;
Some(addr)
}
}
pub fn sweep(&mut self) {
let (new_nodes, new_used_bytes) = {
let mut ret = LinkedList::new();
let nodes = &mut self.current_nodes;
let mut used_bytes = 0;
while !nodes.is_empty() {
let mut node = nodes.pop_front().unwrap();
match node.mark {
NodeMark::Live => {
node.set_mark(NodeMark::PrevLive);
used_bytes += node.size;
ret.push_back(node);
},
NodeMark::PrevLive | NodeMark::FreshAlloc => {
let ptr = node.start.to_ptr::<()>() as *mut ();
// free the memory
unsafe {aligned_alloc::aligned_free(ptr);}
// do not add this node into new linked list
}
}
}
(ret, used_bytes)
};
self.current_nodes = new_nodes;
self.used_bytes = new_used_bytes;
}
pub fn current_nodes(&self) -> &LinkedList<Box<FreeListNode>> {
&self.current_nodes
}
pub fn current_nodes_mut(&mut self) -> &mut LinkedList<Box<FreeListNode>> {
&mut self.current_nodes
}
}
pub struct FreeListNode {
id: usize,
start : Address,
size : usize,
mark : NodeMark
}
impl FreeListNode {
pub fn set_mark(&mut self, mark: NodeMark) {
self.mark = mark;
}
}
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum NodeMark {
FreshAlloc,
PrevLive,
Live,
}
unsafe impl Sync for NodeMark {}
#[inline(never)]
pub fn alloc_large(size: usize, align: usize, mutator: &mut immix::ImmixMutatorLocal, space: Arc<RwLock<FreeListSpace>>) -> Address {
loop {
mutator.yieldpoint();
let ret_addr = {
let mut lo_space_lock = space.write().unwrap();
lo_space_lock.alloc(size, align)
};
match ret_addr {
Some(addr) => {
return addr;
},
None => {
gc::trigger_gc();
}
}
}
}
use std::fmt;
impl fmt::Display for FreeListSpace {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "FreeListSpace\n").unwrap();
write!(f, "{} used, {} total\n", self.used_bytes, self.size).unwrap();
write!(f, "nodes:\n").unwrap();
for node in self.current_nodes() {
write!(f, " {}\n", node).unwrap();
}
write!(f, "done\n")
}
}
impl fmt::Display for FreeListNode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "FreeListNode#{}(start={:#X}, size={}, state={:?})", self.id, self.start, self.size, self.mark)
}
}
\ No newline at end of file
pub use heap::freelist::malloc_list::FreeListSpace;
pub use heap::freelist::malloc_list::alloc_large;
\ No newline at end of file
#![allow(dead_code)]
use utils::Address;
use utils::mem::memmap;
use std::ptr;
use std::sync::Arc;
use common::AddressMap;
const SPACE_ALIGN : usize = 1 << 19;
const BLOCK_SIZE : usize = 1 << 12; // 4kb
#[repr(C)]
pub struct FreeListSpace {
start : Address,
end : Address,
pub alloc_map : Arc<AddressMap<u8>>,
pub trace_map : Arc<AddressMap<u8>>,
#[allow(dead_code)]
mmap : memmap::Mmap,
treadmill: TreadMill
}
impl FreeListSpace {
pub fn new(space_size: usize) -> FreeListSpace {
let anon_mmap : memmap::Mmap = match memmap::Mmap::anonymous(space_size + SPACE_ALIGN, memmap::Protection::ReadWrite) {
Ok(m) => m,
Err(_) => panic!("failed to call mmap")
};
let start : Address = Address::from_ptr::<u8>(anon_mmap.ptr()).align_up(SPACE_ALIGN);
let end : Address = start.plus(space_size);
unimplemented!()
}
}
struct TreadMill{
free: *mut TreadMillNode,
scan: *mut TreadMillNode,
t : *mut TreadMillNode,
b : *mut TreadMillNode
}
impl TreadMill {
fn new(start: Address, end: Address) -> TreadMill {
let mut addr = start;
let free = TreadMillNode::singleton(addr);
let mut tail = free;
while addr < end {
tail = TreadMillNode::insert_after(tail, addr);
}
unimplemented!()
}
}
struct TreadMillNode {
payload: Address,
prev: *mut TreadMillNode,
next: *mut TreadMillNode
}
impl TreadMillNode {
fn singleton(addr: Address) -> *mut TreadMillNode {
let mut ptr = Box::into_raw(Box::new(TreadMillNode {
payload: addr,
prev: ptr::null_mut(),
next: ptr::null_mut(),
}));
// first node in the cyclic doubly linked list
unsafe {
(*ptr).prev = ptr;
(*ptr).next = ptr;
}
ptr
}
/// returns the inserted node
fn insert_after(node: *mut TreadMillNode, addr: Address) -> *mut TreadMillNode {
unsafe {
// node <- ptr -> node.next
let mut ptr = Box::into_raw(Box::new(TreadMillNode {
payload: addr,
// inserted between node and node.next
prev: node,
next: (*node).next
}));
// ptr <- node.next
(*(*node).next).prev = ptr;
// node -> ptr
(*node).next = ptr;
ptr
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment