rt: More work on morestack
This commit is contained in:
parent
8199558443
commit
68aff2ad6d
3
mk/rt.mk
3
mk/rt.mk
@ -67,7 +67,8 @@ RUNTIME_CS_$(1) := \
|
||||
|
||||
RUNTIME_S_$(1) := rt/arch/$$(HOST_$(1))/_context.S \
|
||||
rt/arch/$$(HOST_$(1))/ccall.S \
|
||||
rt/arch/$$(HOST_$(1))/morestack.S
|
||||
rt/arch/$$(HOST_$(1))/morestack.S \
|
||||
rt/arch/$$(HOST_$(1))/record_sp.S
|
||||
|
||||
RUNTIME_HDR_$(1) := rt/globals.h \
|
||||
rt/rust.h \
|
||||
|
@ -2,40 +2,117 @@
|
||||
|
||||
// __morestack
|
||||
//
|
||||
// LLVM generates a call to this to allocate more stack space in a functiono
|
||||
// LLVM generates a call to this to allocate more stack space in a function
|
||||
// prolog when we run out.
|
||||
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
#define RUST_NEW_STACK _rust_new_stack
|
||||
#define RUST_DEL_STACK _rust_del_stack
|
||||
#define MORESTACK ___morestack
|
||||
#define RUST_NEW_STACK _rust_new_stack
|
||||
#define RUST_DEL_STACK _rust_del_stack
|
||||
#define RUST_GET_PREV_STACK _rust_get_prev_stack
|
||||
#define RUST_GET_TASK _rust_get_task
|
||||
#define UPCALL_ALLOC_C_STACK _upcall_alloc_c_stack
|
||||
#define UPCALL_CALL_C_STACK _upcall_call_c_stack
|
||||
#define MORESTACK ___morestack
|
||||
#else
|
||||
#define RUST_NEW_STACK rust_new_stack
|
||||
#define RUST_DEL_STACK rust_del_stack
|
||||
#define MORESTACK __morestack
|
||||
#define RUST_NEW_STACK rust_new_stack
|
||||
#define RUST_DEL_STACK rust_del_stack
|
||||
#define RUST_GET_PREV_STACK rust_get_prev_stack
|
||||
#define RUST_GET_TASK rust_get_task
|
||||
#define UPCALL_ALLOC_C_STACK upcall_alloc_c_stack
|
||||
#define UPCALL_CALL_C_STACK upcall_call_c_stack
|
||||
#define MORESTACK __morestack
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define ALIGNMENT 4
|
||||
#else
|
||||
#define ALIGNMENT 8
|
||||
#endif
|
||||
|
||||
#define RETURN_OFFSET 7
|
||||
|
||||
.globl RUST_NEW_STACK
|
||||
.globl RUST_DEL_STACK
|
||||
|
||||
.globl RUST_GET_PREV_STACK
|
||||
.globl RUST_GET_TASK
|
||||
.globl UPCALL_ALLOC_C_STACK
|
||||
.globl UPCALL_CALL_C_STACK
|
||||
.globl MORESTACK
|
||||
|
||||
MORESTACK:
|
||||
pushl 8(%esp) // argsz > ra stksz argsz x x ra args
|
||||
leal 28(%esp),%eax // argsz ra stksz argsz x x ra args
|
||||
pushl %eax // argp > argsz ra stksz argsz x x ra args
|
||||
pushl 12(%esp) // stksz > argp argsz ra stksz argsz x x ra args
|
||||
calll RUST_NEW_STACK
|
||||
addl $12,%esp // ra stksz argsz x x ra args
|
||||
|
||||
movl (%esp),%edx // Grab the return pointer.
|
||||
incl %edx // Skip past the `ret`.
|
||||
movl %eax,%esp // Switch to the new stack.
|
||||
// Sanity check to make sure that there is a currently-running task.
|
||||
subl $12,%esp
|
||||
calll RUST_GET_TASK
|
||||
testl %eax,%eax
|
||||
jz L$bail
|
||||
|
||||
subl $12,%esp
|
||||
pushl $12
|
||||
calll UPCALL_ALLOC_C_STACK
|
||||
movl %eax,%edx
|
||||
|
||||
// C stack | esp+12
|
||||
// ---------------------+-------------------------
|
||||
movl 20(%esp),%eax // | ra stksz argsz x ra args
|
||||
movl %eax,8(%edx) // argsz > | ra stksz argsz x ra args
|
||||
leal 32(%esp),%eax // argsz | ra stksz argsz x ra args
|
||||
movl %eax,4(%edx) // argp > argsz | ra stksz argsz x ra args
|
||||
movl 16(%esp),%eax // argp argsz | ra stksz argsz x ra args
|
||||
movl %eax,(%edx) // stksz > argp argsz | ra stksz argsz x ra args
|
||||
|
||||
calll L$pic_ref_pt_0
|
||||
L$pic_ref_pt_0:
|
||||
popl %eax
|
||||
|
||||
movl rust_new_stack_sym-L$pic_ref_pt_0(%eax),%eax
|
||||
movl %eax,(%esp)
|
||||
movl %edx,4(%esp)
|
||||
calll UPCALL_CALL_C_STACK
|
||||
|
||||
movl 16(%esp),%edx // Grab the return pointer.
|
||||
addl $RETURN_OFFSET,%edx // Skip past the `add esp,4` and the `ret`.
|
||||
|
||||
movl %eax,%esp // Switch stacks.
|
||||
subl $12,%esp // Align the stack.
|
||||
calll *%edx // Re-enter the function that called us.
|
||||
|
||||
// Now the function that called us has returned, so we need to delete the
|
||||
// old stack space.
|
||||
calll RUST_DEL_STACK
|
||||
movl %eax,%esp
|
||||
retl $8 // ra stksz argsz x x ra args
|
||||
|
||||
calll RUST_GET_PREV_STACK
|
||||
movl %eax,%esp // Switch back to the old stack.
|
||||
|
||||
movl $0,(%esp)
|
||||
calll UPCALL_ALLOC_C_STACK
|
||||
|
||||
calll L$pic_ref_pt_1
|
||||
L$pic_ref_pt_1:
|
||||
popl %edx
|
||||
|
||||
movl rust_del_stack_sym-L$pic_ref_pt_1(%edx),%edx
|
||||
movl %edx,(%esp)
|
||||
movl %eax,4(%esp)
|
||||
calll UPCALL_CALL_C_STACK
|
||||
|
||||
addl $16,%esp
|
||||
retl $16 + ALIGNMENT // ra stksz argsz x ra args
|
||||
|
||||
L$bail:
|
||||
movl 12(%esp),%edx
|
||||
addl $RETURN_OFFSET,%edx
|
||||
addl $12+16,%esp
|
||||
jmpl *%edx
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
.section __IMPORT,__pointers,non_lazy_symbol_pointers
|
||||
rust_new_stack_sym:
|
||||
.indirect_symbol RUST_NEW_STACK
|
||||
.long 0
|
||||
rust_del_stack_sym:
|
||||
.indirect_symbol RUST_DEL_STACK
|
||||
.long 0
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "rust_internal.h"
|
||||
#include <cstdio>
|
||||
|
||||
struct
|
||||
command_line_args : public kernel_owned<command_line_args>
|
||||
@ -75,6 +76,8 @@ int check_claims = 0;
|
||||
|
||||
extern "C" CDECL int
|
||||
rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) {
|
||||
fprintf(stderr, "rust_start, argc=%d argv=%p\n", argc, argv);
|
||||
|
||||
rust_env *env = load_env();
|
||||
|
||||
update_log_settings(crate_map, env->logspec);
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <cassert>
|
||||
#include <pthread.h>
|
||||
#include "rust_internal.h"
|
||||
#include "globals.h"
|
||||
|
||||
@ -12,6 +13,9 @@ DWORD rust_scheduler::task_key;
|
||||
|
||||
bool rust_scheduler::tls_initialized = false;
|
||||
|
||||
// Defined in arch/*/record_sp.S.
|
||||
extern "C" void rust_record_sp(uintptr_t sp);
|
||||
|
||||
rust_scheduler::rust_scheduler(rust_kernel *kernel,
|
||||
rust_srv *srv,
|
||||
int id) :
|
||||
@ -285,6 +289,8 @@ rust_scheduler::start_main_loop() {
|
||||
scheduled_task->state->name);
|
||||
|
||||
place_task_in_tls(scheduled_task);
|
||||
rust_record_sp(scheduled_task->stk->limit);
|
||||
//pthread_setspecific(89, (void *)scheduled_task->stk->limit);
|
||||
|
||||
interrupt_flag = 0;
|
||||
|
||||
@ -374,6 +380,8 @@ rust_scheduler::place_task_in_tls(rust_task *task) {
|
||||
|
||||
rust_task *
|
||||
rust_scheduler::get_task() {
|
||||
if (!tls_initialized)
|
||||
return NULL;
|
||||
rust_task *task = reinterpret_cast<rust_task *>
|
||||
(pthread_getspecific(task_key));
|
||||
assert(task && "Couldn't get the task from TLS!");
|
||||
@ -395,6 +403,8 @@ rust_scheduler::place_task_in_tls(rust_task *task) {
|
||||
|
||||
rust_task *
|
||||
rust_scheduler::get_task() {
|
||||
if (!tls_initialized)
|
||||
return NULL;
|
||||
rust_task *task = reinterpret_cast<rust_task *>(TlsGetValue(task_key));
|
||||
assert(task && "Couldn't get the task from TLS!");
|
||||
return task;
|
||||
|
@ -8,11 +8,14 @@
|
||||
#ifndef __WIN32__
|
||||
#include <execinfo.h>
|
||||
#endif
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
#define RED_ZONE_SIZE 128
|
||||
|
||||
// Stack size
|
||||
size_t g_custom_min_stack_size = 0;
|
||||
|
||||
@ -34,16 +37,16 @@ new_stk(rust_scheduler *sched, rust_task *task, size_t minsz)
|
||||
size_t min_stk_bytes = get_min_stk_size(sched->min_stack_size);
|
||||
if (minsz < min_stk_bytes)
|
||||
minsz = min_stk_bytes;
|
||||
size_t sz = sizeof(stk_seg) + minsz;
|
||||
size_t sz = sizeof(stk_seg) + minsz + RED_ZONE_SIZE;
|
||||
stk_seg *stk = (stk_seg *)task->malloc(sz, "stack");
|
||||
LOGPTR(task->sched, "new stk", (uintptr_t)stk);
|
||||
memset(stk, 0, sizeof(stk_seg));
|
||||
stk->next = task->stk;
|
||||
stk->limit = (uintptr_t) &stk->data[minsz];
|
||||
stk->limit = (uintptr_t) &stk->data[minsz + RED_ZONE_SIZE];
|
||||
LOGPTR(task->sched, "stk limit", stk->limit);
|
||||
stk->valgrind_id =
|
||||
VALGRIND_STACK_REGISTER(&stk->data[0],
|
||||
&stk->data[minsz]);
|
||||
&stk->data[minsz + RED_ZONE_SIZE]);
|
||||
task->stk = stk;
|
||||
return stk;
|
||||
}
|
||||
@ -63,18 +66,32 @@ del_stk(rust_task *task, stk_seg *stk)
|
||||
// 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) {
|
||||
std::cerr << "*** New stack!\n";
|
||||
|
||||
rust_task *task = rust_scheduler::get_task();
|
||||
if (!task)
|
||||
return NULL;
|
||||
|
||||
stk_seg *stk_seg = new_stk(task->sched, task, stk_sz);
|
||||
memcpy(stk_seg->data, args_addr, args_sz);
|
||||
return stk_seg->data;
|
||||
}
|
||||
|
||||
extern "C" void *
|
||||
extern "C" void
|
||||
rust_del_stack() {
|
||||
rust_task *task = rust_scheduler::get_task();
|
||||
stk_seg *next_seg = task->stk->next;
|
||||
del_stk(task, task->stk);
|
||||
return next_seg->data;
|
||||
}
|
||||
|
||||
extern "C" void *
|
||||
rust_get_prev_stack() {
|
||||
rust_task *task = rust_scheduler::get_task();
|
||||
return task->stk->next;
|
||||
}
|
||||
|
||||
extern "C" rust_task *
|
||||
rust_get_task() {
|
||||
return rust_scheduler::get_task();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
__morestack
|
||||
align_of
|
||||
chan_id_send
|
||||
check_claims
|
||||
@ -28,7 +29,10 @@ rand_free
|
||||
rand_new
|
||||
rand_next
|
||||
refcount
|
||||
rust_del_stack
|
||||
rust_file_is_dir
|
||||
rust_getcwd
|
||||
rust_get_prev_stack
|
||||
rust_get_stdin
|
||||
rust_get_stdout
|
||||
rust_get_stderr
|
||||
@ -36,12 +40,14 @@ rust_str_push
|
||||
rust_list_files
|
||||
rust_port_detach
|
||||
rust_port_size
|
||||
rust_new_stack
|
||||
rust_process_wait
|
||||
rust_ptr_eq
|
||||
rust_run_program
|
||||
rust_start
|
||||
rust_getcwd
|
||||
rust_task_sleep
|
||||
rust_get_task
|
||||
set_min_stack
|
||||
sched_threads
|
||||
size_of
|
||||
@ -63,10 +69,10 @@ upcall_dynastack_mark
|
||||
upcall_fail
|
||||
upcall_free
|
||||
upcall_get_type_desc
|
||||
upcall_vec_grow
|
||||
upcall_vec_push
|
||||
upcall_log_type
|
||||
upcall_malloc
|
||||
upcall_rust_personality
|
||||
upcall_shared_malloc
|
||||
upcall_shared_free
|
||||
upcall_vec_grow
|
||||
upcall_vec_push
|
||||
|
Loading…
Reference in New Issue
Block a user