rt: Reorganize stack growth code

This commit is contained in:
Brian Anderson 2011-11-30 17:54:11 -08:00
parent dd48a1af58
commit f2de42c39a
7 changed files with 75 additions and 72 deletions

View file

@ -6,14 +6,14 @@
// prolog when we run out.
#if defined(__APPLE__) || defined(_WIN32)
#define RUST_NEW_STACK2 _rust_new_stack2
#define RUST_DEL_STACK _rust_del_stack
#define UPCALL_NEW_STACK _upcall_new_stack
#define UPCALL_DEL_STACK _upcall_del_stack
#define RUST_GET_TASK _rust_get_task
#define UPCALL_CALL_C _upcall_call_shim_on_c_stack
#define MORESTACK ___morestack
#else
#define RUST_NEW_STACK2 rust_new_stack2
#define RUST_DEL_STACK rust_del_stack
#define UPCALL_NEW_STACK upcall_new_stack
#define UPCALL_DEL_STACK upcall_del_stack
#define RUST_GET_TASK rust_get_task
#define UPCALL_CALL_C upcall_call_shim_on_c_stack
#define MORESTACK __morestack
@ -22,11 +22,9 @@
#define ALIGNMENT 8
#define RETURN_OFFSET 7
.globl RUST_NEW_STACK
.globl RUST_DEL_STACK
.globl RUST_GET_PREV_STACK
.globl UPCALL_NEW_STACK
.globl UPCALL_DEL_STACK
.globl RUST_GET_TASK
.globl UPCALL_ALLOC_C_STACK
.globl UPCALL_CALL_C_STACK
.globl MORESTACK
@ -64,7 +62,7 @@ MORESTACK:
movl 32(%esp),%eax // The amount of stack needed
movl %eax,8(%esp)
movl $RUST_NEW_STACK2,4(%esp)
movl $UPCALL_NEW_STACK,4(%esp)
leal 8(%esp), %eax
movl %eax,(%esp)
call UPCALL_CALL_C
@ -81,7 +79,7 @@ MORESTACK:
// Switch back to the rust stack
movl %ebp, %esp
pushl $RUST_DEL_STACK
pushl $UPCALL_DEL_STACK
pushl $0
call UPCALL_CALL_C

View file

@ -6,15 +6,15 @@
// prolog when we run out.
#if defined(__APPLE__) || defined(_WIN32)
#define RUST_NEW_STACK2 _rust_new_stack2
#define RUST_DEL_STACK _rust_del_stack
#define UPCALL_CALL_C _upcall_call_shim_on_c_stack
#define MORESTACK ___morestack
#define UPCALL_NEW_STACK _upcall_new_stack
#define UPCALL_DEL_STACK _upcall_del_stack
#define UPCALL_CALL_C _upcall_call_shim_on_c_stack
#define MORESTACK ___morestack
#else
#define RUST_NEW_STACK2 rust_new_stack2
#define RUST_DEL_STACK rust_del_stack
#define UPCALL_CALL_C upcall_call_shim_on_c_stack
#define MORESTACK __morestack
#define UPCALL_NEW_STACK upcall_new_stack
#define UPCALL_DEL_STACK upcall_del_stack
#define UPCALL_CALL_C upcall_call_shim_on_c_stack
#define MORESTACK __morestack
#endif
// Naturally, nobody can agree as to
@ -30,8 +30,8 @@
# define ARG2 %rdx
#endif
.globl RUST_NEW_STACK2
.globl RUST_DEL_STACK
.globl UPCALL_NEW_STACK
.globl UPCALL_DEL_STACK
.globl UPCALL_CALL_C
.globl MORESTACK
@ -79,7 +79,7 @@ MORESTACK:
pushq %rcx // Address of stack arguments
pushq %r10 // The amount of stack needed
leaq RUST_NEW_STACK2@PLT(%rip), %rsi
leaq UPCALL_NEW_STACK@PLT(%rip), %rsi
movq %rsp, %rdi
call UPCALL_CALL_C@PLT
@ -106,7 +106,7 @@ MORESTACK:
// Align the stack again
pushq $0
leaq RUST_DEL_STACK@PLT(%rip), %rsi
leaq UPCALL_DEL_STACK@PLT(%rip), %rsi
movq $0, %rdi
call UPCALL_CALL_C@PLT

View file

