diff options
| author | Eric Holk <eholk@mozilla.com> | 2011-06-15 18:16:17 -0700 |
|---|---|---|
| committer | Eric Holk <eholk@mozilla.com> | 2011-06-15 18:16:59 -0700 |
| commit | 67360ae61808453d308496f90e0b3faa3e8efee3 (patch) | |
| tree | 7df5f198272c57aeebf35e9a22aa03cd12f33e0b /src/rt | |
| parent | c4f9bd94700188678893659580f3b7aa80da3b7d (diff) | |
Fixed a problem where spawn arguments were getting lost again. Also, fixed up stack alignment, which closes #496
Diffstat (limited to 'src/rt')
| -rw-r--r-- | src/rt/arch/i386/context.cpp | 6 | ||||
| -rw-r--r-- | src/rt/arch/i386/context.h | 8 | ||||
| -rw-r--r-- | src/rt/rust.cpp | 3 | ||||
| -rw-r--r-- | src/rt/rust_task.cpp | 10 | ||||
| -rw-r--r-- | src/rt/rust_task.h | 3 | ||||
| -rw-r--r-- | src/rt/rust_upcall.cpp | 23 | ||||
| -rw-r--r-- | src/rt/test/rust_test_runtime.cpp | 2 |
7 files changed, 31 insertions, 24 deletions
diff --git a/src/rt/arch/i386/context.cpp b/src/rt/arch/i386/context.cpp index 8f5dbacbcf4..c1c8ba2167b 100644 --- a/src/rt/arch/i386/context.cpp +++ b/src/rt/arch/i386/context.cpp @@ -36,10 +36,14 @@ void context::swap(context &out) void context::call(void *f, void *arg, void *stack) { // set up the trampoline frame uint32_t *sp = (uint32_t *)stack; + + // Shift the stack pointer so the alignment works out right. + sp = align_down(sp) - 2; + *--sp = (uint32_t)this; *--sp = (uint32_t)arg; - *--sp = 0xdeadbeef; //(uint32_t)ctx_trampoline1; *--sp = 0xdeadbeef; + *--sp = 0xca11ab1e; regs.esp = (uint32_t)sp; regs.eip = (uint32_t)f; diff --git a/src/rt/arch/i386/context.h b/src/rt/arch/i386/context.h index 0ddbee6988f..5329016450a 100644 --- a/src/rt/arch/i386/context.h +++ b/src/rt/arch/i386/context.h @@ -32,4 +32,12 @@ public: void call(void *f, void *arg, void *sp); }; +template<typename T> +T align_down(T sp) +{ + // There is no platform we care about that needs more than a + // 16-byte alignment. + return (T)((int)sp & ~(16 - 1)); +} + #endif diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index 166c0002533..c7cece2ef81 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -93,8 +93,7 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) { DLOG(dom, dom, "startup: arg[%d] = '%s'", i, args->argv[i]); } - dom->root_task->start(main_fn, - (uintptr_t)args->args, sizeof(args->args)); + dom->root_task->start(main_fn, (uintptr_t)args->args); int ret = dom->start_main_loop(); delete args; diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index bae6f221a95..bb8261bb78a 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -17,6 +17,7 @@ static size_t const min_stk_bytes = 0x300000; // static size_t const min_stk_bytes = 0x10000; + // Task stack segments. Heap allocated and chained together. static stk_seg* @@ -152,25 +153,24 @@ void task_start_wrapper(spawn_args *a) void rust_task::start(uintptr_t spawnee_fn, - uintptr_t args, - size_t callsz) + uintptr_t args) { LOGPTR(dom, "from spawnee", spawnee_fn); I(dom, stk->data != NULL); - char *sp = (char *)stk->limit; + char *sp = (char *)rust_sp; sp -= sizeof(spawn_args); spawn_args *a = (spawn_args *)sp; a->task = this; - a->a3 = 0xca11ab1e; + a->a3 = 0; a->a4 = args; void **f = (void **)&a->f; *f = (void *)spawnee_fn; - + ctx.call((void *)task_start_wrapper, a, sp); yield_timer.reset(0); diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h index 82792c1e1e5..a022a348667 100644 --- a/src/rt/rust_task.h +++ b/src/rt/rust_task.h @@ -60,8 +60,7 @@ rust_task : public maybe_proxy<rust_task>, ~rust_task(); void start(uintptr_t spawnee_fn, - uintptr_t args, - size_t callsz); + uintptr_t args); void grow(size_t n_frame_bytes); bool running(); bool blocked(); diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index 68a15e3b3a3..e8c8e45e1c6 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -509,14 +509,6 @@ upcall_new_task(rust_task *spawner, rust_vec *name) { return task; } -static uintptr_t -align_down(uintptr_t sp) -{ - // There is no platform we care about that needs more than a - // 16-byte alignment. - return sp & ~(16 - 1); -} - extern "C" CDECL rust_task * upcall_start_task(rust_task *spawner, rust_task *task, @@ -538,12 +530,11 @@ upcall_start_task(rust_task *spawner, // The args tuple is stack-allocated. We need to move it over to the new // stack. task->rust_sp -= args_sz; + uintptr_t child_arg = (uintptr_t)task->rust_sp; + memcpy((void*)task->rust_sp, (void*)args, args_sz); - uintptr_t start_args[] = {0, 0, 0, task->rust_sp}; - - task->rust_sp = align_down(task->rust_sp); - - task->start(spawnee_fn, (uintptr_t)start_args, sizeof(start_args)); + + task->start(spawnee_fn, child_arg); return task; } @@ -567,6 +558,8 @@ upcall_new_thread(rust_task *task, const char *name) { return child_task_proxy; } +#if 0 /* TODO: this code will be re-enabled once we have multithreading. */ + #if defined(__WIN32__) static DWORD WINAPI rust_thread_start(void *ptr) #elif defined(__GNUC__) @@ -587,6 +580,8 @@ static void *rust_thread_start(void *ptr) return 0; } +#endif + /** * Called after a new domain is created. Here we create a new thread and * and start the domain main loop. @@ -597,6 +592,7 @@ upcall_start_thread(rust_task *task, uintptr_t spawnee_fn, size_t callsz) { LOG_UPCALL_ENTRY(task); +#if 0 rust_dom *parenet_dom = task->dom; rust_handle<rust_task> *child_task_handle = child_task_proxy->handle(); LOG(task, task, @@ -616,6 +612,7 @@ upcall_start_thread(rust_task *task, pthread_create(&thread, &parenet_dom->attr, rust_thread_start, (void *) child_task->dom); #endif +#endif // 0 return child_task_proxy; } diff --git a/src/rt/test/rust_test_runtime.cpp b/src/rt/test/rust_test_runtime.cpp index c683302dec2..0fed35dad82 100644 --- a/src/rt/test/rust_test_runtime.cpp +++ b/src/rt/test/rust_test_runtime.cpp @@ -52,7 +52,7 @@ rust_task_test::worker::run() { rust_handle<rust_dom> *handle = kernel->create_domain("test"); rust_dom *domain = handle->referent(); - domain->root_task->start((uintptr_t)&task_entry, (uintptr_t)NULL, 0); + domain->root_task->start((uintptr_t)&task_entry, (uintptr_t)NULL); domain->start_main_loop(); kernel->destroy_domain(domain); } |
