WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

Commit 36df60dc authored by qinsoon's avatar qinsoon
Browse files

[wip] totally lost on what I am doing

parent f3670528
......@@ -19,4 +19,5 @@ nalgebra = "0.8.2"
linked-hash-map = "0.0.10"
hprof = "0.1.3"
memmap = "0.4.0"
memsec = "0.1.9"
\ No newline at end of file
memsec = "0.1.9"
rustc-serialize = "0.3"
\ No newline at end of file
......@@ -1156,6 +1156,15 @@ pub fn emit_context(vm: &VM) {
file.write("\n".as_bytes()).unwrap();
}
// serialize vm
unimplemented!();
// main_thread
let primordial = vm.primordial.read().unwrap();
if primordial.is_some() {
let primordial = primordial.as_ref().unwrap();
}
debug!("---finish---");
}
......
......@@ -5,11 +5,14 @@ pub mod code_emission;
use utils::ByteSize;
pub type Word = usize;
pub const WORD_SIZE : ByteSize = 8;
// X86_64
#[cfg(target_arch = "x86_64")]
#[path = "arch/x86_64/mod.rs"]
mod x86_64;
pub mod x86_64;
#[cfg(target_arch = "x86_64")]
pub use compiler::backend::x86_64::init_machine_regs_for_func;
......
......@@ -3,11 +3,30 @@ pub extern crate immix_rust as gc;
pub use gc::common::Address;
pub use gc::common::ObjectReference;
pub type Word = usize;
pub mod thread;
pub enum RuntimeValue {
Pointer(Address),
Value(Word)
use ast::ir::*;
use compiler::backend::Word;
use compiler::backend::RegGroup;
#[derive(Clone, Copy, Debug)]
pub enum ValueLocation {
Register(RegGroup, MuID),
Direct(RegGroup, Address),
Indirect(RegGroup, Address),
Constant(RegGroup, Word),
Relocatable(RegGroup, MuName)
}
impl ValueLocation {
pub fn load_value(&self) -> (RegGroup, Word) {
match self {
&ValueLocation::Register(_, _)
| &ValueLocation::Direct(_, _)
| &ValueLocation::Indirect(_, _)
| &ValueLocation::Constant(_, _) => unimplemented!(),
&ValueLocation::Relocatable(_, _) => panic!("expect a runtime value")
}
}
}
\ No newline at end of file
......@@ -3,6 +3,8 @@
__thread void* mu_tls;
void* init_thread_local(void* local) {
return NULL;
void* init_thread_local(void** local) {
mu_tls = *local;
return &mu_tls;
}
......@@ -4,7 +4,7 @@ use ast::ir::*;
use ast::ptr::*;
use ast::types::*;
use vm::VM;
use runtime::RuntimeValue;
use runtime::ValueLocation;
use runtime::gc;
use utils::ByteSize;
......@@ -27,9 +27,8 @@ impl_mu_entity!(MuStack);
pub struct MuStack {
pub hdr: MuEntityHeader,
func_id: MuID,
state: MuStackState,
func_addr: ValueLocation,
func_id: MuID,
size: ByteSize,
// lo addr hi addr
......@@ -49,12 +48,13 @@ pub struct MuStack {
exception_obj : Option<Address>,
state: MuStackState,
#[allow(dead_code)]
mmap : memmap::Mmap
}
impl MuStack {
pub fn new(id: MuID, func: &MuFunction) -> MuStack {
pub fn new(id: MuID, func_addr: ValueLocation, func: &MuFunction) -> MuStack {
let total_size = PAGE_SIZE * 2 + STACK_SIZE;
let anon_mmap = match memmap::Mmap::anonymous(total_size, memmap::Protection::ReadWrite) {
......@@ -83,6 +83,7 @@ impl MuStack {
MuStack {
hdr: MuEntityHeader::unnamed(id),
func_addr: func_addr,
func_id: func.id(),
state: MuStackState::Ready(func.sig.arg_tys.clone()),
......@@ -102,6 +103,61 @@ impl MuStack {
mmap: anon_mmap
}
}
#[cfg(target_arch = "x86_64")]
pub fn runtime_load_args(&mut self, vals: Vec<ValueLocation>) {
use compiler::backend::Word;
use compiler::backend::WORD_SIZE;
use compiler::backend::RegGroup;
use compiler::backend::x86_64;
let mut gpr_used = vec![];
let mut fpr_used = vec![];
for i in 0..vals.len() {
let ref val = vals[i];
let (reg_group, word) = val.load_value();
match reg_group {
RegGroup::GPR => gpr_used.push(word),
RegGroup::FPR => fpr_used.push(word),
}
}
let mut stack_ptr = self.sp;
for i in 0..x86_64::ARGUMENT_FPRs.len() {
stack_ptr = stack_ptr.sub(WORD_SIZE);
let val = {
if i < fpr_used.len() {
fpr_used[i]
} else {
0 as Word
}
};
debug!("store {} to {}", val, stack_ptr);
unsafe {stack_ptr.store(val);}
}
for i in 0..x86_64::ARGUMENT_GPRs.len() {
stack_ptr = stack_ptr.sub(WORD_SIZE);
let val = {
if i < gpr_used.len() {
gpr_used[i]
} else {
0 as Word
}
};
debug!("store {} to {}", val, stack_ptr);
unsafe {stack_ptr.store(val);}
}
// should have put 6 + 6 words on the stack
debug_assert!(self.sp.diff(stack_ptr) == 12 * WORD_SIZE);
// save it back
self.sp = stack_ptr;
}
}
pub enum MuStackState {
......@@ -118,6 +174,13 @@ pub struct MuThread {
user_tls: Option<Address>
}
#[cfg(target_arch = "x86_64")]
#[cfg(target_os = "macos")]
#[link(name = "runtime")]
extern "C" {
fn init_thread_local(thread: &Box<MuThread>) -> Address;
}
impl MuThread {
pub fn new(id: MuID, allocator: Box<gc::Mutator>, stack: Box<MuStack>, user_tls: Option<Address>) -> MuThread {
MuThread {
......@@ -128,10 +191,15 @@ impl MuThread {
}
}
pub fn launch(id: MuID, stack: Box<MuStack>, user_tls: Option<Address>, vals: Vec<RuntimeValue>, vm: &VM) -> JoinHandle<()> {
#[no_mangle]
pub extern fn mu_thread_launch(id: MuID, stack: Box<MuStack>, user_tls: Option<Address>, vm: &VM) -> JoinHandle<()> {
match thread::Builder::new().name(format!("Mu Thread #{}", id)).spawn(move || {
let mut muthread = Box::new(MuThread::new(id, gc::new_mutator(), stack, user_tls));
MuThread::thread_entry(muthread, vm);
let muthread = Box::new(MuThread::new(id, gc::new_mutator(), stack, user_tls));
// set thread local
let addr = unsafe {init_thread_local(&muthread)};
MuThread::thread_entry(muthread);
}) {
Ok(handle) => handle,
Err(_) => panic!("failed to create a thread")
......@@ -139,7 +207,14 @@ impl MuThread {
}
/// entry function for launching a mu thread
pub fn thread_entry(mu_thread: Box<MuThread>, vm: &VM) -> ! {
pub fn thread_entry(mu_thread: Box<MuThread>) -> ! {
let ref stack = mu_thread.stack;
unimplemented!()
}
}
pub struct MuPrimordialThread {
pub func_id: MuID,
pub args: Vec<Constant>
}
\ No newline at end of file
......@@ -8,9 +8,8 @@ use compiler::backend::BackendTypeInfo;
use vm::machine_code::CompiledFunction;
use vm::vm_options::VMOptions;
use runtime::gc;
use runtime::thread::MuStack;
use runtime::RuntimeValue;
use runtime::thread::MuThread;
use runtime::thread::*;
use runtime::ValueLocation;
use utils::Address;
use std::sync::RwLock;
......@@ -38,7 +37,8 @@ pub struct VM {
compiled_funcs: RwLock<HashMap<MuID, RwLock<CompiledFunction>>>,
threads: RwLock<Vec<JoinHandle<()>>>
threads: RwLock<Vec<JoinHandle<()>>>,
pub primordial: RwLock<Option<MuPrimordialThread>>
}
impl <'a> VM {
......@@ -62,7 +62,8 @@ impl <'a> VM {
funcs: RwLock::new(HashMap::new()),
compiled_funcs: RwLock::new(HashMap::new()),
threads: RwLock::new(vec!())
threads: RwLock::new(vec!()),
primordial: RwLock::new(None)
};
ret.is_running.store(false, Ordering::SeqCst);
......@@ -240,14 +241,31 @@ impl <'a> VM {
&self.func_sigs
}
pub fn resolve_function_address(&self, func_id: MuID) -> ValueLocation {
let funcs = self.funcs.read().unwrap();
let func : &MuFunction = &funcs.get(&func_id).unwrap().read().unwrap();
if self.is_running() {
unimplemented!()
} else {
ValueLocation::Relocatable(backend::RegGroup::GPR, func.name().unwrap())
}
}
pub fn new_stack(&self, func_id: MuID) -> Box<MuStack> {
let funcs = self.funcs.read().unwrap();
let func : &MuFunction = &funcs.get(&func_id).unwrap().read().unwrap();
Box::new(MuStack::new(self.next_id(), func))
Box::new(MuStack::new(self.next_id(), self.resolve_function_address(func_id), func))
}
pub fn make_primordial_thread(&self, func_id: MuID, args: Vec<Constant>) {
let mut guard = self.primordial.write().unwrap();
*guard = Some(MuPrimordialThread{func_id: func_id, args: args});
}
pub fn new_thread_normal(&self, stack: Box<MuStack>, threadlocal: Address, vals: Vec<RuntimeValue>) {
#[deprecated]
pub fn new_thread_normal(&self, mut stack: Box<MuStack>, threadlocal: Address, vals: Vec<ValueLocation>) {
let user_tls = {
if threadlocal.is_zero() {
None
......@@ -257,8 +275,11 @@ impl <'a> VM {
};
// set up arguments on stack
unimplemented!();
stack.runtime_load_args(vals);
let handle = MuThread::mu_thread_launch(self.next_id(), stack, user_tls, self);
MuThread::launch(self.next_id(), stack, user_tls, vals, self);
let mut threads = self.threads.write().unwrap();
threads.push(handle);
}
}
mod test_ir;
mod test_compiler;
mod test_vm;
#[macro_use]
mod common {
......
......@@ -27,9 +27,9 @@ fn test_global_access() {
let func_id = vm.id_of("global_access");
let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow();
let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver);
backend::emit_context(&vm);
......
......@@ -24,9 +24,9 @@ fn test_instsel_fac() {
let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow();
let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver);
}
......@@ -21,9 +21,9 @@ fn test_use_count() {
let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow();
let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver);
......@@ -48,9 +48,9 @@ fn test_build_tree() {
let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow();
let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver);
}
......@@ -68,9 +68,9 @@ fn test_cfa_factorial() {
let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow();
let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver);
......@@ -108,9 +108,9 @@ fn test_cfa_sum() {
let func_id = vm.id_of("sum");
let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow();
let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver);
......@@ -159,9 +159,9 @@ fn test_trace_factorial() {
let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow();
let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver);
......@@ -182,9 +182,9 @@ fn test_trace_sum() {
let func_id = vm.id_of("sum");
let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow();
let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver);
......
......@@ -25,14 +25,14 @@ fn test_ir_liveness_fac() {
let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow();
let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver);
let cf_lock = vm.compiled_funcs().read().unwrap();
let cf = cf_lock.get(&func_ver.id()).unwrap().borrow();
let cf = cf_lock.get(&func_ver.id()).unwrap().read().unwrap();
// block 0
......@@ -74,9 +74,9 @@ fn test_regalloc_fac() {
let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow();
let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver);
}
mod test_thread;
\ No newline at end of file
extern crate mu;
extern crate log;
extern crate simple_logger;
use self::mu::ast::types::*;
use self::mu::ast::ir::*;
use self::mu::ast::inst::*;
use self::mu::ast::op::*;
use self::mu::vm::*;
use self::mu::compiler::*;
use self::mu::utils::Address;
use self::mu::runtime::ValueLocation;
use test_ir::test_ir::factorial;
use std::sync::Arc;
#[test]
fn test_thread_create() {
let vm = Arc::new(factorial());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver);
vm.make_primordial_thread(func_id, vec![Constant::Int(5)]);
backend::emit_context(&vm);
}
\ 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