GitLab will be partched to the latest stable version on 15 July 2020 at 2.00pm (AEDT) to 2.30pm (AEDT) due to Security Patch Availability. During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to us at N110 (b) CSIT building.

Commit ed3728df authored by John Zhang's avatar John Zhang

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

parents 884761cd ec6a6734
......@@ -10,3 +10,4 @@ Cargo.lock
.idea
*.pyc
*.o
mu-client-pypy
#!/bin/bash
echo "Note: this script is only for the convenience of running tests in our lab. "
lowercase(){
echo "$1" | sed "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/"
}
# detect OS
OS=`lowercase \`uname\``
KERNEL=`uname -r`
MACH=`uname -m`
if [ "{$OS}" == "windowsnt" ]; then
OS=windows
elif [ "{$OS}" == "darwin" ]; then
OS=mac
else
OS=`uname`
if [ "${OS}" = "SunOS" ] ; then
OS=Solaris
ARCH=`uname -p`
OSSTR="${OS} ${REV}(${ARCH} `uname -v`)"
elif [ "${OS}" = "AIX" ] ; then
OSSTR="${OS} `oslevel` (`oslevel -r`)"
elif [ "${OS}" = "Linux" ] ; then
if [ -f /etc/redhat-release ] ; then
DistroBasedOn='RedHat'
DIST=`cat /etc/redhat-release |sed s/\ release.*//`
PSUEDONAME=`cat /etc/redhat-release | sed s/.*\(// | sed s/\)//`
REV=`cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*//`
elif [ -f /etc/SuSE-release ] ; then
DistroBasedOn='SuSe'
PSUEDONAME=`cat /etc/SuSE-release | tr "\n" ' '| sed s/VERSION.*//`
REV=`cat /etc/SuSE-release | tr "\n" ' ' | sed s/.*=\ //`
elif [ -f /etc/mandrake-release ] ; then
DistroBasedOn='Mandrake'
PSUEDONAME=`cat /etc/mandrake-release | sed s/.*\(// | sed s/\)//`
REV=`cat /etc/mandrake-release | sed s/.*release\ // | sed s/\ .*//`
elif [ -f /etc/debian_version ] ; then
DistroBasedOn='Debian'
DIST=`cat /etc/lsb-release | grep '^DISTRIB_ID' | awk -F= '{ print $2 }'`
PSUEDONAME=`cat /etc/lsb-release | grep '^DISTRIB_CODENAME' | awk -F= '{ print $2 }'`
REV=`cat /etc/lsb-release | grep '^DISTRIB_RELEASE' | awk -F= '{ print $2 }'`
fi
if [ -f /etc/UnitedLinux-release ] ; then
DIST="${DIST}[`cat /etc/UnitedLinux-release | tr "\n" ' ' | sed s/VERSION.*//`]"
fi
OS=`lowercase $OS`
DistroBasedOn=`lowercase $DistroBasedOn`
readonly OS
readonly DIST
readonly DistroBasedOn
readonly PSUEDONAME
readonly REV
readonly KERNEL
readonly MACH
fi
fi
echo "---------"
echo "OS: $OS"
echo "KERNEL: $KERNEL"
echo "ARCH: $MACH"
echo "---------"
echo "building zebu..."
rm -rf emit/*
if [ "$OS" == "linux" ]; then
RUSTFLAGS=-Zincremental=target/incr-cache RUST_BACKTRACE=1 CC=clang-3.8 cargo build
elif [ "$OS" == "Darwin" ]; then
RUSTFLAGS=-Zincremental=target/incr-cache RUST_BACKTRACE=1 cargo build
else
echo "unknown OS. do not use this script to run"
exit
fi
echo ""
echo "fetching rpython..."
git clone https://gitlab.anu.edu.au/mu/mu-client-pypy.git mu-client-pypy
echo ""
echo "compiling rpython..."
# save current path
project_path=$(pwd)
cd mu-client-pypy
git checkout test-mu-impl-jit
cd rpython/translator/mu/rpyc; make
cd $project_path/tests/test_jit
if [ "$OS" == "linux" ]; then
if [ $# -eq 0 ]; then
RUST_BACKTRACE=1 PYTHONPATH=$project_path/mu-client-pypy MU_RUST=$project_path CC=clang-3.8 python -m pytest . -v
else
RUST_BACKTRACE=1 PYTHONPATH=$project_path/mu-client-pypy MU_RUST=$project_path CC=clang-3.8 python -m pytest . -v -k $@
fi
elif [ "$OS" == "Darwin" ]; then
if [ $# -eq 0 ]; then
RUST_BACKTRACE=1 PYTHONPATH=$project_path/mu-client-pypy MU_RUST=$project_path CC=clang python2 -m pytest . -v
else
RUST_BACKTRACE=1 PYTHONPATH=$project_path/mu-client-pypy MU_RUST=$project_path CC=clang python2 -m pytest . -v -k $@
fi
else
echo "unknown OS. do not use this script to run"
exit
fi
\ No newline at end of file
......@@ -262,7 +262,11 @@ pub enum Instruction_ {
ExnInstruction{
inner: Box<Instruction>,
resume: ResumptionData
}
},
// common inst
CommonInst_GetThreadLocal,
CommonInst_SetThreadLocal(OpIndex)
}
impl Instruction_ {
......@@ -374,7 +378,9 @@ impl Instruction_ {
},
&Instruction_::ExnInstruction{ref inner, ref resume} => {
format!("{} {}", inner.debug_str(ops), resume.debug_str(ops))
}
},
&Instruction_::CommonInst_GetThreadLocal => format!("COMMONINST GetThreadLocal"),
&Instruction_::CommonInst_SetThreadLocal(op) => format!("COMMONINST SetThreadLocal {}", ops[op])
}
}
}
......
......@@ -26,7 +26,9 @@ pub fn is_terminal_inst(inst: &Instruction_) -> bool {
| &ShiftIRef{..}
| &GetVarPartIRef{..}
| &Select{..}
| &Fence(_) => false,
| &Fence(_)
| &CommonInst_GetThreadLocal
| &CommonInst_SetThreadLocal(_) => false,
&Return(_)
| &ThreadExit
| &Throw(_)
......@@ -86,6 +88,8 @@ pub fn has_side_effect(inst: &Instruction_) -> bool {
&CCall{..} => true,
&SwapStack{..} => true,
&Switch{..} => true,
&ExnInstruction{..} => true
&ExnInstruction{..} => true,
&CommonInst_GetThreadLocal => true,
&CommonInst_SetThreadLocal(_) => true,
}
}
......@@ -56,7 +56,10 @@ pub enum OpCode {
GetFieldIRef,
GetElementIRef,
ShiftIRef,
GetVarPartIRef
GetVarPartIRef,
CommonInst_GetThreadLocal,
CommonInst_SetThreadLocal
}
pub fn pick_op_code_for_ssa(ty: &P<MuType>) -> OpCode {
......@@ -244,42 +247,44 @@ pub fn is_int_cmp(op: CmpOp) -> bool {
pub fn pick_op_code_for_inst(inst: &Instruction) -> OpCode {
match inst.v {
Instruction_::BinOp(op, _, _) => OpCode::Binary(op),
Instruction_::CmpOp(op, _, _) => OpCode::Comparison(op),
Instruction_::ConvOp{operation, ..} => OpCode::Conversion(operation),
Instruction_::AtomicRMW{op, ..} => OpCode::AtomicRMW(op),
Instruction_::ExprCall{..} => OpCode::ExprCall,
Instruction_::ExprCCall{..} => OpCode::ExprCCall,
Instruction_::Load{..} => OpCode::Load,
Instruction_::Store{..} => OpCode::Store,
Instruction_::CmpXchg{..} => OpCode::CmpXchg,
Instruction_::New(_) => OpCode::New,
Instruction_::AllocA(_) => OpCode::AllocA,
Instruction_::NewHybrid(_, _) => OpCode::NewHybrid,
Instruction_::AllocAHybrid(_, _) => OpCode::AllocAHybrid,
Instruction_::NewStack(_) => OpCode::NewStack,
Instruction_::NewThread(_, _) => OpCode::NewThread,
Instruction_::NewThreadExn(_, _) => OpCode::NewThreadExn,
Instruction_::NewFrameCursor(_) => OpCode::NewFrameCursor,
Instruction_::GetIRef(_) => OpCode::GetIRef,
Instruction_::GetFieldIRef{..} => OpCode::GetFieldIRef,
Instruction_::GetElementIRef{..} => OpCode::GetElementIRef,
Instruction_::ShiftIRef{..} => OpCode::ShiftIRef,
Instruction_::GetVarPartIRef{..} => OpCode::GetVarPartIRef,
Instruction_::Fence(_) => OpCode::Fence,
Instruction_::Return(_) => OpCode::Return,
Instruction_::ThreadExit => OpCode::ThreadExit,
Instruction_::Throw(_) => OpCode::Throw,
Instruction_::TailCall(_) => OpCode::TailCall,
Instruction_::Branch1(_) => OpCode::Branch1,
Instruction_::Branch2{..} => OpCode::Branch2,
Instruction_::Select{..} => OpCode::Select,
Instruction_::Watchpoint{..} => OpCode::Watchpoint,
Instruction_::WPBranch{..} => OpCode::WPBranch,
Instruction_::Call{..} => OpCode::Call,
Instruction_::CCall{..} => OpCode::CCall,
Instruction_::SwapStack{..} => OpCode::SwapStack,
Instruction_::Switch{..} => OpCode::Switch,
Instruction_::ExnInstruction{..} => OpCode::ExnInstruction
Instruction_::BinOp(op, _, _) => OpCode::Binary(op),
Instruction_::CmpOp(op, _, _) => OpCode::Comparison(op),
Instruction_::ConvOp{operation, ..} => OpCode::Conversion(operation),
Instruction_::AtomicRMW{op, ..} => OpCode::AtomicRMW(op),
Instruction_::ExprCall{..} => OpCode::ExprCall,
Instruction_::ExprCCall{..} => OpCode::ExprCCall,
Instruction_::Load{..} => OpCode::Load,
Instruction_::Store{..} => OpCode::Store,
Instruction_::CmpXchg{..} => OpCode::CmpXchg,
Instruction_::New(_) => OpCode::New,
Instruction_::AllocA(_) => OpCode::AllocA,
Instruction_::NewHybrid(_, _) => OpCode::NewHybrid,
Instruction_::AllocAHybrid(_, _) => OpCode::AllocAHybrid,
Instruction_::NewStack(_) => OpCode::NewStack,
Instruction_::NewThread(_, _) => OpCode::NewThread,
Instruction_::NewThreadExn(_, _) => OpCode::NewThreadExn,
Instruction_::NewFrameCursor(_) => OpCode::NewFrameCursor,
Instruction_::GetIRef(_) => OpCode::GetIRef,
Instruction_::GetFieldIRef{..} => OpCode::GetFieldIRef,
Instruction_::GetElementIRef{..} => OpCode::GetElementIRef,
Instruction_::ShiftIRef{..} => OpCode::ShiftIRef,
Instruction_::GetVarPartIRef{..} => OpCode::GetVarPartIRef,
Instruction_::Fence(_) => OpCode::Fence,
Instruction_::Return(_) => OpCode::Return,
Instruction_::ThreadExit => OpCode::ThreadExit,
Instruction_::Throw(_) => OpCode::Throw,
Instruction_::TailCall(_) => OpCode::TailCall,
Instruction_::Branch1(_) => OpCode::Branch1,
Instruction_::Branch2{..} => OpCode::Branch2,
Instruction_::Select{..} => OpCode::Select,
Instruction_::Watchpoint{..} => OpCode::Watchpoint,
Instruction_::WPBranch{..} => OpCode::WPBranch,
Instruction_::Call{..} => OpCode::Call,
Instruction_::CCall{..} => OpCode::CCall,
Instruction_::SwapStack{..} => OpCode::SwapStack,
Instruction_::Switch{..} => OpCode::Switch,
Instruction_::ExnInstruction{..} => OpCode::ExnInstruction,
Instruction_::CommonInst_GetThreadLocal => OpCode::CommonInst_GetThreadLocal,
Instruction_::CommonInst_SetThreadLocal(_) => OpCode::CommonInst_SetThreadLocal
}
}
......@@ -1031,6 +1031,30 @@ impl <'a> InstructionSelection {
self.emit_runtime_entry(&entrypoints::SWAP_BACK_TO_NATIVE_STACK, vec![tl.clone()], None, Some(node), f_content, f_context, vm);
}
Instruction_::CommonInst_GetThreadLocal => {
// get thread local
let tl = self.emit_get_threadlocal(Some(node), f_content, f_context, vm);
let tmp_res = self.get_result_value(node);
// load [tl + USER_TLS_OFFSET] -> tmp_res
self.emit_load_base_offset(&tmp_res, &tl, *thread::USER_TLS_OFFSET as i32, vm);
}
Instruction_::CommonInst_SetThreadLocal(op) => {
let ops = inst.ops.read().unwrap();
let ref op = ops[op];
debug_assert!(self.match_ireg(op));
let tmp_op = self.emit_ireg(op, f_content, f_context, vm);
// get thread local
let tl = self.emit_get_threadlocal(Some(node), f_content, f_context, vm);
// store tmp_op -> [tl + USER_TLS_OFFSTE]
self.emit_store_base_offset(&tl, *thread::USER_TLS_OFFSET as i32, &tmp_op, vm);
}
Instruction_::New(ref ty) => {
if cfg!(debug_assertions) {
......
......@@ -204,7 +204,7 @@ pub struct MuThread {
pub stack: Option<Box<MuStack>>,
native_sp_loc: Address,
user_tls: Option<Address>,
user_tls: Address, // can be zero
pub vm: Arc<VM>,
pub exception_obj: Address
......@@ -212,17 +212,15 @@ pub struct MuThread {
// this depends on the layout of MuThread
lazy_static! {
pub static ref NATIVE_SP_LOC_OFFSET : usize = mem::size_of::<MuEntityHeader>()
pub static ref ALLOCATOR_OFFSET : usize = mem::size_of::<MuEntityHeader>();
pub static ref NATIVE_SP_LOC_OFFSET : usize = *ALLOCATOR_OFFSET
+ mem::size_of::<Box<mm::Mutator>>()
+ mem::size_of::<Option<Box<MuStack>>>();
pub static ref USER_TLS_OFFSET : usize = *NATIVE_SP_LOC_OFFSET + mem::size_of::<Address>();
pub static ref ALLOCATOR_OFFSET : usize = mem::size_of::<MuEntityHeader>();
pub static ref VM_OFFSET : usize = mem::size_of::<MuEntityHeader>()
+ mem::size_of::<Box<mm::Mutator>>()
+ mem::size_of::<Option<Box<MuStack>>>()
+ mem::size_of::<Address>()
+ mem::size_of::<Option<Address>>();
pub static ref VM_OFFSET : usize = *USER_TLS_OFFSET + mem::size_of::<Address>();
pub static ref EXCEPTION_OBJ_OFFSET : usize = *VM_OFFSET + mem::size_of::<Arc<VM>>();
}
......@@ -247,7 +245,7 @@ extern "C" {
}
impl MuThread {
pub fn new(id: MuID, allocator: mm::Mutator, stack: Box<MuStack>, user_tls: Option<Address>, vm: Arc<VM>) -> MuThread {
pub fn new(id: MuID, allocator: mm::Mutator, stack: Box<MuStack>, user_tls: Address, vm: Arc<VM>) -> MuThread {
MuThread {
hdr: MuEntityHeader::unnamed(id),
allocator: allocator,
......@@ -279,14 +277,6 @@ impl MuThread {
pub unsafe fn current_thread_as_mu_thread(threadlocal: Address, vm: Arc<VM>) {
use std::usize;
let user_tls = {
if threadlocal.is_zero() {
None
} else {
Some(threadlocal)
}
};
// fake a stack for current thread
let fake_mu_stack_for_cur = Box::new(MuStack {
hdr: MuEntityHeader::unnamed(vm.next_id()),
......@@ -321,7 +311,7 @@ impl MuThread {
// we do not need native_sp_loc (we do not expect the thread to call
native_sp_loc: unsafe {Address::zero()},
user_tls: user_tls,
user_tls: threadlocal,
vm: vm,
exception_obj: unsafe {Address::zero()}
......@@ -343,23 +333,15 @@ impl MuThread {
}
pub fn new_thread_normal(mut stack: Box<MuStack>, threadlocal: Address, vals: Vec<ValueLocation>, vm: Arc<VM>) -> JoinHandle<()> {
let user_tls = {
if threadlocal.is_zero() {
None
} else {
Some(threadlocal)
}
};
// set up arguments on stack
stack.runtime_load_args(vals);
MuThread::mu_thread_launch(vm.next_id(), stack, user_tls, vm)
MuThread::mu_thread_launch(vm.next_id(), stack, threadlocal, vm)
}
#[no_mangle]
#[allow(unused_variables)]
pub extern fn mu_thread_launch(id: MuID, stack: Box<MuStack>, user_tls: Option<Address>, vm: Arc<VM>) -> JoinHandle<()> {
pub extern fn mu_thread_launch(id: MuID, stack: Box<MuStack>, user_tls: Address, vm: Arc<VM>) -> JoinHandle<()> {
let new_sp = stack.sp;
let entry = runtime::resolve_symbol(vm.name_of(stack.func.as_ref().unwrap().1));
debug!("entry : 0x{:x}", entry);
......
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