diff options
| author | Brian Anderson <[email protected]> | 2011-03-07 21:21:01 -0500 |
|---|---|---|
| committer | Brian Anderson <[email protected]> | 2011-03-07 21:21:01 -0500 |
| commit | 9fc4db6b89213afdf45c02fc2bd2be62b0ddc40c (patch) | |
| tree | 6c84574116273f91cbe89abd256b9f809adf97de /src/rt | |
| parent | Allow the else part of an expr_if to be either expr_if or expr_block (diff) | |
| parent | rustc: Cast the LLVM representations of tag types when constructing boxes. Un... (diff) | |
| download | rust-9fc4db6b89213afdf45c02fc2bd2be62b0ddc40c.tar.xz rust-9fc4db6b89213afdf45c02fc2bd2be62b0ddc40c.zip | |
Merge branch 'master' into recursive-elseif
Conflicts:
src/Makefile
src/comp/front/ast.rs
src/comp/front/parser.rs
src/comp/middle/fold.rs
src/comp/middle/trans.rs
Diffstat (limited to 'src/rt')
| -rw-r--r-- | src/rt/memory_region.cpp | 5 | ||||
| -rw-r--r-- | src/rt/rust.cpp | 8 | ||||
| -rw-r--r-- | src/rt/rust_crate_cache.cpp | 5 | ||||
| -rw-r--r-- | src/rt/rust_internal.h | 6 | ||||
| -rw-r--r-- | src/rt/rust_task.cpp | 56 | ||||
| -rw-r--r-- | src/rt/rust_task.h | 1 | ||||
| -rw-r--r-- | src/rt/rust_upcall.cpp | 15 | ||||
| -rw-r--r-- | src/rt/test/rust_test_runtime.cpp | 1 |
8 files changed, 68 insertions, 29 deletions
diff --git a/src/rt/memory_region.cpp b/src/rt/memory_region.cpp index fb19620f..48220290 100644 --- a/src/rt/memory_region.cpp +++ b/src/rt/memory_region.cpp @@ -1,7 +1,10 @@ #include "rust_internal.h" #include "memory_region.h" -#define TRACK_ALLOCATIONS +// NB: please do not commit code with this uncommented. It's +// hugely expensive and should only be used as a last resort. +// +// #define TRACK_ALLOCATIONS memory_region::memory_region(rust_srv *srv, bool synchronized) : _srv(srv), _parent(NULL), _live_allocations(0), diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index 0ea167a4..46fcb22e 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -78,7 +78,7 @@ command_line_args : public dom_owned<command_line_args> extern "C" CDECL int rust_start(uintptr_t main_fn, rust_crate const *crate, int argc, - char **argv) { + char **argv) { rust_srv *srv = new rust_srv(); rust_kernel *kernel = new rust_kernel(srv); @@ -87,7 +87,8 @@ rust_start(uintptr_t main_fn, rust_crate const *crate, int argc, rust_dom *dom = handle->referent(); command_line_args *args = new (dom) command_line_args(dom, argc, argv); - dom->log(rust_log::DOM, "startup: %d args", args->argc); + dom->log(rust_log::DOM, "startup: %d args in 0x%" PRIxPTR, + args->argc, (uintptr_t)args->args); for (int i = 0; i < args->argc; i++) { dom->log(rust_log::DOM, "startup: arg[%d] = '%s'", i, args->argv[i]); @@ -99,7 +100,8 @@ rust_start(uintptr_t main_fn, rust_crate const *crate, int argc, uintptr_t main_args[4] = {0, 0, 0, (uintptr_t)args->args}; dom->root_task->start(crate->get_exit_task_glue(), - main_fn, (uintptr_t)&main_args, sizeof(main_args)); + crate->abi_tag, main_fn, + (uintptr_t)&main_args, sizeof(main_args)); int ret = dom->start_main_loop(); delete args; kernel->destroy_domain(dom); diff --git a/src/rt/rust_crate_cache.cpp b/src/rt/rust_crate_cache.cpp index adf1bbfc..62fd7c01 100644 --- a/src/rt/rust_crate_cache.cpp +++ b/src/rt/rust_crate_cache.cpp @@ -49,7 +49,8 @@ rust_crate_cache::c_sym::c_sym(rust_dom *dom, lib *library, char const *name) dom->log(rust_log::CACHE, "resolved symbol '%s' to 0x%" PRIxPTR, name, val); } else { - dom->log(rust_log::CACHE, "unresolved symbol '%s', null lib handle", + dom->log(rust_log::CACHE | rust_log::ERR, + "unresolved symbol '%s', null lib handle", name); } } @@ -79,7 +80,7 @@ rust_crate_cache::rust_sym::rust_sym(rust_dom *dom, typedef rust_crate_reader::die die; rust_crate const *crate = (rust_crate*)crate_sym->get_val(); if (!crate) { - dom->log(rust_log::CACHE, + dom->log(rust_log::CACHE | rust_log::ERR, "failed to resolve symbol, null crate symbol"); return; } diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h index 61716703..42b61801 100644 --- a/src/rt/rust_internal.h +++ b/src/rt/rust_internal.h @@ -88,6 +88,10 @@ static size_t const TIME_SLICE_IN_MS = 10; static intptr_t const CONST_REFCOUNT = 0x7badface; +// ABI tags for rust_start, rust_task::start and friends. +static uintptr_t const ABI_X86_RUSTBOOT_CDECL = 1; +static uintptr_t const ABI_X86_RUSTC_FASTCALL = 2; + // This accounts for logging buffers. static size_t const BUF_BYTES = 2048; @@ -241,6 +245,8 @@ public: size_t n_c_syms; size_t n_libs; + uintptr_t abi_tag; + // Crates are immutable, constructed by the compiler. uintptr_t get_image_base() const; diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index 68882b21..1afbfdd6 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -123,6 +123,7 @@ rust_task::~rust_task() void rust_task::start(uintptr_t exit_task_glue, + uintptr_t spawnee_abi, uintptr_t spawnee_fn, uintptr_t args, size_t callsz) @@ -147,26 +148,29 @@ rust_task::start(uintptr_t exit_task_glue, // The exit_task_glue frame we synthesize above the frame we activate: *spp-- = (uintptr_t) 0; // closure-or-obj *spp-- = (uintptr_t) this; // task - *spp-- = (uintptr_t) 0; // output - *spp-- = (uintptr_t) 0; // retpc + *spp-- = (uintptr_t) 0x0; // output + *spp-- = (uintptr_t) 0x0; // retpc uintptr_t exit_task_frame_base; - for (size_t j = 0; j < n_callee_saves; ++j) { + if (spawnee_abi == ABI_X86_RUSTBOOT_CDECL) { + for (size_t j = 0; j < n_callee_saves; ++j) { - // We want 'frame_base' to point to the old fp in this (exit-task) - // frame, because we're going to inject this frame-pointer into the - // callee-save frame pointer value in the *next* (spawnee) frame. A - // cheap trick, but this means the spawnee frame will restore the - // proper frame pointer of the glue frame as it runs its epilogue. - if (j == callee_save_fp) - exit_task_frame_base = (uintptr_t)spp; + // We want 'frame_base' to point to the old fp in this (exit-task) + // frame, because we're going to inject this frame-pointer into + // the callee-save frame pointer value in the *next* (spawnee) + // frame. A cheap trick, but this means the spawnee frame will + // restore the proper frame pointer of the glue frame as it runs + // its epilogue. + if (j == callee_save_fp) + exit_task_frame_base = (uintptr_t)spp; - *spp-- = 0; - } + *spp-- = 0; + } - *spp-- = (uintptr_t) dom->root_crate; // crate ptr - *spp-- = (uintptr_t) 0; // frame_glue_fns + *spp-- = (uintptr_t) dom->root_crate; // crate ptr + *spp-- = (uintptr_t) 0; // frame_glue_fns + } // Copy args from spawner to spawnee. if (args) { @@ -174,12 +178,16 @@ rust_task::start(uintptr_t exit_task_glue, src += 1; // spawn-call output slot src += 1; // spawn-call task slot src += 1; // spawn-call closure-or-obj slot - // Memcpy all but the task and output pointers - callsz -= (2 * sizeof(uintptr_t)); + + // Undo previous sp-- so we're pointing at the last word pushed. + ++spp; + + // Memcpy all but the task, output and env pointers + callsz -= (3 * sizeof(uintptr_t)); spp = (uintptr_t*) (((uintptr_t)spp) - callsz); memcpy(spp, src, callsz); - // Move sp down to point to task cell. + // Move sp down to point to last implicit-arg cell (env). spp--; } else { // We're at root, starting up. @@ -188,10 +196,18 @@ rust_task::start(uintptr_t exit_task_glue, // The *implicit* incoming args to the spawnee frame we're // activating: + *spp-- = (uintptr_t) 0x0; // closure-or-obj + + if (spawnee_abi == ABI_X86_RUSTBOOT_CDECL) { + // in CDECL mode we write the task + outptr to the spawnee stack. + *spp-- = (uintptr_t) this; // task + *spp-- = (uintptr_t) 0; // output addr + } else { + // in FASTCALL mode we don't, the outptr will be in ecx and the task + // in edx, and the activate_glue will make sure to set that up. + I(dom, spawnee_abi == ABI_X86_RUSTC_FASTCALL); + } - *spp-- = (uintptr_t) 0; // closure-or-obj - *spp-- = (uintptr_t) this; // task - *spp-- = (uintptr_t) 0; // output addr *spp-- = (uintptr_t) exit_task_glue; // retpc // The context the activate_glue needs to switch stack. diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h index 9fbc67ac..5318ab71 100644 --- a/src/rt/rust_task.h +++ b/src/rt/rust_task.h @@ -56,6 +56,7 @@ rust_task : public maybe_proxy<rust_task>, ~rust_task(); void start(uintptr_t exit_task_glue, + uintptr_t spawnee_abi, uintptr_t spawnee_fn, uintptr_t args, size_t callsz); diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index 7e2fac10..1dba1102 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -253,6 +253,10 @@ upcall_fail(rust_task *task, task->log(rust_log::UPCALL | rust_log::ERR, "upcall fail '%s', %s:%" PRIdPTR, expr, file, line); task->fail(4); + if (getenv("RUST_TRAP_FAILURE")) { + // FIXME: x86-ism. + __asm__("int3"); + } } /** @@ -555,6 +559,7 @@ extern "C" CDECL rust_task * upcall_start_task(rust_task *spawner, rust_task *task, uintptr_t exit_task_glue, + uintptr_t spawnee_abi, uintptr_t spawnee_fn, size_t callsz) { LOG_UPCALL_ENTRY(spawner); @@ -566,7 +571,8 @@ upcall_start_task(rust_task *spawner, ", spawnee 0x%" PRIxPTR ", callsz %" PRIdPTR ")", task->name, task, exit_task_glue, spawnee_fn, callsz); - task->start(exit_task_glue, spawnee_fn, spawner->rust_sp, callsz); + task->start(exit_task_glue, spawnee_abi, spawnee_fn, + spawner->rust_sp, callsz); return task; } @@ -619,6 +625,7 @@ extern "C" CDECL maybe_proxy<rust_task> * upcall_start_thread(rust_task *task, rust_proxy<rust_task> *child_task_proxy, uintptr_t exit_task_glue, + uintptr_t spawnee_abi, uintptr_t spawnee_fn, size_t callsz) { LOG_UPCALL_ENTRY(task); @@ -626,9 +633,11 @@ upcall_start_thread(rust_task *task, rust_handle<rust_task> *child_task_handle = child_task_proxy->handle(); task->log(rust_log::UPCALL | rust_log::MEM | rust_log::TASK, "exit_task_glue: " PTR ", spawnee_fn " PTR - ", callsz %" PRIdPTR ")", exit_task_glue, spawnee_fn, callsz); + ", callsz %" PRIdPTR ")", + exit_task_glue, spawnee_fn, callsz); rust_task *child_task = child_task_handle->referent(); - child_task->start(exit_task_glue, spawnee_fn, task->rust_sp, callsz); + child_task->start(exit_task_glue, spawnee_abi, spawnee_fn, + task->rust_sp, callsz); #if defined(__WIN32__) HANDLE thread; thread = CreateThread(NULL, 0, rust_thread_start, child_task->dom, 0, diff --git a/src/rt/test/rust_test_runtime.cpp b/src/rt/test/rust_test_runtime.cpp index 1cde532e..e0e24156 100644 --- a/src/rt/test/rust_test_runtime.cpp +++ b/src/rt/test/rust_test_runtime.cpp @@ -54,6 +54,7 @@ rust_task_test::worker::run() { kernel->create_domain(crate, "test"); rust_dom *domain = handle->referent(); domain->root_task->start(crate->get_exit_task_glue(), + ABI_X86_RUSTBOOT_CDECL, (uintptr_t)&task_entry, (uintptr_t)NULL, 0); domain->start_main_loop(); kernel->destroy_domain(domain); |