about summary refs log tree commit diff
path: root/src/rt
diff options
context:
space:
mode:
authorBrian Anderson <andersrb@gmail.com>2011-03-07 21:21:01 -0500
committerBrian Anderson <andersrb@gmail.com>2011-03-07 21:21:01 -0500
commit9fc4db6b89213afdf45c02fc2bd2be62b0ddc40c (patch)
tree6c84574116273f91cbe89abd256b9f809adf97de /src/rt
parent3fedb18c0af0bd9fa5e4973936003c0b57e4d3e8 (diff)
parent6ed226c6b3a28f3c10d2176d7dba7e339bf0ab99 (diff)
downloadrust-9fc4db6b89213afdf45c02fc2bd2be62b0ddc40c.tar.gz
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.cpp5
-rw-r--r--src/rt/rust.cpp8
-rw-r--r--src/rt/rust_crate_cache.cpp5
-rw-r--r--src/rt/rust_internal.h6
-rw-r--r--src/rt/rust_task.cpp56
-rw-r--r--src/rt/rust_task.h1
-rw-r--r--src/rt/rust_upcall.cpp15
-rw-r--r--src/rt/test/rust_test_runtime.cpp1
8 files changed, 68 insertions, 29 deletions
diff --git a/src/rt/memory_region.cpp b/src/rt/memory_region.cpp
index fb19620f8b9..48220290270 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 0ea167a4a8c..46fcb22ea0b 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 adf1bbfc84d..62fd7c01a9c 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 61716703deb..42b61801f53 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 68882b21882..1afbfdd6b3b 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 9fbc67acff5..5318ab71edf 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 7e2fac101ed..1dba11024f4 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 1cde532e94a..e0e24156e6f 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);