about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Holk <eholk@mozilla.com>2011-06-27 19:15:03 -0700
committerGraydon Hoare <graydon@mozilla.com>2011-06-28 16:12:33 -0700
commit49a8cb34d2b6e3f7af4a7cbe842fe48ffa0245eb (patch)
treefb74a37b34ec7334f273e1bc59c18d2daf439583
parentf6f945fed5c8d1061d80b444331910df29afa392 (diff)
downloadrust-49a8cb34d2b6e3f7af4a7cbe842fe48ffa0245eb.tar.gz
rust-49a8cb34d2b6e3f7af4a7cbe842fe48ffa0245eb.zip
Removed dom_owned, splitting things between task_owned and kernel_owned. Had to re-xfail a few tests brson recently un-xfailed.
-rw-r--r--src/rt/circular_buffer.cpp17
-rw-r--r--src/rt/circular_buffer.h8
-rw-r--r--src/rt/memory.h45
-rw-r--r--src/rt/rust.cpp31
-rw-r--r--src/rt/rust_builtin.cpp6
-rw-r--r--src/rt/rust_chan.cpp2
-rw-r--r--src/rt/rust_crate_cache.cpp4
-rw-r--r--src/rt/rust_dom.cpp68
-rw-r--r--src/rt/rust_dom.h11
-rw-r--r--src/rt/rust_internal.h41
-rw-r--r--src/rt/rust_kernel.h9
-rw-r--r--src/rt/rust_message.cpp7
-rw-r--r--src/rt/rust_port.cpp4
-rw-r--r--src/rt/rust_task.cpp86
-rw-r--r--src/rt/rust_task.h39
-rw-r--r--src/rt/rust_task_list.h3
-rw-r--r--src/rt/rust_upcall.cpp7
-rw-r--r--src/rt/rust_util.h49
-rw-r--r--src/test/run-pass/child-outlives-parent.rs2
-rw-r--r--src/test/run-pass/spawn-types.rs2
-rw-r--r--src/test/run-pass/task-life-0.rs2
21 files changed, 217 insertions, 226 deletions
diff --git a/src/rt/circular_buffer.cpp b/src/rt/circular_buffer.cpp
index ab98dfe34c4..0239e40f997 100644
--- a/src/rt/circular_buffer.cpp
+++ b/src/rt/circular_buffer.cpp
@@ -4,13 +4,14 @@
 
 #include "rust_internal.h"
 
-circular_buffer::circular_buffer(rust_dom *dom, size_t unit_sz) :
-    dom(dom),
+circular_buffer::circular_buffer(rust_task *task, size_t unit_sz) :
+    dom(task->dom),
+    task(task),
     unit_sz(unit_sz),
     _buffer_sz(initial_size()),
     _next(0),
     _unread(0),