@ -399,6 +399,11 @@ get_task_pointer(rust_task_id id) {
return task->kernel->get_task_by_id(id);
}
extern "C" rust_task *
rust_get_task() {
return rust_scheduler::get_task();
}
struct fn_env_pair {
intptr_t f;
intptr_t env;

View file

@ -62,54 +62,6 @@ del_stk(rust_task *task, stk_seg *stk)
task->free(stk);
}
extern "C" CDECL void
record_sp(void *limit);
// Entry points for `__morestack` (see arch/*/morestack.S).
extern "C" void *
rust_new_stack(size_t stk_sz, void *args_addr, size_t args_sz) {
rust_task *task = rust_scheduler::get_task();
stk_seg *stk_seg = new_stk(task->sched, task, stk_sz + args_sz);
uint8_t *new_sp = (uint8_t*)stk_seg->limit;
size_t sizeof_retaddr = sizeof(void*);
// Make enough room on the new stack to hold the old stack pointer
// in addition to the function arguments
new_sp = align_down(new_sp - (args_sz + sizeof_retaddr));
new_sp += sizeof_retaddr;
memcpy(new_sp, args_addr, args_sz);
record_sp(stk_seg->data + RED_ZONE_SIZE);
return new_sp;
}
struct rust_new_stack2_args {
size_t stk_sz;
void *args_addr;
size_t args_sz;
};
// A new stack function suitable for calling through
// upcall_call_shim_on_c_stack
extern "C" void *
rust_new_stack2(struct rust_new_stack2_args *args) {
return rust_new_stack(args->stk_sz, args->args_addr,
args->args_sz);
}
extern "C" void
rust_del_stack() {
rust_task *task = rust_scheduler::get_task();
del_stk(task, task->stk);
record_sp(task->stk->data + RED_ZONE_SIZE);
}
extern "C" rust_task *
rust_get_task() {
return rust_scheduler::get_task();
}
// Tasks
rust_task::rust_task(rust_scheduler *sched, rust_task_list *state,
rust_task *spawner, const char *name) :
@ -609,6 +561,31 @@ rust_task::notify(bool success) {
}
}
extern "C" CDECL void
record_sp(void *limit);
void *
rust_task::new_stack(size_t stk_sz, void *args_addr, size_t args_sz) {
stk_seg *stk_seg = new_stk(sched, this, stk_sz + args_sz);
uint8_t *new_sp = (uint8_t*)stk_seg->limit;
size_t sizeof_retaddr = sizeof(void*);
// Make enough room on the new stack to hold the old stack pointer
// in addition to the function arguments
new_sp = align_down(new_sp - (args_sz + sizeof_retaddr));
new_sp += sizeof_retaddr;
memcpy(new_sp, args_addr, args_sz);
record_sp(stk_seg->data + RED_ZONE_SIZE);
return new_sp;
}
void
rust_task::del_stack() {
del_stk(this, stk);
record_sp(stk->data + RED_ZONE_SIZE);
}
//
// Local Variables:
// mode: C++

View file

@ -196,6 +196,9 @@ rust_task : public kernel_owned<rust_task>, rust_cond
void claim_alloc(void *alloc, const type_desc *tydesc);
void notify(bool success);
void *new_stack(size_t stk_sz, void *args_addr, size_t args_sz);
void del_stack();
};
//

View file

@ -219,6 +219,26 @@ upcall_call_shim_on_c_stack(void *args, void *fn_ptr) {
sched->c_context.call_shim_on_c_stack(args, fn_ptr);
}
struct rust_new_stack2_args {
size_t stk_sz;
void *args_addr;
size_t args_sz;
};
// A new stack function suitable for calling through
// upcall_call_shim_on_c_stack
extern "C" CDECL void *
upcall_new_stack(struct rust_new_stack2_args *args) {
rust_task *task = rust_scheduler::get_task();
return task->new_stack(args->stk_sz, args->args_addr, args->args_sz);
}
extern "C" CDECL void
upcall_del_stack() {
rust_task *task = rust_scheduler::get_task();
task->del_stack();
}
extern "C" _Unwind_Reason_Code
__gxx_personality_v0(int version,
_Unwind_Action actions,

View file

@ -27,7 +27,6 @@ rand_free
rand_new
rand_next
refcount
rust_del_stack
rust_file_is_dir
rust_getcwd
rust_get_stdin
@ -37,7 +36,6 @@ rust_str_push
rust_list_files
rust_port_detach
rust_port_size
rust_new_stack
rust_process_wait
rust_ptr_eq
rust_run_program
@ -68,4 +66,6 @@ upcall_shared_free
upcall_vec_grow
upcall_vec_push
upcall_call_shim_on_c_stack
upcall_new_stack
upcall_del_stack
asm_call_on_stack