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

Fixed kill_stack bug

parent 15e35778
Pipeline #932 failed with stages
in 3 minutes and 42 seconds
......@@ -1425,7 +1425,7 @@ impl<'a> InstructionSelection {
);
self.emit_runtime_entry(
&entrypoints::MUENTRY_THREAD_EXIT,
&entrypoints::THREAD_EXIT,
vec![tl.clone()],
None,
Some(node),
......@@ -1449,7 +1449,7 @@ impl<'a> InstructionSelection {
let (_, _, stack_arg_size) = compute_argument_locations(&sig.arg_tys, &SP, 0, &vm);
self.emit_runtime_entry(
&entrypoints::MUENTRY_NEW_STACK,
&entrypoints::NEW_STACK,
vec![tmp_func, make_value_int_const(stack_arg_size as u64, vm)],
Some(vec![tmp_res]),
Some(node),
......@@ -1457,6 +1457,18 @@ impl<'a> InstructionSelection {
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 => {
trace!("instsel on CURRENT_STACK");
......
......@@ -2084,7 +2084,6 @@ fn split_int128(
.unwrap()
.set_split(vec![arg_l.clone(), arg_h.clone()]);
trace!("ISAAC <- make temporary ({}, {})", &arg_l, &arg_h);
(arg_l, arg_h)
}
}
......@@ -2106,13 +2105,6 @@ pub fn emit_ireg_ex_value(
emit_mov_u64(backend, &tmp_l, val[0]);
emit_mov_u64(backend, &tmp_h, val[1]);
trace!(
"ISAAC <- ({}, {}) = ({}, {})",
&tmp_l,
&tmp_h,
val[0],
val[1]
);
(tmp_l, tmp_h)
}
_ => panic!("expected ireg_ex")
......
......@@ -57,7 +57,7 @@ lazy_static! {
// impl: runtime_asm_ARCH_OS.s
// decl: thread.rs
pub static ref MUENTRY_THREAD_EXIT : RuntimeEntrypoint = RuntimeEntrypoint {
pub static ref THREAD_EXIT : RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig{
hdr: MuEntityHeader::unnamed(ir::new_internal_id()),
ret_tys: vec![],
......@@ -70,7 +70,7 @@ lazy_static! {
}
lazy_static! {
// impl/decl: thread.rs
pub static ref MUENTRY_NEW_STACK: RuntimeEntrypoint = RuntimeEntrypoint {
pub static ref NEW_STACK: RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig{
hdr: MuEntityHeader::unnamed(ir::new_internal_id()),
ret_tys: vec![STACKREF_TYPE.clone()],
......@@ -80,6 +80,17 @@ lazy_static! {
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
pub static ref ALLOC_FAST : RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig {
......
......@@ -46,16 +46,14 @@ begin_func exception_restore
end_func exception_restore
# Swapstack internals
.macro stack_pass new_sp
MOV SP, \new_sp
.macro stack_pass
# On the new stack, reverse the above
pop_callee_saved
exit_frame
RET
.endm
.macro stack_throw new_sp
MOV SP, \new_sp
.macro stack_throw
# 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
......@@ -73,12 +71,10 @@ end_func exception_restore
STR X11, [\old_sp]
.endm
.macro stack_kill old_sp
.macro stack_kill old_stack
mov_args_to_callee_saved
push_pair X9, X10
MOV X0, \old_sp
MOV X0, \old_stack
BL muentry_kill_stack
pop_pair X10, X9
mov_callee_saved_to_args
.endm
......@@ -89,7 +85,8 @@ begin_func muthread_start_pass
stack_ret X1
MOV X9, X0 # X1 will be overriden by the next instructions
load_arguments X9
stack_pass X9
MOV SP, X9
stack_pass
end_func muthread_start_pass
......@@ -98,7 +95,8 @@ end_func muthread_start_pass
# X0 X1 X2
begin_func muthread_start_throw
stack_ret X2
stack_throw X1
MOV SP, X1
stack_throw
end_func muthread_start_throw
# restores the thread
......@@ -106,7 +104,8 @@ end_func muthread_start_throw
# X0
begin_func muentry_thread_exit
# Rust code will be responsible for actually killing the stack
stack_pass X0
MOV SP, X0
stack_pass
end_func muentry_thread_exit
# swap to the new stack whilst passing values and saving the old stack
......@@ -114,7 +113,8 @@ end_func muentry_thread_exit
# X0 ... X7 [x8] X9 X10
begin_func muentry_swapstack_ret_pass
stack_ret X10
stack_pass X9
MOV SP, X9
stack_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
......@@ -122,21 +122,24 @@ end_func muentry_swapstack_ret_pass
# X0 X1 X2
begin_func muentry_swapstack_ret_throw
stack_ret X2
stack_throw X1
MOV SP, X1
stack_throw
end_func muentry_swapstack_ret_throw
# 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)
# X0 ... X7 [x8] X9 X10
begin_func muentry_swapstack_kill_pass
MOV SP, X9
stack_kill X10
stack_pass X9
stack_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
# muentry_swapstack_kill_throw(exception: Address, new_sp: Address, old_stack: *mut MuStack)
# X0 X1 X2
begin_func muentry_swapstack_kill_throw
MOV SP, X1
stack_kill X2
stack_throw X1
stack_throw
end_func muentry_swapstack_kill_throw
......@@ -107,26 +107,6 @@ pub struct MuStack {
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 {
/// creates a new MuStack for given entry function and function address
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)
// Save the current stack, don't deallocate it
let cur_stack = Box::into_raw(cur_thread.stack.take().unwrap());
cur_thread.stack = Some(Box::from_raw(new_stack));
let new_sp = (*new_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)
((*new_stack).sp, &mut (*cur_stack).sp)
}
// 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)
// (i.e. when were are not on the current stack)
let cur_stack = Box::into_raw(cur_thread.stack.take().unwrap());
cur_thread.stack = Some(Box::from_raw(new_stack));
let new_sp = (*new_stack).sp;
trace!("ISAAC: muentry_prepare_swapstack_kill({}) -> ({}, {})", Address::from_ptr(new_stack), new_sp, Address::from_ptr(cur_stack));
(new_sp, cur_stack)
((*new_stack).sp, cur_stack)
}
#[no_mangle]
pub unsafe extern "C" fn muentry_new_stack(entry: Address, stack_size: usize) -> *mut MuStack {
let ref vm = MuThread::current_mut().vm;
let stack = Box::new(MuStack::new(vm.next_id(), entry, stack_size));
let a = Box::into_raw(stack);
trace!("ISAAC: muentry_new_stack({}, {}) -> {}", entry, stack_size, Address::from_mut_ptr(a));
a
Box::into_raw(stack)
}
// Kills the given stack. WARNING! do not call this whilst on the given stack
#[no_mangle]
pub unsafe extern "C" fn muentry_kill_stack(stack: *mut MuStack) {
// 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> {
hdr: hdr,
value: None,
ops: vec![impl_opnd],
v: Instruction_::NewStack(0)
v: Instruction_::KillStack(0)
}
}
CMU_CI_UVM_TR64_IS_FP => {
......
......@@ -1201,15 +1201,11 @@ impl<'a> VM {
let func_addr = resolve_symbol(self.name_of(func_id));
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(),
func_addr,
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
......
......@@ -145,3 +145,25 @@ def test_swapstack_throw_back():
}
""", "test_swapstack_throw_back");
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