-    _buffer((uint8_t *)dom->malloc(_buffer_sz)) {
+    _buffer((uint8_t *)task->malloc(_buffer_sz)) {
 
     A(dom, unit_sz, "Unit size must be larger than zero.");
 
@@ -26,7 +27,7 @@ circular_buffer::~circular_buffer() {
     I(dom, _buffer);
     W(dom, _unread == 0,
       "freeing circular_buffer with %d unread bytes", _unread);
-    dom->free(_buffer);
+    task->free(_buffer);
 }
 
 size_t
@@ -141,9 +142,9 @@ circular_buffer::grow() {
     size_t new_buffer_sz = _buffer_sz * 2;
     I(dom, new_buffer_sz <= MAX_CIRCULAR_BUFFER_SIZE);
     DLOG(dom, mem, "circular_buffer is growing to %d bytes", new_buffer_sz);
-    void *new_buffer = dom->malloc(new_buffer_sz);
+    void *new_buffer = task->malloc(new_buffer_sz);
     transfer(new_buffer);
-    dom->free(_buffer);
+    task->free(_buffer);
     _buffer = (uint8_t *)new_buffer;
     _next = 0;
     _buffer_sz = new_buffer_sz;
@@ -154,9 +155,9 @@ circular_buffer::shrink() {
     size_t new_buffer_sz = _buffer_sz / 2;
     I(dom, initial_size() <= new_buffer_sz);
     DLOG(dom, mem, "circular_buffer is shrinking to %d bytes", new_buffer_sz);
-    void *new_buffer = dom->malloc(new_buffer_sz);
+    void *new_buffer = task->malloc(new_buffer_sz);
     transfer(new_buffer);
-    dom->free(_buffer);
+    task->free(_buffer);
     _buffer = (uint8_t *)new_buffer;
     _next = 0;
     _buffer_sz = new_buffer_sz;
diff --git a/src/rt/circular_buffer.h b/src/rt/circular_buffer.h
index cdd0b03b091..1e686ea6f14 100644
--- a/src/rt/circular_buffer.h
+++ b/src/rt/circular_buffer.h
@@ -6,15 +6,17 @@
 #define CIRCULAR_BUFFER_H
 
 class
-circular_buffer : public dom_owned<circular_buffer> {
+circular_buffer : public task_owned<circular_buffer> {
     static const size_t INITIAL_CIRCULAR_BUFFER_SIZE_IN_UNITS = 8;
     static const size_t MAX_CIRCULAR_BUFFER_SIZE = 1 << 24;
 
-public:
     rust_dom *dom;
+
+public:
+    rust_task *task;
     // Size of the data unit in bytes.
     const size_t unit_sz;
-    circular_buffer(rust_dom *dom, size_t unit_sz);
+    circular_buffer(rust_task *task, size_t unit_sz);
     ~circular_buffer();
     void transfer(void *dst);
     void enqueue(void *src);
diff --git a/src/rt/memory.h b/src/rt/memory.h
index 9196e28dd83..d5e5a6eb1a7 100644
--- a/src/rt/memory.h
+++ b/src/rt/memory.h
@@ -1,3 +1,4 @@
+// -*- c++ -*-
 #ifndef MEMORY_H
 #define MEMORY_H
 
@@ -5,50 +6,54 @@ inline void *operator new(size_t size, void *mem) {
     return mem;
 }
 
-inline void *operator new(size_t size, rust_dom *dom) {
-    return dom->malloc(size, memory_region::LOCAL);
+inline void *operator new(size_t size, rust_kernel *kernel) {
+    return kernel->malloc(size);
 }
 
-inline void *operator new[](size_t size, rust_dom *dom) {
-    return dom->malloc(size, memory_region::LOCAL);
+inline void *operator new(size_t size, rust_task *task) {
+    return task->malloc(size, memory_region::LOCAL);
 }
 
-inline void *operator new(size_t size, rust_dom &dom) {
-    return dom.malloc(size, memory_region::LOCAL);
+inline void *operator new[](size_t size, rust_task *task) {
+    return task->malloc(size, memory_region::LOCAL);
 }
 
-inline void *operator new[](size_t size, rust_dom &dom) {
-    return dom.malloc(size, memory_region::LOCAL);
+inline void *operator new(size_t size, rust_task &task) {
+    return task.malloc(size, memory_region::LOCAL);
 }
 
-inline void *operator new(size_t size, rust_dom *dom,
+inline void *operator new[](size_t size, rust_task &task) {
+    return task.malloc(size, memory_region::LOCAL);
+}
+
+inline void *operator new(size_t size, rust_task *task,
     memory_region::memory_region_type type) {
-    return dom->malloc(size, type);
+    return task->malloc(size, type);
 }
 
-inline void *operator new[](size_t size, rust_dom *dom,
+inline void *operator new[](size_t size, rust_task *task,
     memory_region::memory_region_type type) {
-    return dom->malloc(size, type);
+    return task->malloc(size, type);
 }
 
-inline void *operator new(size_t size, rust_dom &dom,
+inline void *operator new(size_t size, rust_task &task,
     memory_region::memory_region_type type) {
-    return dom.malloc(size, type);
+    return task.malloc(size, type);
 }
 
-inline void *operator new[](size_t size, rust_dom &dom,
+inline void *operator new[](size_t size, rust_task &task,
     memory_region::memory_region_type type) {
-    return dom.malloc(size, type);
+    return task.malloc(size, type);
 }
 
-inline void operator delete(void *mem, rust_dom *dom) {
-    dom->free(mem, memory_region::LOCAL);
+inline void operator delete(void *mem, rust_task *task) {
+    task->free(mem, memory_region::LOCAL);
     return;
 }
 
-inline void operator delete(void *mem, rust_dom *dom,
+inline void operator delete(void *mem, rust_task *task,
     memory_region::memory_region_type type) {
-    dom->free(mem, type);
+    task->free(mem, type);
     return;
 }
 
diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp
index 2a491b61150..293d8562e4b 100644
--- a/src/rt/rust.cpp
+++ b/src/rt/rust.cpp
@@ -1,19 +1,21 @@
 #include "rust_internal.h"
 
 struct
-command_line_args : public dom_owned<command_line_args>
+command_line_args : public kernel_owned<command_line_args>
 {
-    rust_dom *dom;
+    rust_kernel *kernel;
+    rust_task *task;
     int argc;
     char **argv;
 
     // vec[str] passed to rust_task::start.
     rust_vec *args;
 
-    command_line_args(rust_dom *dom,
+    command_line_args(rust_task *task,
                       int sys_argc,
                       char **sys_argv)
-        : dom(dom),
+        : kernel(task->kernel),
+          task(task),
           argc(sys_argc),
           argv(sys_argv),
           args(NULL)
@@ -21,7 +23,7 @@ command_line_args : public dom_owned<command_line_args>
 #if defined(__WIN32__)
         LPCWSTR cmdline = GetCommandLineW();
         LPWSTR *wargv = CommandLineToArgvW(cmdline, &argc);
-        dom->win32_require("CommandLineToArgvW", wargv != NULL);
+        task->dom->win32_require("CommandLineToArgvW", wargv != NULL);
         argv = (char **) dom->malloc(sizeof(char*) * argc);
         for (int i = 0; i < argc; ++i) {
             int n_chars = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1,
@@ -36,14 +38,14 @@ command_line_args : public dom_owned<command_line_args>
 #endif
         size_t vec_fill = sizeof(rust_str *) * argc;
         size_t vec_alloc = next_power_of_two(sizeof(rust_vec) + vec_fill);
-        void *mem = dom->malloc(vec_alloc);
-        args = new (mem) rust_vec(dom, vec_alloc, 0, NULL);
+        void *mem = kernel->malloc(vec_alloc);
+        args = new (mem) rust_vec(task->dom, vec_alloc, 0, NULL);
         rust_str **strs = (rust_str**) &args->data[0];
         for (int i = 0; i < argc; ++i) {
             size_t str_fill = strlen(argv[i]) + 1;
             size_t str_alloc = next_power_of_two(sizeof(rust_str) + str_fill);
-            mem = dom->malloc(str_alloc);
-            strs[i] = new (mem) rust_str(dom, str_alloc, str_fill,
+            mem = kernel->malloc(str_alloc);
+            strs[i] = new (mem) rust_str(task->dom, str_alloc, str_fill,
                                          (uint8_t const *)argv[i]);
         }
         args->fill = vec_fill;
@@ -58,15 +60,15 @@ command_line_args : public dom_owned<command_line_args>
             // Drop the args we've had pinned here.
             rust_str **strs = (rust_str**) &args->data[0];
             for (int i = 0; i < argc; ++i)
-                dom->free(strs[i]);
-            dom->free(args);
+                kernel->free(strs[i]);
+            kernel->free(args);
         }
 
 #ifdef __WIN32__
         for (int i = 0; i < argc; ++i) {
-            dom->free(argv[i]);
+            task->free(argv[i]);
         }
-        dom->free(argv);
+        task->free(argv);
 #endif
     }
 };
@@ -97,7 +99,8 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) {
     rust_kernel *kernel = new rust_kernel(srv);
     kernel->start();
     rust_dom *dom = kernel->get_domain();
-    command_line_args *args = new (dom) command_line_args(dom, argc, argv);
+    command_line_args *args 
+        = new (kernel) command_line_args(dom->root_task, argc, argv);
 
     DLOG(dom, dom, "startup: %d args in 0x%" PRIxPTR,
              args->argc, (uintptr_t)args->args);
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index 2a724ee1791..76455d0ca99 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -42,7 +42,7 @@ last_os_error(rust_task *task) {
 #endif
     size_t fill = strlen(buf) + 1;
     size_t alloc = next_power_of_two(sizeof(rust_str) + fill);
-    void *mem = dom->malloc(alloc, memory_region::LOCAL);
+    void *mem = task->malloc(alloc, memory_region::LOCAL);
     if (!mem) {
         task->fail(1);
         return NULL;
@@ -73,7 +73,7 @@ rust_getcwd(rust_task *task) {
 
     size_t fill = strlen(cbuf) + 1;
     size_t alloc = next_power_of_two(sizeof(rust_str) + fill);
-    void *mem = dom->malloc(alloc, memory_region::LOCAL);
+    void *mem = task->malloc(alloc, memory_region::LOCAL);
     if (!mem) {
         task->fail(1);
         return NULL;
@@ -200,7 +200,7 @@ vec_alloc_with_data(rust_task *task,
 {
     rust_dom *dom = task->dom;
     size_t alloc = next_power_of_two(sizeof(rust_vec) + (n_elts * elt_size));
-    void *mem = dom->malloc(alloc, memory_region::LOCAL);
+    void *mem = task->malloc(alloc, memory_region::LOCAL);
     if (!mem) return NULL;
     return new (mem) rust_vec(dom, alloc, fill * elt_size, (uint8_t*)d);
 }
diff --git a/src/rt/rust_chan.cpp b/src/rt/rust_chan.cpp
index cc03c227acd..bf75c89057b 100644
--- a/src/rt/rust_chan.cpp
+++ b/src/rt/rust_chan.cpp
@@ -9,7 +9,7 @@ rust_chan::rust_chan(rust_task *task,
                      size_t unit_sz) :
                      task(task),
                      port(port),
-                     buffer(task->dom, unit_sz) {
+                     buffer(task, unit_sz) {
     ++task->ref_count;
     if (port) {
         associate(port);
diff --git a/src/rt/rust_crate_cache.cpp b/src/rt/rust_crate_cache.cpp
index 1f66e0e0084..70509dcae95 100644
--- a/src/rt/rust_crate_cache.cpp
+++ b/src/rt/rust_crate_cache.cpp
@@ -16,7 +16,7 @@ rust_crate_cache::get_type_desc(size_t size,
         return td;
     }
     DLOG(dom, cache, "rust_crate_cache::get_type_desc miss");
-    td = (type_desc*) dom->malloc(sizeof(type_desc) + keysz);
+    td = (type_desc*) dom->kernel->malloc(sizeof(type_desc) + keysz);
     if (!td)
         return NULL;
     // By convention, desc 0 is the root descriptor.
@@ -53,7 +53,7 @@ rust_crate_cache::flush() {
         type_desc *d = type_descs;
         HASH_DEL(type_descs, d);
         DLOG(dom, mem, "rust_crate_cache::flush() tydesc %" PRIxPTR, d);
-        dom->free(d);
+        dom->kernel->free(d);
     }
 }
 
diff --git a/src/rt/rust_dom.cpp b/src/rt/rust_dom.cpp
index 65ccf158b64..d89cb181fb8 100644
--- a/src/rt/rust_dom.cpp
+++ b/src/rt/rust_dom.cpp
@@ -10,8 +10,6 @@ rust_dom::rust_dom(rust_kernel *kernel,
     _log(srv, this),
     log_lvl(log_note),
     srv(srv),
-    local_region(&srv->local_region),
-    synchronized_region(&srv->synchronized_region),
     name(name),
     newborn_tasks(this, "newborn"),
     running_tasks(this, "running"),
@@ -36,6 +34,7 @@ rust_dom::rust_dom(rust_kernel *kernel,
 
 rust_dom::~rust_dom() {
     DLOG(this, dom, "~rust_dom %s @0x%" PRIxPTR, name, (uintptr_t)this);
+
     newborn_tasks.delete_all();
     running_tasks.delete_all();
     blocked_tasks.delete_all();
@@ -75,69 +74,6 @@ rust_dom::fail() {
     rval = 1;
 }
 
-void *
-rust_dom::malloc(size_t size) {
-    return malloc(size, memory_region::LOCAL);
-}
-
-void *
-rust_dom::malloc(size_t size, memory_region::memory_region_type type) {
-    if (type == memory_region::LOCAL) {
-        return local_region.malloc(size);
-    } else if (type == memory_region::SYNCHRONIZED) {
-        return synchronized_region.malloc(size);
-    }
-    I(this, false);
-    return NULL;
-}
-
-void *
-rust_dom::calloc(size_t size) {
-    return calloc(size, memory_region::LOCAL);
-}
-
-void *
-rust_dom::calloc(size_t size, memory_region::memory_region_type type) {
-    if (type == memory_region::LOCAL) {
-        return local_region.calloc(size);
-    } else if (type == memory_region::SYNCHRONIZED) {
-        return synchronized_region.calloc(size);
-    }
-    return NULL;
-}
-
-void *
-rust_dom::realloc(void *mem, size_t size) {
-    return realloc(mem, size, memory_region::LOCAL);
-}
-
-void *
-rust_dom::realloc(void *mem, size_t size,
-    memory_region::memory_region_type type) {
-    if (type == memory_region::LOCAL) {
-        return local_region.realloc(mem, size);
-    } else if (type == memory_region::SYNCHRONIZED) {
-        return synchronized_region.realloc(mem, size);
-    }
-    return NULL;
-}
-
-void
-rust_dom::free(void *mem) {
-    free(mem, memory_region::LOCAL);
-}
-
-void
-rust_dom::free(void *mem, memory_region::memory_region_type type) {
-    DLOG(this, mem, "rust_dom::free(0x%" PRIxPTR ")", mem);
-    if (type == memory_region::LOCAL) {
-        local_region.free(mem);
-    } else if (type == memory_region::SYNCHRONIZED) {
-        synchronized_region.free(mem);
-    }
-    return;
-}
-
 #ifdef __WIN32__
 void
 rust_dom::win32_require(LPCTSTR fn, BOOL ok) {
@@ -372,7 +308,7 @@ rust_dom::get_cache() {
 rust_task *
 rust_dom::create_task(rust_task *spawner, const char *name) {
     rust_task *task =
-        new (this) rust_task (this, &newborn_tasks, spawner, name);
+        new (this->kernel) rust_task (this, &newborn_tasks, spawner, name);
     DLOG(this, task, "created task: " PTR ", spawner: %s, name: %s",
                         task, spawner ? spawner->name : "null", name);
     newborn_tasks.append(task);
diff --git a/src/rt/rust_dom.h b/src/rt/rust_dom.h
index dfc0960a9ea..b936a0e580a 100644
--- a/src/rt/rust_dom.h
+++ b/src/rt/rust_dom.h
@@ -35,8 +35,6 @@ struct rust_dom : public kernel_owned<rust_dom>, rc_base<rust_dom>
     rust_log _log;
     uint32_t log_lvl;
     rust_srv *srv;
-    memory_region local_region;
-    memory_region synchronized_region;
     const char *const name;
 
     rust_task_list newborn_tasks;
@@ -74,15 +72,6 @@ struct rust_dom : public kernel_owned<rust_dom>, rc_base<rust_dom>
     void log(rust_task *task, uint32_t level, char const *fmt, ...);
     rust_log & get_log();
     void fail();
-    void *malloc(size_t size);
-    void *malloc(size_t size, memory_region::memory_region_type type);
-    void *calloc(size_t size);
-    void *calloc(size_t size, memory_region::memory_region_type type);
-    void *realloc(void *mem, size_t size);
-    void *realloc(void *mem, size_t size,
-        memory_region::memory_region_type type);
-    void free(void *mem);
-    void free(void *mem, memory_region::memory_region_type type);
 
     void drain_incoming_message_queue(bool process);
 
diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h
index cc494a26148..ac201fc799c 100644
--- a/src/rt/rust_internal.h
+++ b/src/rt/rust_internal.h
@@ -115,15 +115,9 @@ template <typename T> struct rc_base {
     ~rc_base();
 };
 
-template <typename T> struct dom_owned {
-    void operator delete(void *ptr) {
-        ((T *)ptr)->dom->free(ptr);
-    }
-};
-
 template <typename T> struct task_owned {
     void operator delete(void *ptr) {
-        ((T *)ptr)->task->dom->free(ptr);
+        ((T *)ptr)->task->free(ptr);
     }
 };
 
@@ -148,14 +142,14 @@ struct rust_cond { };
 
 // Helper class used regularly elsewhere.
 
-template <typename T> class ptr_vec : public dom_owned<ptr_vec<T> > {
+template <typename T> class ptr_vec : public task_owned<ptr_vec<T> > {
     static const size_t INIT_SIZE = 8;
-    rust_dom *dom;
+    rust_task *task;
     size_t alloc;
     size_t fill;
     T **data;
 public:
-    ptr_vec(rust_dom *dom);
+    ptr_vec(rust_task *task);
     ~ptr_vec();
 
     size_t length() {
@@ -181,7 +175,6 @@ public:
 #include "rust_kernel.h"
 #include "rust_message.h"
 #include "rust_dom.h"
-#include "memory.h"
 
 struct rust_timer {
     // FIXME: This will probably eventually need replacement
@@ -250,35 +243,11 @@ rust_alarm
 typedef ptr_vec<rust_alarm> rust_wait_queue;
 
 
-struct stk_seg {
-    unsigned int valgrind_id;
-    uintptr_t limit;
-    uint8_t data[];
-};
-
-struct frame_glue_fns {
-    uintptr_t mark_glue_off;
-    uintptr_t drop_glue_off;
-    uintptr_t reloc_glue_off;
-};
-
-struct gc_alloc {
-    gc_alloc *prev;
-    gc_alloc *next;
-    uintptr_t ctrl_word;
-    uint8_t data[];
-    bool mark() {
-        if (ctrl_word & 1)
-            return false;
-        ctrl_word |= 1;
-        return true;
-    }
-};
-
 #include "circular_buffer.h"
 #include "rust_task.h"
 #include "rust_chan.h"
 #include "rust_port.h"
+#include "memory.h"
 
 //
 // Local Variables:
diff --git a/src/rt/rust_kernel.h b/src/rt/rust_kernel.h
index ee5cf99ef5d..5e03d8072d6 100644
--- a/src/rt/rust_kernel.h
+++ b/src/rt/rust_kernel.h
@@ -116,15 +116,6 @@ public:
     int start_task_threads(int num_threads);
 };
 
-inline void *operator new(size_t size, rust_kernel *kernel) {
-    return kernel->malloc(size);
-}
-
-inline void *operator new(size_t size, rust_kernel &kernel) {
-    return kernel.malloc(size);
-}
-
-
 class rust_task_thread : public rust_thread {
     int id;
     rust_kernel *owner;
diff --git a/src/rt/rust_message.cpp b/src/rt/rust_message.cpp
index 19a1d8a367e..6d1b7c528d2 100644
--- a/src/rt/rust_message.cpp
+++ b/src/rt/rust_message.cpp
@@ -109,9 +109,10 @@ void data_message::kernel_process() {
 
 }
 
-rust_message_queue::rust_message_queue(rust_srv *srv, rust_kernel *kernel) :
-                                       region (srv, true), kernel(kernel),
-                                       dom_handle(NULL) {
+rust_message_queue::rust_message_queue(rust_srv *srv, rust_kernel *kernel) 
+    : region(srv, true),
+      kernel(kernel),
+      dom_handle(NULL) {
     // Nop.
 }
 
diff --git a/src/rt/rust_port.cpp b/src/rt/rust_port.cpp
index 57d0b216836..a2bd3b34c38 100644
--- a/src/rt/rust_port.cpp
+++ b/src/rt/rust_port.cpp
@@ -3,14 +3,14 @@
 
 rust_port::rust_port(rust_task *task, size_t unit_sz) :
                      maybe_proxy<rust_port>(this), task(task),
-                     unit_sz(unit_sz), writers(task->dom), chans(task->dom) {
+                     unit_sz(unit_sz), writers(task), chans(task) {
 
     LOG(task, comm,
         "new rust_port(task=0x%" PRIxPTR ", unit_sz=%d) -> port=0x%"
         PRIxPTR, (uintptr_t)task, unit_sz, (uintptr_t)this);
 
     // Allocate a remote channel, for remote channel data.
-    remote_channel = new (task->dom) rust_chan(task, this, unit_sz);
+    remote_channel = new (task) rust_chan(task, this, unit_sz);
 }
 
 rust_port::~rust_port() {
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp
index 325bb560502..52987c68d64 100644
--- a/src/rt/rust_task.cpp
+++ b/src/rt/rust_task.cpp
@@ -20,16 +20,16 @@ static size_t const min_stk_bytes = 0x100000;
 // Task stack segments. Heap allocated and chained together.
 
 static stk_seg*
-new_stk(rust_dom *dom, size_t minsz)
+new_stk(rust_task *task, size_t minsz)
 {
     if (minsz < min_stk_bytes)
         minsz = min_stk_bytes;
     size_t sz = sizeof(stk_seg) + minsz;
-    stk_seg *stk = (stk_seg *)dom->malloc(sz);
-    LOGPTR(dom, "new stk", (uintptr_t)stk);
+    stk_seg *stk = (stk_seg *)task->malloc(sz);
+    LOGPTR(task->dom, "new stk", (uintptr_t)stk);
     memset(stk, 0, sizeof(stk_seg));
     stk->limit = (uintptr_t) &stk->data[minsz];
-    LOGPTR(dom, "stk limit", stk->limit);
+    LOGPTR(task->dom, "stk limit", stk->limit);
     stk->valgrind_id =
         VALGRIND_STACK_REGISTER(&stk->data[0],
                                 &stk->data[minsz]);
@@ -37,11 +37,11 @@ new_stk(rust_dom *dom, size_t minsz)
 }
 
 static void
-del_stk(rust_dom *dom, stk_seg *stk)
+del_stk(rust_task *task, stk_seg *stk)
 {
     VALGRIND_STACK_DEREGISTER(stk->valgrind_id);
-    LOGPTR(dom, "freeing stk segment", (uintptr_t)stk);
-    dom->free(stk);
+    LOGPTR(task->dom, "freeing stk segment", (uintptr_t)stk);
+    task->free(stk);
 }
 
 // Tasks
@@ -55,9 +55,9 @@ size_t const callee_save_fp = 0;
 rust_task::rust_task(rust_dom *dom, rust_task_list *state,
                      rust_task *spawner, const char *name) :
     maybe_proxy<rust_task>(this),
-    stk(new_stk(dom, 0)),
+    stk(NULL),
     runtime_sp(0),
-    rust_sp(stk->limit),
+    rust_sp(NULL),
     gc_alloc_chain(0),
     dom(dom),
     cache(NULL),
@@ -69,13 +69,17 @@ rust_task::rust_task(rust_dom *dom, rust_task_list *state,
     supervisor(spawner),
     list_index(-1),
     rendezvous_ptr(0),
-    alarm(this),
     handle(NULL),
-    active(false)
+    active(false),
+    local_region(&dom->srv->local_region),
+    synchronized_region(&dom->srv->synchronized_region)
 {
     LOGPTR(dom, "new task", (uintptr_t)this);
     DLOG(dom, task, "sizeof(task) = %d (0x%x)", sizeof *this, sizeof *this);
 
+    stk = new_stk(this, 0);
+    rust_sp = stk->limit;
+
     if (spawner == NULL) {
         ref_count = 0;
     }
@@ -111,7 +115,7 @@ rust_task::~rust_task()
     I(dom, ref_count == 0 ||
       (ref_count == 1 && this == dom->root_task));
 
-    del_stk(dom, stk);
+    del_stk(this, stk);
 }
 
 extern "C" void rust_new_exit_task_glue();
@@ -352,7 +356,7 @@ rust_task::malloc(size_t sz, type_desc *td)
     if (td) {
         sz += sizeof(gc_alloc);
     }
-    void *mem = dom->malloc(sz);
+    void *mem = malloc(sz, memory_region::LOCAL);
     if (!mem)
         return mem;
     if (td) {
@@ -379,7 +383,7 @@ rust_task::realloc(void *data, size_t sz, bool is_gc)
         gc_alloc *gcm = (gc_alloc*)(((char *)data) - sizeof(gc_alloc));
         unlink_gc(gcm);
         sz += sizeof(gc_alloc);
-        gcm = (gc_alloc*) dom->realloc((void*)gcm, sz);
+        gcm = (gc_alloc*) realloc((void*)gcm, sz, memory_region::LOCAL);
         DLOG(dom, task, "task %s @0x%" PRIxPTR
              " reallocated %d GC bytes = 0x%" PRIxPTR,
              name, (uintptr_t)this, sz, gcm);
@@ -388,7 +392,7 @@ rust_task::realloc(void *data, size_t sz, bool is_gc)
         link_gc(gcm);
         data = (void*) &(gcm->data);
     } else {
-        data = dom->realloc(data, sz);
+        data = realloc(data, sz, memory_region::LOCAL);
     }
     return data;
 }
@@ -405,9 +409,9 @@ rust_task::free(void *p, bool is_gc)
         DLOG(dom, mem,
              "task %s @0x%" PRIxPTR " freeing GC memory = 0x%" PRIxPTR,
              name, (uintptr_t)this, gcm);
-        dom->free(gcm);
+        free(gcm, memory_region::LOCAL);
     } else {
-        dom->free(p);
+        free(p, memory_region::LOCAL);
     }
 }
 
@@ -492,6 +496,54 @@ bool rust_task::can_schedule()
     return yield_timer.has_timed_out() && !active;
 }
 
+void *
+rust_task::malloc(size_t size, memory_region::memory_region_type type) {
+    if (type == memory_region::LOCAL) {
+        return local_region.malloc(size);
+    } else if (type == memory_region::SYNCHRONIZED) {
+        return synchronized_region.malloc(size);
+    }
+    I(dom, false);
+    return NULL;
+}
+
+void *
+rust_task::calloc(size_t size) {
+    return calloc(size, memory_region::LOCAL);
+}
+
+void *
+rust_task::calloc(size_t size, memory_region::memory_region_type type) {
+    if (type == memory_region::LOCAL) {
+        return local_region.calloc(size);
+    } else if (type == memory_region::SYNCHRONIZED) {
+        return synchronized_region.calloc(size);
+    }
+    return NULL;
+}
+
+void *
+rust_task::realloc(void *mem, size_t size,
+    memory_region::memory_region_type type) {
+    if (type == memory_region::LOCAL) {
+        return local_region.realloc(mem, size);
+    } else if (type == memory_region::SYNCHRONIZED) {
+        return synchronized_region.realloc(mem, size);
+    }
+    return NULL;
+}
+
+void
+rust_task::free(void *mem, memory_region::memory_region_type type) {
+    DLOG(dom, mem, "rust_task::free(0x%" PRIxPTR ")", mem);
+    if (type == memory_region::LOCAL) {
+        local_region.free(mem);
+    } else if (type == memory_region::SYNCHRONIZED) {
+        synchronized_region.free(mem);
+    }
+    return;
+}
+
 //
 // Local Variables:
 // mode: C++
diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h
index 62a725a98d5..5e61306af2e 100644
--- a/src/rt/rust_task.h
+++ b/src/rt/rust_task.h
@@ -9,9 +9,34 @@
 
 #include "context.h"
 
+struct stk_seg {
+    unsigned int valgrind_id;
+    uintptr_t limit;
+    uint8_t data[];
+};
+
+struct frame_glue_fns {
+    uintptr_t mark_glue_off;
+    uintptr_t drop_glue_off;
+    uintptr_t reloc_glue_off;
+};
+
+struct gc_alloc {
+    gc_alloc *prev;
+    gc_alloc *next;
+    uintptr_t ctrl_word;
+    uint8_t data[];
+    bool mark() {
+        if (ctrl_word & 1)
+            return false;
+        ctrl_word |= 1;
+        return true;
+    }
+};
+
 struct
 rust_task : public maybe_proxy<rust_task>,
-            public dom_owned<rust_task>
+            public kernel_owned<rust_task>
 {
     // Fields known to the compiler.
     stk_seg *stk;
@@ -46,8 +71,6 @@ rust_task : public maybe_proxy<rust_task>,
     // List of tasks waiting for this task to finish.
     array_list<maybe_proxy<rust_task> *> tasks_waiting_to_join;
 
-    rust_alarm alarm;
-
     rust_handle<rust_task> *handle;
 
     context ctx;
@@ -56,6 +79,9 @@ rust_task : public maybe_proxy<rust_task>,
     // or is about to run this task.
     volatile bool active;
 
+    memory_region local_region;
+    memory_region synchronized_region;
+
     // Only a pointer to 'name' is kept, so it must live as long as this task.
     rust_task(rust_dom *dom,
               rust_task_list *state,
@@ -118,6 +144,13 @@ rust_task : public maybe_proxy<rust_task>,
     rust_crate_cache * get_crate_cache();
 
     bool can_schedule();
+
+    void *malloc(size_t size, memory_region::memory_region_type type);
+    void *calloc(size_t size);
+    void *calloc(size_t size, memory_region::memory_region_type type);
+    void *realloc(void *mem, size_t size,
+        memory_region::memory_region_type type);
+    void free(void *mem, memory_region::memory_region_type type);
 };
 
 //
diff --git a/src/rt/rust_task_list.h b/src/rt/rust_task_list.h
index b1fba75029d..479f9e936fb 100644
--- a/src/rt/rust_task_list.h
+++ b/src/rt/rust_task_list.h
@@ -1,3 +1,4 @@
+// -*- c++-mode -*-
 #ifndef RUST_TASK_LIST_H
 #define RUST_TASK_LIST_H
 
@@ -5,7 +6,7 @@
  * Used to indicate the state of a rust task.
  */
 class rust_task_list : public indexed_list<rust_task>,
-                       public dom_owned<rust_task_list> {
+                       public kernel_owned<rust_task_list> {
 public:
     rust_dom *dom;
     const char* name;
diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp
index ccb35958a80..ce349b18e9d 100644
--- a/src/rt/rust_upcall.cpp
+++ b/src/rt/rust_upcall.cpp
@@ -74,11 +74,10 @@ upcall_trace_str(rust_task *task, char const *c) {
 extern "C" CDECL rust_port*
 upcall_new_port(rust_task *task, size_t unit_sz) {
     LOG_UPCALL_ENTRY(task);
-    rust_dom *dom = task->dom;
     scoped_lock with(task->kernel->scheduler_lock);
     LOG(task, comm, "upcall_new_port(task=0x%" PRIxPTR " (%s), unit_sz=%d)",
         (uintptr_t) task, task->name, unit_sz);
-    return new (dom) rust_port(task, unit_sz);
+    return new (task) rust_port(task, unit_sz);
 }
 
 extern "C" CDECL void
@@ -101,7 +100,7 @@ upcall_new_chan(rust_task *task, rust_port *port) {
         "task=0x%" PRIxPTR " (%s), port=0x%" PRIxPTR ")",
         (uintptr_t) task, task->name, port);
     I(dom, port);
-    return new (dom) rust_chan(task, port, port->unit_sz);
+    return new (task) rust_chan(task, port, port->unit_sz);
 }
 
 /**
@@ -181,7 +180,7 @@ upcall_clone_chan(rust_task *task, maybe_proxy<rust_task> *target,
         port = proxy;
         target_task = target->as_proxy()->handle()->referent();
     }
-    return new (target_task->dom) rust_chan(target_task, port, unit_sz);
+    return new (target_task) rust_chan(target_task, port, unit_sz);
 }
 
 extern "C" CDECL void
diff --git a/src/rt/rust_util.h b/src/rt/rust_util.h
index fe3c2459966..260f7eb9d5d 100644
--- a/src/rt/rust_util.h
+++ b/src/rt/rust_util.h
@@ -1,6 +1,8 @@
 #ifndef RUST_UTIL_H
 #define RUST_UTIL_H
 
+#include "rust_task.h"
+
 // Reference counted objects
 
 template <typename T>
@@ -17,30 +19,30 @@ rc_base<T>::~rc_base()
 // Utility type: pointer-vector.
 
 template <typename T>
-ptr_vec<T>::ptr_vec(rust_dom *dom) :
-    dom(dom),
+ptr_vec<T>::ptr_vec(rust_task *task) :
+    task(task),
     alloc(INIT_SIZE),
     fill(0),
-    data(new (dom) T*[alloc])
+    data(new (task) T*[alloc])
 {
-    I(dom, data);
-    DLOG(dom, mem, "new ptr_vec(data=0x%" PRIxPTR ") -> 0x%" PRIxPTR,
+    I(task->dom, data);
+    DLOG(task->dom, mem, "new ptr_vec(data=0x%" PRIxPTR ") -> 0x%" PRIxPTR,
          (uintptr_t)data, (uintptr_t)this);
 }
 
 template <typename T>
 ptr_vec<T>::~ptr_vec()
 {
-    I(dom, data);
-    DLOG(dom, mem, "~ptr_vec 0x%" PRIxPTR ", data=0x%" PRIxPTR,
+    I(task->dom, data);
+    DLOG(task->dom, mem, "~ptr_vec 0x%" PRIxPTR ", data=0x%" PRIxPTR,
          (uintptr_t)this, (uintptr_t)data);
-    I(dom, fill == 0);
-    dom->free(data);
+    I(task->dom, fill == 0);
+    task->free(data);
 }
 
 template <typename T> T *&
 ptr_vec<T>::operator[](size_t offset) {
-    I(dom, data[offset]->idx == offset);
+    I(task->dom, data[offset]->idx == offset);
     return data[offset];
 }
 
@@ -48,14 +50,14 @@ template <typename T>
 void
 ptr_vec<T>::push(T *p)
 {
-    I(dom, data);
-    I(dom, fill <= alloc);
+    I(task->dom, data);
+    I(task->dom, fill <= alloc);
     if (fill == alloc) {
         alloc *= 2;
-        data = (T **)dom->realloc(data, alloc * sizeof(T*));
-        I(dom, data);
+        data = (T **)task->realloc(data, alloc * sizeof(T*));
+        I(task->dom, data);
     }
-    I(dom, fill < alloc);
+    I(task->dom, fill < alloc);
     p->idx = fill;
     data[fill++] = p;
 }
@@ -78,13 +80,13 @@ template <typename T>
 void
 ptr_vec<T>::trim(size_t sz)
 {
-    I(dom, data);
+    I(task->dom, data);
     if (sz <= (alloc / 4) &&
         (alloc / 2) >= INIT_SIZE) {
         alloc /= 2;
-        I(dom, alloc >= fill);
-        data = (T **)dom->realloc(data, alloc * sizeof(T*));
-        I(dom, data);
+        I(task->dom, alloc >= fill);
+        data = (T **)task->realloc(data, alloc * sizeof(T*));
+        I(task->dom, data);
     }
 }
 
@@ -93,9 +95,9 @@ void
 ptr_vec<T>::swap_delete(T *item)
 {
     /* Swap the endpoint into i and decr fill. */
-    I(dom, data);
-    I(dom, fill > 0);
-    I(dom, item->idx < fill);
+    I(task->dom, data);
+    I(task->dom, fill > 0);
+    I(task->dom, item->idx < fill);
     fill--;
     if (fill > 0) {
         T *subst = data[fill];
@@ -155,7 +157,8 @@ isaac_init(rust_dom *dom, randctx *rctx)
         } else {
             int fd = open("/dev/urandom", O_RDONLY);
             I(dom, fd > 0);
-            I(dom, read(fd, (void*) &rctx->randrsl, sizeof(rctx->randrsl))
+            I(dom, 
+              read(fd, (void*) &rctx->randrsl, sizeof(rctx->randrsl))
               == sizeof(rctx->randrsl));
             I(dom, close(fd) == 0);
         }
diff --git a/src/test/run-pass/child-outlives-parent.rs b/src/test/run-pass/child-outlives-parent.rs
index 988172ba6ad..9cd3b67821b 100644
--- a/src/test/run-pass/child-outlives-parent.rs
+++ b/src/test/run-pass/child-outlives-parent.rs
@@ -2,6 +2,8 @@
 
 
 // xfail-stage0
+// xfail-stage1
+// xfail-stage2
 // Reported as issue #126, child leaks the string.
 fn child2(str s) { }
 
diff --git a/src/test/run-pass/spawn-types.rs b/src/test/run-pass/spawn-types.rs
index 4bbeb3c064f..0051b2ba14d 100644
--- a/src/test/run-pass/spawn-types.rs
+++ b/src/test/run-pass/spawn-types.rs
@@ -5,6 +5,8 @@
  */
 
 // xfail-stage0
+// xfail-stage1
+// xfail-stage2
 
 use std;
 
diff --git a/src/test/run-pass/task-life-0.rs b/src/test/run-pass/task-life-0.rs
index 324572344a4..726dfa261e0 100644
--- a/src/test/run-pass/task-life-0.rs
+++ b/src/test/run-pass/task-life-0.rs
@@ -1,4 +1,6 @@
 // xfail-stage0
+// xfail-stage1
+// xfail-stage2
 fn main() -> () {
     spawn child("Hello");
 }