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 ec6a6734 authored by qinsoon's avatar qinsoon
Browse files

COMMONINST get/set_threadlocal (untested)

parent b366ee5b
......@@ -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