GitLab will continue to be upgraded from 11.4.5-ce.0 on November 25th 2019 at 4.00pm (AEDT) to 5.00pm (AEDT) due to Critical Security Patch Availability. During the update, GitLab and Mattermost services will not be available.

Commit 36df60dc authored by qinsoon's avatar qinsoon

[wip] totally lost on what I am doing

parent f3670528
......@@ -20,3 +20,4 @@ linked-hash-map = "0.0.10"
hprof = "0.1.3"
memmap = "0.4.0"
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,10 +27,9 @@ impl_mu_entity!(MuStack);
pub struct MuStack {
pub hdr: MuEntityHeader,
func_addr: ValueLocation,
func_id: MuID,
state: MuStackState,
size: ByteSize,
// lo addr hi addr
// | overflow guard page | actual stack ..................... | underflow guard page|
......@@ -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 new_thread_normal(&self, stack: Box<MuStack>, threadlocal: Address, vals: Vec<RuntimeValue>) {
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});
}
#[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