Commit c24b8896 authored by Isaac Oscar Gariano's avatar Isaac Oscar Gariano

Fixed kill_stack bug

parent 15e35778
...@@ -1425,7 +1425,7 @@ impl<'a> InstructionSelection { ...@@ -1425,7 +1425,7 @@ impl<'a> InstructionSelection {
); );
self.emit_runtime_entry( self.emit_runtime_entry(
&entrypoints::MUENTRY_THREAD_EXIT, &entrypoints::THREAD_EXIT,
vec![tl.clone()], vec![tl.clone()],
None, None,
Some(node), Some(node),
...@@ -1449,7 +1449,7 @@ impl<'a> InstructionSelection { ...@@ -1449,7 +1449,7 @@ impl<'a> InstructionSelection {
let (_, _, stack_arg_size) = compute_argument_locations(&sig.arg_tys, &SP, 0, &vm); let (_, _, stack_arg_size) = compute_argument_locations(&sig.arg_tys, &SP, 0, &vm);
self.emit_runtime_entry( self.emit_runtime_entry(
&entrypoints::MUENTRY_NEW_STACK, &entrypoints::NEW_STACK,
vec![tmp_func, make_value_int_const(stack_arg_size as u64, vm)], vec![tmp_func, make_value_int_const(stack_arg_size as u64, vm)],
Some(vec![tmp_res]), Some(vec![tmp_res]),
Some(node), Some(node),
...@@ -1457,6 +1457,18 @@ impl<'a> InstructionSelection { ...@@ -1457,6 +1457,18 @@ impl<'a> InstructionSelection {
vm vm
); );
} }
Instruction_::KillStack(op) => {
trace!("instself on KILL_STACK");
let op = self.emit_ireg(&inst.ops[op], f_content, f_context, vm);
self.emit_runtime_entry(
&entrypoints::KILL_STACK,
vec![op],
None,
Some(node),
f_context,
vm
);
}
Instruction_::CurrentStack => { Instruction_::CurrentStack => {
trace!("instsel on CURRENT_STACK"); trace!("instsel on CURRENT_STACK");
......
...@@ -2084,7 +2084,6 @@ fn split_int128( ...@@ -2084,7 +2084,6 @@ fn split_int128(
.unwrap() .unwrap()
.set_split(vec![arg_l.clone(), arg_h.clone()]); .set_split(vec![arg_l.clone(), arg_h.clone()]);
trace!("ISAAC <- make temporary ({}, {})", &arg_l, &arg_h);
(arg_l, arg_h) (arg_l, arg_h)
} }
} }
...@@ -2106,13 +2105,6 @@ pub fn emit_ireg_ex_value( ...@@ -2106,13 +2105,6 @@ pub fn emit_ireg_ex_value(
emit_mov_u64(backend, &tmp_l, val[0]); emit_mov_u64(backend, &tmp_l, val[0]);
emit_mov_u64(backend, &tmp_h, val[1]); emit_mov_u64(backend, &tmp_h, val[1]);
trace!(
"ISAAC <- ({}, {}) = ({}, {})",
&tmp_l,
&tmp_h,
val[0],
val[1]
);
(tmp_l, tmp_h) (tmp_l, tmp_h)
} }
_ => panic!("expected ireg_ex") _ => panic!("expected ireg_ex")
......
...@@ -57,7 +57,7 @@ lazy_static! { ...@@ -57,7 +57,7 @@ lazy_static! {
// impl: runtime_asm_ARCH_OS.s // impl: runtime_asm_ARCH_OS.s
// decl: thread.rs // decl: thread.rs
pub static ref MUENTRY_THREAD_EXIT : RuntimeEntrypoint = RuntimeEntrypoint { pub static ref THREAD_EXIT : RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig{ sig: P(MuFuncSig{
hdr: MuEntityHeader::unnamed(ir::new_internal_id()), hdr: MuEntityHeader::unnamed(ir::new_internal_id()),
ret_tys: vec![], ret_tys: vec![],
...@@ -70,7 +70,7 @@ lazy_static! { ...@@ -70,7 +70,7 @@ lazy_static! {
} }
lazy_static! { lazy_static! {
// impl/decl: thread.rs // impl/decl: thread.rs
pub static ref MUENTRY_NEW_STACK: RuntimeEntrypoint = RuntimeEntrypoint { pub static ref NEW_STACK: RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig{ sig: P(MuFuncSig{
hdr: MuEntityHeader::unnamed(ir::new_internal_id()), hdr: MuEntityHeader::unnamed(ir::new_internal_id()),
ret_tys: vec![STACKREF_TYPE.clone()], ret_tys: vec![STACKREF_TYPE.clone()],
...@@ -80,6 +80,17 @@ lazy_static! { ...@@ -80,6 +80,17 @@ lazy_static! {
jit: RwLock::new(None), jit: RwLock::new(None),
}; };
// impl/decl: thread.rs
pub static ref KILL_STACK: RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig{
hdr: MuEntityHeader::unnamed(ir::new_internal_id()),
ret_tys: vec![],
arg_tys: vec![STACKREF_TYPE.clone()]
}),
aot: ValueLocation::Relocatable(RegGroup::GPR, String::from("muentry_kill_stack")),
jit: RwLock::new(None),
};
// impl/decl: gc/lib.rs // impl/decl: gc/lib.rs
pub static ref ALLOC_FAST : RuntimeEntrypoint = RuntimeEntrypoint { pub static ref ALLOC_FAST : RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig { sig: P(MuFuncSig {
......
...@@ -46,16 +46,14 @@ begin_func exception_restore ...@@ -46,16 +46,14 @@ begin_func exception_restore
end_func exception_restore end_func exception_restore
# Swapstack internals # Swapstack internals
.macro stack_pass new_sp .macro stack_pass
MOV SP, \new_sp
# On the new stack, reverse the above # On the new stack, reverse the above
pop_callee_saved pop_callee_saved
exit_frame exit_frame
RET RET
.endm .endm
.macro stack_throw new_sp .macro stack_throw
MOV SP, \new_sp
# The new stack will have the same layout as the stack when muentry_throw_exception # The new stack will have the same layout as the stack when muentry_throw_exception
# calls throw_exception_internal, so we can do that directly here # calls throw_exception_internal, so we can do that directly here
...@@ -73,12 +71,10 @@ end_func exception_restore ...@@ -73,12 +71,10 @@ end_func exception_restore
STR X11, [\old_sp] STR X11, [\old_sp]
.endm .endm
.macro stack_kill old_sp .macro stack_kill old_stack
mov_args_to_callee_saved mov_args_to_callee_saved
push_pair X9, X10 MOV X0, \old_stack
MOV X0, \old_sp
BL muentry_kill_stack BL muentry_kill_stack
pop_pair X10, X9
mov_callee_saved_to_args mov_callee_saved_to_args
.endm .endm
...@@ -89,7 +85,8 @@ begin_func muthread_start_pass ...@@ -89,7 +85,8 @@ begin_func muthread_start_pass
stack_ret X1 stack_ret X1
MOV X9, X0 # X1 will be overriden by the next instructions MOV X9, X0 # X1 will be overriden by the next instructions
load_arguments X9 load_arguments X9
stack_pass X9 MOV SP, X9
stack_pass
end_func muthread_start_pass end_func muthread_start_pass
...@@ -98,7 +95,8 @@ end_func muthread_start_pass ...@@ -98,7 +95,8 @@ end_func muthread_start_pass
# X0 X1 X2 # X0 X1 X2
begin_func muthread_start_throw begin_func muthread_start_throw
stack_ret X2 stack_ret X2
stack_throw X1 MOV SP, X1
stack_throw
end_func muthread_start_throw end_func muthread_start_throw
# restores the thread # restores the thread
...@@ -106,7 +104,8 @@ end_func muthread_start_throw ...@@ -106,7 +104,8 @@ end_func muthread_start_throw
# X0 # X0
begin_func muentry_thread_exit begin_func muentry_thread_exit
# Rust code will be responsible for actually killing the stack # Rust code will be responsible for actually killing the stack
stack_pass X0 MOV SP, X0
stack_pass
end_func muentry_thread_exit end_func muentry_thread_exit
# swap to the new stack whilst passing values and saving the old stack # swap to the new stack whilst passing values and saving the old stack
...@@ -114,7 +113,8 @@ end_func muentry_thread_exit ...@@ -114,7 +113,8 @@ end_func muentry_thread_exit
# X0 ... X7 [x8] X9 X10 # X0 ... X7 [x8] X9 X10
begin_func muentry_swapstack_ret_pass begin_func muentry_swapstack_ret_pass
stack_ret X10 stack_ret X10
stack_pass X9 MOV SP, X9
stack_pass
end_func muentry_swapstack_ret_pass end_func muentry_swapstack_ret_pass
# Same as swapstack_ret_pass except will throw an exception to the new stack instead of passing values # Same as swapstack_ret_pass except will throw an exception to the new stack instead of passing values
...@@ -122,21 +122,24 @@ end_func muentry_swapstack_ret_pass ...@@ -122,21 +122,24 @@ end_func muentry_swapstack_ret_pass
# X0 X1 X2 # X0 X1 X2
begin_func muentry_swapstack_ret_throw begin_func muentry_swapstack_ret_throw
stack_ret X2 stack_ret X2
stack_throw X1 MOV SP, X1
stack_throw
end_func muentry_swapstack_ret_throw end_func muentry_swapstack_ret_throw
# swap to the new stack whilst passing values and killing the old stack # swap to the new stack whilst passing values and killing the old stack
# muentry_swapstack_kill_pass(new_stack args..., new_sp: Address, old_stack: *mut MuStack) # muentry_swapstack_kill_pass(new_stack args..., new_sp: Address, old_stack: *mut MuStack)
# X0 ... X7 [x8] X9 X10 # X0 ... X7 [x8] X9 X10
begin_func muentry_swapstack_kill_pass begin_func muentry_swapstack_kill_pass
MOV SP, X9
stack_kill X10 stack_kill X10
stack_pass X9 stack_pass
end_func muentry_swapstack_kill_pass end_func muentry_swapstack_kill_pass
# Same as muentry_swapstack_kill_pass except will throw an exception to the new stack instead of passing values # Same as muentry_swapstack_kill_pass except will throw an exception to the new stack instead of passing values
# muentry_swapstack_kill_throw(exception: Address, new_sp: Address, old_stack: *mut MuStack) # muentry_swapstack_kill_throw(exception: Address, new_sp: Address, old_stack: *mut MuStack)
# X0 X1 X2 # X0 X1 X2
begin_func muentry_swapstack_kill_throw begin_func muentry_swapstack_kill_throw
MOV SP, X1
stack_kill X2 stack_kill X2
stack_throw X1 stack_throw
end_func muentry_swapstack_kill_throw end_func muentry_swapstack_kill_throw
...@@ -107,26 +107,6 @@ pub struct MuStack { ...@@ -107,26 +107,6 @@ pub struct MuStack {
mmap: Option<memmap::Mmap> mmap: Option<memmap::Mmap>
} }
impl Drop for MuStack
{
fn drop(&mut self) {
// Reverse memory protection so that dropping will work...
//trace!("dropping MuStack {}", Address::from_ref(self));
unsafe {
memsec::mprotect(
self.overflow_guard.to_ptr_mut::<u8>(),
PAGE_SIZE,
memsec::Prot::ReadWriteExec
);
memsec::mprotect(
self.underflow_guard.to_ptr_mut::<u8>(),
PAGE_SIZE,
memsec::Prot::ReadWriteExec
);
}
}
}
impl MuStack { impl MuStack {
/// creates a new MuStack for given entry function and function address /// creates a new MuStack for given entry function and function address
pub fn new(id: MuID, func_addr: Address, stack_arg_size: usize) -> MuStack { pub fn new(id: MuID, func_addr: Address, stack_arg_size: usize) -> MuStack {
...@@ -673,10 +653,7 @@ pub unsafe extern "C" fn muentry_prepare_swapstack_ret(new_stack: *mut MuStack) ...@@ -673,10 +653,7 @@ pub unsafe extern "C" fn muentry_prepare_swapstack_ret(new_stack: *mut MuStack)
// Save the current stack, don't deallocate it // Save the current stack, don't deallocate it
let cur_stack = Box::into_raw(cur_thread.stack.take().unwrap()); let cur_stack = Box::into_raw(cur_thread.stack.take().unwrap());
cur_thread.stack = Some(Box::from_raw(new_stack)); cur_thread.stack = Some(Box::from_raw(new_stack));
let new_sp = (*new_stack).sp; ((*new_stack).sp, &mut (*cur_stack).sp)
let old_sp_loc =&mut (*cur_stack).sp;
trace!("ISAAC: muentry_prepare_swapstack_ret({}) -> ({}, {})", Address::from_ptr(new_stack), new_sp, Address::from_ref(old_sp_loc));
(new_sp, old_sp_loc)
} }
// This prepares a thread for a swap stack operation that kills the current stack // This prepares a thread for a swap stack operation that kills the current stack
...@@ -691,24 +668,19 @@ pub unsafe extern "C" fn muentry_prepare_swapstack_kill(new_stack: *mut MuStack) ...@@ -691,24 +668,19 @@ pub unsafe extern "C" fn muentry_prepare_swapstack_kill(new_stack: *mut MuStack)
// (i.e. when were are not on the current stack) // (i.e. when were are not on the current stack)
let cur_stack = Box::into_raw(cur_thread.stack.take().unwrap()); let cur_stack = Box::into_raw(cur_thread.stack.take().unwrap());
cur_thread.stack = Some(Box::from_raw(new_stack)); cur_thread.stack = Some(Box::from_raw(new_stack));
let new_sp = (*new_stack).sp; ((*new_stack).sp, cur_stack)
trace!("ISAAC: muentry_prepare_swapstack_kill({}) -> ({}, {})", Address::from_ptr(new_stack), new_sp, Address::from_ptr(cur_stack));
(new_sp, cur_stack)
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn muentry_new_stack(entry: Address, stack_size: usize) -> *mut MuStack { pub unsafe extern "C" fn muentry_new_stack(entry: Address, stack_size: usize) -> *mut MuStack {
let ref vm = MuThread::current_mut().vm; let ref vm = MuThread::current_mut().vm;
let stack = Box::new(MuStack::new(vm.next_id(), entry, stack_size)); let stack = Box::new(MuStack::new(vm.next_id(), entry, stack_size));
let a = Box::into_raw(stack); Box::into_raw(stack)
trace!("ISAAC: muentry_new_stack({}, {}) -> {}", entry, stack_size, Address::from_mut_ptr(a));
a
} }
// Kills the given stack. WARNING! do not call this whilst on the given stack // Kills the given stack. WARNING! do not call this whilst on the given stack
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn muentry_kill_stack(stack: *mut MuStack) { pub unsafe extern "C" fn muentry_kill_stack(stack: *mut MuStack) {
// This new box will be destroyed upon returning // This new box will be destroyed upon returning
trace!("ISAAC: muentry_kill_stack({})", Address::from_mut_ptr(stack)); Box::from_raw(stack);
//Box::from_raw(stack);
} }
...@@ -3897,7 +3897,7 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> { ...@@ -3897,7 +3897,7 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
hdr: hdr, hdr: hdr,
value: None, value: None,
ops: vec![impl_opnd], ops: vec![impl_opnd],
v: Instruction_::NewStack(0) v: Instruction_::KillStack(0)
} }
} }
CMU_CI_UVM_TR64_IS_FP => { CMU_CI_UVM_TR64_IS_FP => {
......
...@@ -1201,15 +1201,11 @@ impl<'a> VM { ...@@ -1201,15 +1201,11 @@ impl<'a> VM {
let func_addr = resolve_symbol(self.name_of(func_id)); let func_addr = resolve_symbol(self.name_of(func_id));
let stack_arg_size = backend::call_stack_size(func.sig.clone(), self); let stack_arg_size = backend::call_stack_size(func.sig.clone(), self);
let b = Box::new(MuStack::new( Box::new(MuStack::new(
self.next_id(), self.next_id(),
func_addr, func_addr,
stack_arg_size stack_arg_size
)); ))
let a: Address = unsafe{*(std::mem::transmute::<&Box<MuStack>, &Address>(&b))};
trace!("ISAAC: vm.new_stack({}) -> {}", func_addr, a);
b
} }
/// creates a handle that we can return to the client /// creates a handle that we can return to the client
......
...@@ -145,3 +145,25 @@ def test_swapstack_throw_back(): ...@@ -145,3 +145,25 @@ def test_swapstack_throw_back():
} }
""", "test_swapstack_throw_back"); """, "test_swapstack_throw_back");
assert(execute("test_swapstack_throw_back", []) == 3); assert(execute("test_swapstack_throw_back", []) == 3);
def test_kill_stack():
compile_bundle(
"""
.funcdef new_func <(stackref)->()>
{
entry(<stackref>s):
COMMINST uvm.kill_stack(s)
CCALL #DEFAULT <exit_type exit_sig> exit(<int<32>>3)
RET
}
.funcdef test_kill_stack <main_sig>
{
entry(<int<32>>argc <uptr<uptr<char>>>argv):
cs = COMMINST uvm.current_stack()
s = COMMINST uvm.new_stack<[(stackref)->()]>(new_func)
SWAPSTACK s RET_WITH<> PASS_VALUES<stackref>(cs)
RET <int<32>>0
}
""", "test_kill_stack");
assert(execute("test_kill_stack", []) == 3);
\ 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