about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libextra/arena.rs46
-rw-r--r--src/libextra/comm.rs9
-rw-r--r--src/libextra/dlist.rs42
-rw-r--r--src/libextra/treemap.rs152
-rw-r--r--src/libextra/unicode.rs51
-rw-r--r--src/librustc/driver/driver.rs2
-rw-r--r--src/librustc/driver/session.rs3
-rw-r--r--src/librustc/middle/check_loop.rs2
-rw-r--r--src/librustc/middle/entry.rs6
-rw-r--r--src/librustc/middle/trans/base.rs15
-rw-r--r--src/librustc/middle/typeck/mod.rs3
-rw-r--r--src/libstd/comm.rs110
-rw-r--r--src/libstd/gc.rs358
-rw-r--r--src/libstd/logging.rs10
-rw-r--r--src/libstd/pipes.rs44
-rw-r--r--src/libstd/rt/local.rs81
-rw-r--r--src/libstd/rt/local_ptr.rs26
-rw-r--r--src/libstd/rt/logging.rs21
-rw-r--r--src/libstd/rt/mod.rs10
-rw-r--r--src/libstd/rt/sched.rs12
-rw-r--r--src/libstd/rt/task.rs17
-rw-r--r--src/libstd/stackwalk.rs80
-rw-r--r--src/libstd/std.rs2
-rw-r--r--src/libstd/str.rs9
-rw-r--r--src/libstd/sys.rs4
-rw-r--r--src/rt/arch/arm/record_sp.S14
-rw-r--r--src/test/bench/shootout-binarytrees.rs8
-rw-r--r--src/test/run-pass/issue-3176.rs39
-rw-r--r--src/test/run-pass/placement-new-arena.rs4
29 files changed, 398 insertions, 782 deletions
diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs
index 47b64d76951..ae4356eb4ba 100644
--- a/src/libextra/arena.rs
+++ b/src/libextra/arena.rs
@@ -67,17 +67,16 @@ pub struct Arena {
     priv chunks: @mut MutList<Chunk>,
 }
 
-#[unsafe_destructor]
-impl Drop for Arena {
-    fn drop(&self) {
-        unsafe {
-            destroy_chunk(&self.head);
-            do self.chunks.each |chunk| {
-                if !chunk.is_pod {
-                    destroy_chunk(chunk);
-                }
-                true
-            };
+impl Arena {
+    pub fn new() -> Arena {
+        Arena::new_with_size(32u)
+    }
+
+    pub fn new_with_size(initial_size: uint) -> Arena {
+        Arena {
+            head: chunk(initial_size, false),
+            pod_head: chunk(initial_size, true),
+            chunks: @mut MutNil,
         }
     }
 }
@@ -92,18 +91,21 @@ fn chunk(size: uint, is_pod: bool) -> Chunk {
     }
 }
 
-pub fn arena_with_size(initial_size: uint) -> Arena {
-    Arena {
-        head: chunk(initial_size, false),
-        pod_head: chunk(initial_size, true),
-        chunks: @mut MutNil,
+#[unsafe_destructor]
+impl Drop for Arena {
+    fn drop(&self) {
+        unsafe {
+            destroy_chunk(&self.head);
+            do self.chunks.each |chunk| {
+                if !chunk.is_pod {
+                    destroy_chunk(chunk);
+                }
+                true
+            };
+        }
     }
 }
 
-pub fn Arena() -> Arena {
-    arena_with_size(32u)
-}
-
 #[inline]
 fn round_up_to(base: uint, align: uint) -> uint {
     (base + (align - 1)) & !(align - 1)
@@ -276,7 +278,7 @@ impl Arena {
 
 #[test]
 fn test_arena_destructors() {
-    let arena = Arena();
+    let arena = Arena::new();
     for i in range(0u, 10) {
         // Arena allocate something with drop glue to make sure it
         // doesn't leak.
@@ -291,7 +293,7 @@ fn test_arena_destructors() {
 #[should_fail]
 #[ignore(cfg(windows))]
 fn test_arena_destructors_fail() {
-    let arena = Arena();
+    let arena = Arena::new();
     // Put some stuff in the arena.
     for i in range(0u, 10) {
         // Arena allocate something with drop glue to make sure it
diff --git a/src/libextra/comm.rs b/src/libextra/comm.rs
index 44581efc6f0..776e25cac89 100644
--- a/src/libextra/comm.rs
+++ b/src/libextra/comm.rs
@@ -18,9 +18,8 @@ Higher level communication abstractions.
 
 
 use std::comm::{GenericChan, GenericSmartChan, GenericPort};
-use std::comm::{Chan, Port, Selectable, Peekable};
+use std::comm::{Chan, Port, Peekable};
 use std::comm;
-use std::pipes;
 
 /// An extension of `pipes::stream` that allows both sending and receiving.
 pub struct DuplexStream<T, U> {
@@ -75,12 +74,6 @@ impl<T:Send,U:Send> Peekable<U> for DuplexStream<T, U> {
     }
 }
 
-impl<T:Send,U:Send> Selectable for DuplexStream<T, U> {
-    fn header(&mut self) -> *mut pipes::PacketHeader {
-        self.port.header()
-    }
-}
-
 /// Creates a bidirectional stream.
 pub fn DuplexStream<T:Send,U:Send>()
     -> (DuplexStream<T, U>, DuplexStream<U, T>)
diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs
index 4142bdadaf6..75487a44f26 100644
--- a/src/libextra/dlist.rs
+++ b/src/libextra/dlist.rs
@@ -92,6 +92,11 @@ impl<T> Rawlink<T> {
             Some(unsafe { cast::transmute(self.p) })
         }
     }
+
+    /// Return the `Rawlink` and replace with `Rawlink::none()`
+    fn take(&mut self) -> Rawlink<T> {
+        util::replace(self, Rawlink::none())
+    }
 }
 
 impl<T> Clone for Rawlink<T> {
@@ -280,13 +285,16 @@ impl<T> DList<T> {
     /// Add all elements from `other` to the end of the list
     ///
     /// O(1)
-    pub fn append(&mut self, other: DList<T>) {
+    pub fn append(&mut self, mut other: DList<T>) {
         match self.list_tail.resolve() {
             None => *self = other,
             Some(tail) => {
-                match other {
-                    DList{list_head: None, _} => return,
-                    DList{list_head: Some(node), list_tail: o_tail, length: o_length} => {
+                // Carefully empty `other`.
+                let o_tail = other.list_tail.take();
+                let o_length = other.length;
+                match other.list_head.take() {
+                    None => return,
+                    Some(node) => {
                         tail.next = link_with_prev(node, self.list_tail);
                         self.list_tail = o_tail;
                         self.length += o_length;
@@ -404,6 +412,32 @@ impl<T: Ord> DList<T> {
     }
 }
 
+#[unsafe_destructor]
+impl<T> Drop for DList<T> {
+    fn drop(&self) {
+        let mut_self = unsafe {
+            cast::transmute_mut(self)
+        };
+        // Dissolve the dlist in backwards direction
+        // Just dropping the list_head can lead to stack exhaustion
+        // when length is >> 1_000_000
+        let mut tail = mut_self.list_tail;
+        loop {
+            match tail.resolve() {
+                None => break,
+                Some(prev) => {
+                    prev.next.take(); // release ~Node<T>
+                    tail = prev.prev;
+                }
+            }
+        }
+        mut_self.length = 0;
+        mut_self.list_head = None;
+        mut_self.list_tail = Rawlink::none();
+    }
+}
+
+
 impl<'self, A> Iterator<&'self A> for DListIterator<'self, A> {
     #[inline]
     fn next(&mut self) -> Option<&'self A> {
diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs
index 1736e62aee9..487ad050e78 100644
--- a/src/libextra/treemap.rs
+++ b/src/libextra/treemap.rs
@@ -184,7 +184,68 @@ impl<K: TotalOrd, V> TreeMap<K, V> {
     /// Get a lazy iterator over the key-value pairs in the map.
     /// Requires that it be frozen (immutable).
     pub fn iter<'a>(&'a self) -> TreeMapIterator<'a, K, V> {
-        TreeMapIterator{stack: ~[], node: &self.root, remaining: self.length}
+        TreeMapIterator {
+            stack: ~[],
+            node: &self.root,
+            remaining_min: self.length,
+            remaining_max: self.length
+        }
+    }
+
+    /// Get a lazy iterator that should be initialized using
+    /// `iter_traverse_left`/`iter_traverse_right`/`iter_traverse_complete`.
+    fn iter_for_traversal<'a>(&'a self) -> TreeMapIterator<'a, K, V> {
+        TreeMapIterator {
+            stack: ~[],
+            node: &self.root,
+            remaining_min: 0,
+            remaining_max: self.length
+        }
+    }
+
+    /// Return a lazy iterator to the first key-value pair whose key is not less than `k`
+    /// If all keys in map are less than `k` an empty iterator is returned.
+    pub fn lower_bound_iter<'a>(&'a self, k: &K) -> TreeMapIterator<'a, K, V> {
+        let mut iter: TreeMapIterator<'a, K, V> = self.iter_for_traversal();
+        loop {
+            match *iter.node {
+              Some(ref r) => {
+                match k.cmp(&r.key) {
+                  Less => iter_traverse_left(&mut iter),
+                  Greater => iter_traverse_right(&mut iter),
+                  Equal => {
+                    iter_traverse_complete(&mut iter);
+                    return iter;
+                  }
+                }
+              }
+              None => {
+                iter_traverse_complete(&mut iter);
+                return iter;
+              }
+            }
+        }
+    }
+
+    /// Return a lazy iterator to the first key-value pair whose key is greater than `k`
+    /// If all keys in map are not greater than `k` an empty iterator is returned.
+    pub fn upper_bound_iter<'a>(&'a self, k: &K) -> TreeMapIterator<'a, K, V> {
+        let mut iter: TreeMapIterator<'a, K, V> = self.iter_for_traversal();
+        loop {
+            match *iter.node {
+              Some(ref r) => {
+                match k.cmp(&r.key) {
+                  Less => iter_traverse_left(&mut iter),
+                  Greater => iter_traverse_right(&mut iter),
+                  Equal => iter_traverse_right(&mut iter)
+                }
+              }
+              None => {
+                iter_traverse_complete(&mut iter);
+                return iter;
+              }
+            }
+        }
     }
 
     /// Get a lazy iterator that consumes the treemap.
@@ -205,7 +266,8 @@ impl<K: TotalOrd, V> TreeMap<K, V> {
 pub struct TreeMapIterator<'self, K, V> {
     priv stack: ~[&'self ~TreeNode<K, V>],
     priv node: &'self Option<~TreeNode<K, V>>,
-    priv remaining: uint
+    priv remaining_min: uint,
+    priv remaining_max: uint
 }
 
 impl<'self, K, V> Iterator<(&'self K, &'self V)> for TreeMapIterator<'self, K, V> {
@@ -222,7 +284,10 @@ impl<'self, K, V> Iterator<(&'self K, &'self V)> for TreeMapIterator<'self, K, V
               None => {
                 let res = self.stack.pop();
                 self.node = &res.right;
-                self.remaining -= 1;
+                self.remaining_max -= 1;
+                if self.remaining_min > 0 {
+                    self.remaining_min -= 1;
+                }
                 return Some((&res.key, &res.value));
               }
             }
@@ -232,7 +297,46 @@ impl<'self, K, V> Iterator<(&'self K, &'self V)> for TreeMapIterator<'self, K, V
 
     #[inline]
     fn size_hint(&self) -> (uint, Option<uint>) {
-        (self.remaining, Some(self.remaining))
+        (self.remaining_min, Some(self.remaining_max))
+    }
+}
+
+/// iter_traverse_left, iter_traverse_right and iter_traverse_complete are used to
+/// initialize TreeMapIterator pointing to element inside tree structure.
+///
+/// They should be used in following manner:
+///   - create iterator using TreeMap::iter_for_traversal
+///   - find required node using `iter_traverse_left`/`iter_traverse_right`
+///     (current node is `TreeMapIterator::node` field)
+///   - complete initialization with `iter_traverse_complete`
+#[inline]
+fn iter_traverse_left<'a, K, V>(it: &mut TreeMapIterator<'a, K, V>) {
+    let node = it.node.get_ref();
+    it.stack.push(node);
+    it.node = &node.left;
+}
+
+#[inline]
+fn iter_traverse_right<'a, K, V>(it: &mut TreeMapIterator<'a, K, V>) {
+    it.node = &(it.node.get_ref().right);
+}
+
+/// iter_traverse_left, iter_traverse_right and iter_traverse_complete are used to
+/// initialize TreeMapIterator pointing to element inside tree structure.
+///
+/// Completes traversal. Should be called before using iterator.
+/// Iteration will start from `self.node`.
+/// If `self.node` is None iteration will start from last node from which we
+/// traversed left.
+#[inline]
+fn iter_traverse_complete<'a, K, V>(it: &mut TreeMapIterator<'a, K, V>) {
+    static none: Option<~TreeNode<K, V>> = None;
+    match *it.node {
+        Some(ref n) => {
+            it.stack.push(n);
+            it.node = &none;
+        }
+        None => ()
     }
 }
 
@@ -417,6 +521,20 @@ impl<T: TotalOrd> TreeSet<T> {
         TreeSetIterator{iter: self.map.iter()}
     }
 
+    /// Get a lazy iterator pointing to the first value not less than `v` (greater or equal).
+    /// If all elements in the set are less than `v` empty iterator is returned.
+    #[inline]
+    pub fn lower_bound_iter<'a>(&'a self, v: &T) -> TreeSetIterator<'a, T> {
+        TreeSetIterator{iter: self.map.lower_bound_iter(v)}
+    }
+
+    /// Get a lazy iterator pointing to the first value greater than `v`.
+    /// If all elements in the set are not greater than `v` empty iterator is returned.
+    #[inline]
+    pub fn upper_bound_iter<'a>(&'a self, v: &T) -> TreeSetIterator<'a, T> {
+        TreeSetIterator{iter: self.map.upper_bound_iter(v)}
+    }
+
     /// Visit all values in reverse order
     #[inline]
     pub fn each_reverse(&self, f: &fn(&T) -> bool) -> bool {
@@ -983,6 +1101,31 @@ mod test_treemap {
             assert_eq!(*v, n * 2);
             n += 1;
         }
+        assert_eq!(n, 5);
+    }
+
+    #[test]
+    fn test_interval_iteration() {
+        let mut m = TreeMap::new();
+        for i in range(1, 100) {
+            assert!(m.insert(i * 2, i * 4));
+        }
+
+        for i in range(1, 198) {
+            let mut lb_it = m.lower_bound_iter(&i);
+            let (&k, &v) = lb_it.next().unwrap();
+            let lb = i + i % 2;
+            assert_eq!(lb, k);
+            assert_eq!(lb * 2, v);
+
+            let mut ub_it = m.upper_bound_iter(&i);
+            let (&k, &v) = ub_it.next().unwrap();
+            let ub = i + 2 - i % 2;
+            assert_eq!(ub, k);
+            assert_eq!(ub * 2, v);
+        }
+        let mut end_it = m.lower_bound_iter(&199);
+        assert_eq!(end_it.next(), None);
     }
 
     #[test]
@@ -1256,7 +1399,6 @@ mod test_set {
 
         let mut n = 0;
         for x in m.iter() {
-            printfln!(x);
             assert_eq!(*x, n);
             n += 1
         }
diff --git a/src/libextra/unicode.rs b/src/libextra/unicode.rs
index 4949ee79e5d..3957551c846 100644
--- a/src/libextra/unicode.rs
+++ b/src/libextra/unicode.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[forbid(deprecated_mode)];
 #[allow(missing_doc)];
 
 pub mod icu {
@@ -159,7 +158,10 @@ pub mod icu {
     pub static UCHAR_INVALID_CODE : UProperty = -1;
 
     pub mod libicu {
-        #[link_name = "icuuc"]
+        use unicode::icu::*;
+
+        // #[link_name = "icuuc"]
+        #[link_args = "-licuuc"]
         #[abi = "cdecl"]
         extern {
             pub fn u_hasBinaryProperty(c: UChar32, which: UProperty) -> UBool;
@@ -174,13 +176,17 @@ pub mod icu {
 }
 
 pub fn is_XID_start(c: char) -> bool {
-    return icu::libicu::u_hasBinaryProperty(c, icu::UCHAR_XID_START)
-        == icu::TRUE;
+    unsafe {
+        return icu::libicu::u_hasBinaryProperty(c, icu::UCHAR_XID_START)
+            == icu::TRUE;
+    }
 }
 
 pub fn is_XID_continue(c: char) -> bool {
-    return icu::libicu::u_hasBinaryProperty(c, icu::UCHAR_XID_START)
-        == icu::TRUE;
+    unsafe {
+        return icu::libicu::u_hasBinaryProperty(c, icu::UCHAR_XID_START)
+            == icu::TRUE;
+    }
 }
 
 /*
@@ -189,7 +195,9 @@ Function: is_digit
 Returns true if a character is a digit.
 */
 pub fn is_digit(c: char) -> bool {
-    return icu::libicu::u_isdigit(c) == icu::TRUE;
+    unsafe {
+        return icu::libicu::u_isdigit(c) == icu::TRUE;
+    }
 }
 
 /*
@@ -198,7 +206,9 @@ Function: is_lower
 Returns true if a character is a lowercase letter.
 */
 pub fn is_lower(c: char) -> bool {
-    return icu::libicu::u_islower(c) == icu::TRUE;
+    unsafe {
+        return icu::libicu::u_islower(c) == icu::TRUE;
+    }
 }
 
 /*
@@ -207,7 +217,9 @@ Function: is_space
 Returns true if a character is space.
 */
 pub fn is_space(c: char) -> bool {
-    return icu::libicu::u_isspace(c) == icu::TRUE;
+    unsafe {
+        return icu::libicu::u_isspace(c) == icu::TRUE;
+    }
 }
 
 /*
@@ -216,33 +228,36 @@ Function: is_upper
 Returns true if a character is an uppercase letter.
 */
 pub fn is_upper(c: char) -> bool {
-    return icu::libicu::u_isupper(c) == icu::TRUE;
+    unsafe {
+        return icu::libicu::u_isupper(c) == icu::TRUE;
+    }
 }
 
 #[cfg(test)]
 mod tests {
+    use unicode::*;
 
     #[test]
     fn test_is_digit() {
-        assert!((unicode::icu::is_digit('0')));
-        assert!((!unicode::icu::is_digit('m')));
+        assert!((is_digit('0')));
+        assert!((!is_digit('m')));
     }
 
     #[test]
     fn test_is_lower() {
-        assert!((unicode::icu::is_lower('m')));
-        assert!((!unicode::icu::is_lower('M')));
+        assert!((is_lower('m')));
+        assert!((!is_lower('M')));
     }
 
     #[test]
     fn test_is_space() {
-        assert!((unicode::icu::is_space(' ')));
-        assert!((!unicode::icu::is_space('m')));
+        assert!((is_space(' ')));
+        assert!((!is_space('m')));
     }
 
     #[test]
     fn test_is_upper() {
-        assert!((unicode::icu::is_upper('M')));
-        assert!((!unicode::icu::is_upper('m')));
+        assert!((is_upper('M')));
+        assert!((!is_upper('m')));
     }
 }
diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index 1c983057dba..ea679d19f73 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -335,7 +335,7 @@ pub fn phase_5_run_llvm_passes(sess: Session,
                                outputs: &OutputFilenames) {
 
     // NB: Android hack
-    if sess.targ_cfg.arch == abi::Arm &&
+    if sess.targ_cfg.os == session::os_android &&
         (sess.opts.output_type == link::output_type_object ||
          sess.opts.output_type == link::output_type_exe) {
         let output_type = link::output_type_assembly;
diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs
index e43f85008d5..d725e2db1eb 100644
--- a/src/librustc/driver/session.rs
+++ b/src/librustc/driver/session.rs
@@ -179,7 +179,8 @@ pub struct crate_metadata {
 #[deriving(Eq)]
 pub enum EntryFnType {
     EntryMain,
-    EntryStart
+    EntryStart,
+    EntryNone,
 }
 
 pub struct Session_ {
diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs
index fb12f97c50c..cbd1d3cd9ad 100644
--- a/src/librustc/middle/check_loop.rs
+++ b/src/librustc/middle/check_loop.rs
@@ -52,7 +52,7 @@ pub fn check_crate(tcx: ty::ctxt, crate: &Crate) {
               }
               expr_again(_) => {
                 if !cx.in_loop {
-                    tcx.sess.span_err(e.span, "`again` outside of loop");
+                    tcx.sess.span_err(e.span, "`loop` outside of loop");
                 }
               }
               expr_ret(oe) => {
diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs
index 1bf5c944fab..34aeaf8a6ce 100644
--- a/src/librustc/middle/entry.rs
+++ b/src/librustc/middle/entry.rs
@@ -50,6 +50,12 @@ pub fn find_entry_point(session: Session, crate: &Crate, ast_map: ast_map::map)
         return;
     }
 
+    // If the user wants no main function at all, then stop here.
+    if attr::contains_name(crate.attrs, "no_main") {
+        *session.entry_type = Some(session::EntryNone);
+        return
+    }
+
     let ctxt = @mut EntryContext {
         session: session,
         ast_map: ast_map,
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index fc39af095b7..0a28da5f88a 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -2268,13 +2268,16 @@ pub fn is_entry_fn(sess: &Session, node_id: ast::NodeId) -> bool {
 // Create a _rust_main(args: ~[str]) function which will be called from the
 // runtime rust_start function
 pub fn create_entry_wrapper(ccx: @mut CrateContext,
-                           _sp: span, main_llfn: ValueRef) {
+                           _sp: span,
+                           main_llfn: ValueRef) {
     let et = ccx.sess.entry_type.unwrap();
-    if et == session::EntryMain {
-        let llfn = create_main(ccx, main_llfn);
-        create_entry_fn(ccx, llfn, true);
-    } else {
-        create_entry_fn(ccx, main_llfn, false);
+    match et {
+        session::EntryMain => {
+            let llfn = create_main(ccx, main_llfn);
+            create_entry_fn(ccx, llfn, true);
+        }
+        session::EntryStart => create_entry_fn(ccx, main_llfn, false),
+        session::EntryNone => {}    // Do nothing.
     }
 
     fn create_main(ccx: @mut CrateContext, main_llfn: ValueRef) -> ValueRef {
diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs
index 6128c169967..e6c27fc8f83 100644
--- a/src/librustc/middle/typeck/mod.rs
+++ b/src/librustc/middle/typeck/mod.rs
@@ -408,9 +408,10 @@ fn check_for_entry_fn(ccx: &CrateCtxt) {
           Some((id, sp)) => match *tcx.sess.entry_type {
               Some(session::EntryMain) => check_main_fn_ty(ccx, id, sp),
               Some(session::EntryStart) => check_start_fn_ty(ccx, id, sp),
+              Some(session::EntryNone) => {}
               None => tcx.sess.bug("entry function without a type")
           },
-          None => tcx.sess.bug("type checking without entry function")
+          None => {}
         }
     }
 }
diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs
index a0731dc3494..4356f1143da 100644
--- a/src/libstd/comm.rs
+++ b/src/libstd/comm.rs
@@ -14,7 +14,6 @@ Message passing
 
 #[allow(missing_doc)];
 
-use cast::transmute;
 use either::{Either, Left, Right};
 use kinds::Send;
 use option::{Option, Some};
@@ -23,12 +22,6 @@ pub use rt::comm::SendDeferred;
 use rtcomm = rt::comm;
 use rt;
 
-use pipes::{wait_many, PacketHeader};
-
-// FIXME #5160: Making this public exposes some plumbing from
-// pipes. Needs some refactoring
-pub use pipes::Selectable;
-
 /// A trait for things that can send multiple messages.
 pub trait GenericChan<T> {
     /// Sends a message.
@@ -146,15 +139,6 @@ impl<T: Send> Peekable<T> for Port<T> {
     }
 }
 
-impl<T: Send> Selectable for Port<T> {
-    fn header(&mut self) -> *mut PacketHeader {
-        match self.inner {
-            Left(ref mut port) => port.header(),
-            Right(_) => fail!("can't select on newsched ports")
-        }
-    }
-}
-
 /// A channel that can be shared between many senders.
 pub struct SharedChan<T> {
     inner: Either<Exclusive<pipesy::Chan<T>>, rtcomm::SharedChan<T>>
@@ -318,8 +302,8 @@ mod pipesy {
 
     use kinds::Send;
     use option::{Option, Some, None};
-    use pipes::{recv, try_recv, peek, PacketHeader};
-    use super::{GenericChan, GenericSmartChan, GenericPort, Peekable, Selectable};
+    use pipes::{recv, try_recv, peek};
+    use super::{GenericChan, GenericSmartChan, GenericPort, Peekable};
     use cast::transmute_mut;
 
     /*proto! oneshot (
@@ -651,80 +635,6 @@ mod pipesy {
         }
     }
 
-    impl<T: Send> Selectable for Port<T> {
-        fn header(&mut self) -> *mut PacketHeader {
-            match self.endp {
-                Some(ref mut endp) => endp.header(),
-                None => fail!("peeking empty stream")
-            }
-    }
-}
-
-}
-
-/// Returns the index of an endpoint that is ready to receive.
-pub fn selecti<T: Selectable>(endpoints: &mut [T]) -> uint {
-    wait_many(endpoints)
-}
-
-/// Returns 0 or 1 depending on which endpoint is ready to receive
-pub fn select2i<A:Selectable, B:Selectable>(a: &mut A, b: &mut B)
-                                            -> Either<(), ()> {
-    let mut endpoints = [ a.header(), b.header() ];
-    match wait_many(endpoints) {
-        0 => Left(()),
-        1 => Right(()),
-        _ => fail!("wait returned unexpected index"),
-    }
-}
-
-/// Receive a message from one of two endpoints.
-pub trait Select2<T: Send, U: Send> {
-    /// Receive a message or return `None` if a connection closes.
-    fn try_select(&mut self) -> Either<Option<T>, Option<U>>;
-    /// Receive a message or fail if a connection closes.
-    fn select(&mut self) -> Either<T, U>;
-}
-
-impl<T:Send,
-     U:Send,
-     Left:Selectable + GenericPort<T>,
-     Right:Selectable + GenericPort<U>>
-     Select2<T, U>
-     for (Left, Right) {
-    fn select(&mut self) -> Either<T, U> {
-        // XXX: Bad borrow check workaround.
-        unsafe {
-            let this: &(Left, Right) = transmute(self);
-            match *this {
-                (ref lp, ref rp) => {
-                    let lp: &mut Left = transmute(lp);
-                    let rp: &mut Right = transmute(rp);
-                    match select2i(lp, rp) {
-                        Left(()) => Left(lp.recv()),
-                        Right(()) => Right(rp.recv()),
-                    }
-                }
-            }
-        }
-    }
-
-    fn try_select(&mut self) -> Either<Option<T>, Option<U>> {
-        // XXX: Bad borrow check workaround.
-        unsafe {
-            let this: &(Left, Right) = transmute(self);
-            match *this {
-                (ref lp, ref rp) => {
-                    let lp: &mut Left = transmute(lp);
-                    let rp: &mut Right = transmute(rp);
-                    match select2i(lp, rp) {
-                        Left(()) => Left (lp.try_recv()),
-                        Right(()) => Right(rp.try_recv()),
-                    }
-                }
-            }
-        }
-    }
 }
 
 #[cfg(test)]
@@ -733,22 +643,6 @@ mod test {
     use super::{Chan, Port, oneshot, stream};
 
     #[test]
-    fn test_select2() {
-        let (p1, c1) = stream();
-        let (p2, c2) = stream();
-
-        c1.send(~"abc");
-
-        let mut tuple = (p1, p2);
-        match tuple.select() {
-            Right(_) => fail!(),
-            _ => (),
-        }
-
-        c2.send(123);
-    }
-
-    #[test]
     fn test_oneshot() {
         let (p, c) = oneshot();
 
diff --git a/src/libstd/gc.rs b/src/libstd/gc.rs
deleted file mode 100644
index 2e27f82f6f6..00000000000
--- a/src/libstd/gc.rs
+++ /dev/null
@@ -1,358 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[doc(hidden)];
-#[allow(non_uppercase_statics)];
-
-/*! Precise garbage collector
-
-The precise GC exposes two functions, gc and
-cleanup_stack_for_failure. The gc function is the entry point to the
-garbage collector itself. The cleanup_stack_for_failure is the entry
-point for GC-based cleanup.
-
-Precise GC depends on changes to LLVM's GC which add support for
-automatic rooting and addrspace-based metadata marking. Rather than
-explicitly rooting pointers with LLVM's gcroot intrinsic, the GC
-merely creates allocas for pointers, and allows an LLVM pass to
-automatically infer roots based on the allocas present in a function
-(and live at a given location). The compiler communicates the type of
-the pointer to LLVM by setting the addrspace of the pointer type. The
-compiler then emits a map from addrspace to tydesc, which LLVM then
-uses to match pointers with their tydesc. The GC reads the metadata
-table produced by LLVM, and uses it to determine which glue functions
-to call to free objects on their respective heaps.
-
-GC-based cleanup is a replacement for landing pads which relies on the
-GC infrastructure to find pointers on the stack to cleanup. Whereas
-the normal GC needs to walk task-local heap allocations, the cleanup
-code needs to walk exchange heap allocations and stack-allocations
-with destructors.
-
-*/
-
-use cast;
-use container::{Set, MutableSet};
-use io;
-use libc::{uintptr_t};
-use option::{None, Option, Some};
-use ptr;
-use hashmap::HashSet;
-use stackwalk::walk_stack;
-use sys;
-use unstable::intrinsics::{TyDesc};
-
-pub use stackwalk::Word;
-
-// Mirrors rust_stack.h stk_seg
-pub struct StackSegment {
-    prev: *StackSegment,
-    next: *StackSegment,
-    end: uintptr_t,
-    // And other fields which we don't care about...
-}
-
-pub mod rustrt {
-    use stackwalk::Word;
-    use super::StackSegment;
-
-    #[link_name = "rustrt"]
-    extern {
-        #[rust_stack]
-        pub fn rust_gc_metadata() -> *Word;
-
-        pub fn rust_get_stack_segment() -> *StackSegment;
-        pub fn rust_get_c_stack() -> *StackSegment;
-    }
-}
-
-unsafe fn bump<T, U>(ptr: *T, count: uint) -> *U {
-    return ptr::offset(ptr, count as int) as *U;
-}
-
-unsafe fn align_to_pointer<T>(ptr: *T) -> *T {
-    let align = sys::min_align_of::<*T>();
-    let ptr = ptr as uint;
-    let ptr = (ptr + (align - 1)) & -align;
-    return ptr as *T;
-}
-
-unsafe fn get_safe_point_count() -> uint {
-    let module_meta = rustrt::rust_gc_metadata();
-    return *module_meta;
-}
-
-struct SafePoint {
-    sp_meta: *Word,
-    fn_meta: *Word,
-}
-
-// Returns the safe point metadata for the given program counter, if
-// any.
-unsafe fn is_safe_point(pc: *Word) -> Option<SafePoint> {
-    let module_meta = rustrt::rust_gc_metadata();
-    let num_safe_points = *module_meta;
-    let safe_points: *Word = bump(module_meta, 1);
-
-    if ptr::is_null(pc) {
-        return None;
-    }
-
-    // FIXME (#2997): Use binary rather than linear search.
-    let mut spi = 0;
-    while spi < num_safe_points {
-        let sp: **Word = bump(safe_points, spi*3);
-        let sp_loc = *sp;
-        if sp_loc == pc {
-            return Some(SafePoint {
-                sp_meta: *bump(sp, 1),
-                fn_meta: *bump(sp, 2),
-            });
-        }
-        spi += 1;
-    }
-    return None;
-}
-
-type Visitor<'self> = &'self fn(root: **Word, tydesc: *TyDesc);
-
-// Walks the list of roots for the given safe point, and calls visitor
-// on each root.
-unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) {
-    let fp_bytes = fp as *u8;
-    let sp_meta = sp.sp_meta as *u32;
-
-    let num_stack_roots = *sp_meta as uint;
-    let num_reg_roots = *ptr::offset(sp_meta, 1) as uint;
-
-    let stack_roots: *u32 = bump(sp_meta, 2);
-    let reg_roots: *u8 = bump(stack_roots, num_stack_roots);
-    let addrspaces: *Word = align_to_pointer(bump(reg_roots, num_reg_roots));
-    let tydescs: ***TyDesc = bump(addrspaces, num_stack_roots);
-
-    // Stack roots
-    let mut sri = 0;
-    while sri < num_stack_roots {
-        if *ptr::offset(addrspaces, sri as int) >= 1 {
-            let root =
-                ptr::offset(fp_bytes, *ptr::offset(stack_roots, sri as int) as int)
-                as **Word;
-            let tydescpp = ptr::offset(tydescs, sri as int);
-            let tydesc = if ptr::is_not_null(tydescpp) &&
-                ptr::is_not_null(*tydescpp) {
-                **tydescpp
-            } else {
-                ptr::null()
-            };
-            visitor(root, tydesc);
-        }
-        sri += 1;
-    }
-
-    // Register roots
-    let mut rri = 0;
-    while rri < num_reg_roots {
-        if *ptr::offset(addrspaces, (num_stack_roots + rri) as int) == 1 {
-            // FIXME(#2997): Need to find callee saved registers on the stack.
-        }
-        rri += 1;
-    }
-}
-
-unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) {
-    _walk_safe_point(fp, sp, visitor)
-}
-
-// Is fp contained in segment?
-unsafe fn is_frame_in_segment(fp: *Word, segment: *StackSegment) -> bool {
-    let begin = segment as Word;
-    let end = (*segment).end as Word;
-    let frame = fp as Word;
-
-    return begin <= frame && frame <= end;
-}
-
-struct Segment { segment: *StackSegment, boundary: bool }
-
-// Find and return the segment containing the given frame pointer. At
-// stack segment boundaries, returns true for boundary, so that the
-// caller can do any special handling to identify where the correct
-// return address is in the stack frame.
-unsafe fn find_segment_for_frame(fp: *Word, segment: *StackSegment)
-    -> Segment {
-    // Check if frame is in either current frame or previous frame.
-    let in_segment = is_frame_in_segment(fp, segment);
-    let in_prev_segment = ptr::is_not_null((*segment).prev) &&
-        is_frame_in_segment(fp, (*segment).prev);
-
-    // If frame is not in either segment, walk down segment list until
-    // we find the segment containing this frame.
-    if !in_segment && !in_prev_segment {
-        let mut segment = segment;
-        while ptr::is_not_null((*segment).next) &&
-            is_frame_in_segment(fp, (*segment).next) {
-            segment = (*segment).next;
-        }
-        return Segment {segment: segment, boundary: false};
-    }
-
-    // If frame is in previous frame, then we're at a boundary.
-    if !in_segment && in_prev_segment {
-        return Segment {segment: (*segment).prev, boundary: true};
-    }
-
-    // Otherwise, we're somewhere on the inside of the frame.
-    return Segment {segment: segment, boundary: false};
-}
-
-type Memory = uint;
-
-static task_local_heap: Memory = 1;
-static exchange_heap:   Memory = 2;
-static stack:           Memory = 4;
-
-static need_cleanup:    Memory = exchange_heap | stack;
-
-// Walks stack, searching for roots of the requested type, and passes
-// each root to the visitor.
-unsafe fn _walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) {
-    let mut segment = rustrt::rust_get_stack_segment();
-    let mut last_ret: *Word = ptr::null();
-    // To avoid collecting memory used by the GC itself, skip stack
-    // frames until past the root GC stack frame. The root GC stack
-    // frame is marked by a sentinel, which is a box pointer stored on
-    // the stack.
-    let mut reached_sentinel = ptr::is_null(sentinel);
-    do walk_stack |frame| {
-        let pc = last_ret;
-        let Segment {segment: next_segment, boundary: boundary} =
-            find_segment_for_frame(frame.fp, segment);
-        segment = next_segment;
-        // Each stack segment is bounded by a morestack frame. The
-        // morestack frame includes two return addresses, one for
-        // morestack itself, at the normal offset from the frame
-        // pointer, and then a second return address for the
-        // function prologue (which called morestack after
-        // determining that it had hit the end of the stack).
-        // Since morestack itself takes two parameters, the offset
-        // for this second return address is 3 greater than the
-        // return address for morestack.
-        let ret_offset = if boundary { 4 } else { 1 };
-        last_ret = *ptr::offset(frame.fp, ret_offset as int) as *Word;
-
-        if !ptr::is_null(pc) {
-
-            let mut delay_reached_sentinel = reached_sentinel;
-            let sp = is_safe_point(pc);
-            match sp {
-                Some(sp_info) => {
-                    do walk_safe_point(frame.fp, sp_info) |root, tydesc| {
-                        // Skip roots until we see the sentinel.
-                        if !reached_sentinel && root == sentinel {
-                            delay_reached_sentinel = true;
-                        }
-
-                        // Skip null pointers, which can occur when a
-                        // unique pointer has already been freed.
-                        if reached_sentinel && !ptr::is_null(*root) {
-                            if ptr::is_null(tydesc) {
-                                // Root is a generic box.
-                                let refcount = **root;
-                                if mem | task_local_heap != 0 && refcount != -1 {
-                                    visitor(root, tydesc);
-                                } else if mem | exchange_heap != 0 && refcount == -1 {
-                                    visitor(root, tydesc);
-                                }
-                            } else {
-                                // Root is a non-immediate.
-                                if mem | stack != 0 {
-                                    visitor(root, tydesc);
-                                }
-                            }
-                        }
-                    }
-                }
-                None => ()
-            }
-            reached_sentinel = delay_reached_sentinel;
-        }
-    }
-}
-
-unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) {
-    _walk_gc_roots(mem, sentinel, visitor)
-}
-pub fn gc() {
-    unsafe {
-        // Abort when GC is disabled.
-        if get_safe_point_count() == 0 {
-            return;
-        }
-
-        do walk_gc_roots(task_local_heap, ptr::null()) |_root, _tydesc| {
-            // FIXME(#2997): Walk roots and mark them.
-            io::stdout().write([46]); // .
-        }
-    }
-}
-
-#[cfg(gc)]
-fn expect_sentinel() -> bool { true }
-
-#[cfg(nogc)]
-fn expect_sentinel() -> bool { false }
-
-// Entry point for GC-based cleanup. Walks stack looking for exchange
-// heap and stack allocations requiring drop, and runs all
-// destructors.
-//
-// This should only be called from fail!, as it will drop the roots
-// which are *live* on the stack, rather than dropping those that are
-// dead.
-pub fn cleanup_stack_for_failure() {
-    unsafe {
-        // Abort when GC is disabled.
-        if get_safe_point_count() == 0 {
-            return;
-        }
-
-        // Leave a sentinel on the stack to mark the current frame. The
-        // stack walker will ignore any frames above the sentinel, thus
-        // avoiding collecting any memory being used by the stack walker
-        // itself.
-        //
-        // However, when core itself is not compiled with GC, then none of
-        // the functions in core will have GC metadata, which means we
-        // won't be able to find the sentinel root on the stack. In this
-        // case, we can safely skip the sentinel since we won't find our
-        // own stack roots on the stack anyway.
-        let sentinel_box = ~0;
-        let sentinel: **Word = if expect_sentinel() {
-            cast::transmute(&sentinel_box)
-        } else {
-            ptr::null()
-        };
-
-        let mut roots = HashSet::new();
-        do walk_gc_roots(need_cleanup, sentinel) |root, tydesc| {
-            // Track roots to avoid double frees.
-            if !roots.contains(&*root) {
-                roots.insert(*root);
-
-                if ptr::is_null(tydesc) {
-                    // FIXME #4420: Destroy this box
-                    // FIXME #4330: Destroy this box
-                } else {
-                    ((*tydesc).drop_glue)(*root as *i8);
-                }
-            }
-        }
-    }
-}
diff --git a/src/libstd/logging.rs b/src/libstd/logging.rs
index c662e5997af..6e11d14aea9 100644
--- a/src/libstd/logging.rs
+++ b/src/libstd/logging.rs
@@ -85,16 +85,6 @@ pub fn log_type<T>(level: u32, object: &T) {
 fn newsched_log_str(msg: ~str) {
     use rt::task::Task;
     use rt::local::Local;
-    use str::StrSlice;
-    use container::Container;
-
-    // Truncate the string
-    let buf_bytes = 256;
-    let msg = if msg.len() > buf_bytes {
-        msg.slice(0, buf_bytes) + "[...]"
-    } else {
-        msg
-    };
 
     unsafe {
         match Local::try_unsafe_borrow::<Task>() {
diff --git a/src/libstd/pipes.rs b/src/libstd/pipes.rs
index 1fd534825a5..78f937e058a 100644
--- a/src/libstd/pipes.rs
+++ b/src/libstd/pipes.rs
@@ -868,47 +868,3 @@ pub mod rt {
     pub fn make_some<T>(val: T) -> Option<T> { Some(val) }
     pub fn make_none<T>() -> Option<T> { None }
 }
-
-#[cfg(test)]
-mod test {
-    use either::Right;
-    use comm::{Chan, Port, oneshot, recv_one, stream, Select2,
-               GenericChan, Peekable};
-
-    #[test]
-    fn test_select2() {
-        let (p1, c1) = stream();
-        let (p2, c2) = stream();
-
-        c1.send(~"abc");
-
-        let mut tuple = (p1, p2);
-        match tuple.select() {
-            Right(_) => fail!(),
-            _ => (),
-        }
-
-        c2.send(123);
-    }
-
-    #[test]
-    fn test_oneshot() {
-        let (p, c) = oneshot();
-
-        c.send(());
-
-        recv_one(p)
-    }
-
-    #[test]
-    fn test_peek_terminated() {
-        let (port, chan): (Port<int>, Chan<int>) = stream();
-
-        {
-            // Destroy the channel
-            let _chan = chan;
-        }
-
-        assert!(!port.peek());
-    }
-}
diff --git a/src/libstd/rt/local.rs b/src/libstd/rt/local.rs
index 7ab63233cff..131507196b1 100644
--- a/src/libstd/rt/local.rs
+++ b/src/libstd/rt/local.rs
@@ -126,6 +126,7 @@ impl Local for IoFactoryObject {
 
 #[cfg(test)]
 mod test {
+    use unstable::run_in_bare_thread;
     use rt::test::*;
     use super::*;
     use rt::task::Task;
@@ -133,56 +134,64 @@ mod test {
 
     #[test]
     fn thread_local_task_smoke_test() {
-        local_ptr::init_tls_key();
-        let mut sched = ~new_test_uv_sched();
-        let task = ~Task::new_root(&mut sched.stack_pool, || {});
-        Local::put(task);
-        let task: ~Task = Local::take();
-        cleanup_task(task);
+        do run_in_bare_thread {
+            local_ptr::init_tls_key();
+            let mut sched = ~new_test_uv_sched();
+            let task = ~Task::new_root(&mut sched.stack_pool, || {});
+            Local::put(task);
+            let task: ~Task = Local::take();
+            cleanup_task(task);
+        }
     }
 
     #[test]
     fn thread_local_task_two_instances() {
-        local_ptr::init_tls_key();
-        let mut sched = ~new_test_uv_sched();
-        let task = ~Task::new_root(&mut sched.stack_pool, || {});
-        Local::put(task);
-        let task: ~Task = Local::take();
-        cleanup_task(task);
-        let task = ~Task::new_root(&mut sched.stack_pool, || {});
-        Local::put(task);
-        let task: ~Task = Local::take();
-        cleanup_task(task);
+        do run_in_bare_thread {
+            local_ptr::init_tls_key();
+            let mut sched = ~new_test_uv_sched();
+            let task = ~Task::new_root(&mut sched.stack_pool, || {});
+            Local::put(task);
+            let task: ~Task = Local::take();
+            cleanup_task(task);
+            let task = ~Task::new_root(&mut sched.stack_pool, || {});
+            Local::put(task);
+            let task: ~Task = Local::take();
+            cleanup_task(task);
+        }
 
     }
 
     #[test]
     fn borrow_smoke_test() {
-        local_ptr::init_tls_key();
-        let mut sched = ~new_test_uv_sched();
-        let task = ~Task::new_root(&mut sched.stack_pool, || {});
-        Local::put(task);
-
-        unsafe {
-            let _task: *mut Task = Local::unsafe_borrow();
+        do run_in_bare_thread {
+            local_ptr::init_tls_key();
+            let mut sched = ~new_test_uv_sched();
+            let task = ~Task::new_root(&mut sched.stack_pool, || {});
+            Local::put(task);
+
+            unsafe {
+                let _task: *mut Task = Local::unsafe_borrow();
+            }
+            let task: ~Task = Local::take();
+            cleanup_task(task);
         }
-        let task: ~Task = Local::take();
-        cleanup_task(task);
     }
 
     #[test]
     fn borrow_with_return() {
-        local_ptr::init_tls_key();
-        let mut sched = ~new_test_uv_sched();
-        let task = ~Task::new_root(&mut sched.stack_pool, || {});
-        Local::put(task);
-
-        let res = do Local::borrow::<Task,bool> |_task| {
-            true
-        };
-        assert!(res)
-        let task: ~Task = Local::take();
-        cleanup_task(task);
+        do run_in_bare_thread {
+            local_ptr::init_tls_key();
+            let mut sched = ~new_test_uv_sched();
+            let task = ~Task::new_root(&mut sched.stack_pool, || {});
+            Local::put(task);
+
+            let res = do Local::borrow::<Task,bool> |_task| {
+                true
+            };
+            assert!(res)
+                let task: ~Task = Local::take();
+            cleanup_task(task);
+        }
     }
 
 }
diff --git a/src/libstd/rt/local_ptr.rs b/src/libstd/rt/local_ptr.rs
index cd7c5daa444..652e39b05c7 100644
--- a/src/libstd/rt/local_ptr.rs
+++ b/src/libstd/rt/local_ptr.rs
@@ -52,7 +52,9 @@ pub unsafe fn put<T>(sched: ~T) {
 pub unsafe fn take<T>() -> ~T {
     let key = tls_key();
     let void_ptr: *mut c_void = tls::get(key);
-    rtassert!(void_ptr.is_not_null());
+    if void_ptr.is_null() {
+        rtabort!("thread-local pointer is null. bogus!");
+    }
     let ptr: ~T = cast::transmute(void_ptr);
     tls::set(key, ptr::mut_null());
     return ptr;
@@ -68,8 +70,8 @@ pub fn exists() -> bool {
     }
 }
 
-/// Borrow the thread-local scheduler from thread-local storage.
-/// While the scheduler is borrowed it is not available in TLS.
+/// Borrow the thread-local value from thread-local storage.
+/// While the value is borrowed it is not available in TLS.
 ///
 /// # Safety note
 ///
@@ -88,21 +90,23 @@ pub unsafe fn borrow<T>(f: &fn(&mut T)) {
     }
 }
 
-/// Borrow a mutable reference to the thread-local Scheduler
+/// Borrow a mutable reference to the thread-local value
 ///
 /// # Safety Note
 ///
-/// Because this leaves the Scheduler in thread-local storage it is possible
+/// Because this leaves the value in thread-local storage it is possible
 /// For the Scheduler pointer to be aliased
 pub unsafe fn unsafe_borrow<T>() -> *mut T {
     let key = tls_key();
-    let mut void_sched: *mut c_void = tls::get(key);
-    rtassert!(void_sched.is_not_null());
+    let mut void_ptr: *mut c_void = tls::get(key);
+    if void_ptr.is_null() {
+        rtabort!("thread-local pointer is null. bogus!");
+    }
     {
-        let sched: *mut *mut c_void = &mut void_sched;
-        let sched: *mut ~T = sched as *mut ~T;
-        let sched: *mut T = &mut **sched;
-        return sched;
+        let ptr: *mut *mut c_void = &mut void_ptr;
+        let ptr: *mut ~T = ptr as *mut ~T;
+        let ptr: *mut T = &mut **ptr;
+        return ptr;
     }
 }
 
diff --git a/src/libstd/rt/logging.rs b/src/libstd/rt/logging.rs
index 11d11daebc2..9056f0d52e0 100644
--- a/src/libstd/rt/logging.rs
+++ b/src/libstd/rt/logging.rs
@@ -10,6 +10,7 @@
 
 use either::*;
 use libc;
+use str::StrSlice;
 
 pub trait Logger {
     fn log(&mut self, msg: Either<~str, &'static str>);
@@ -35,10 +36,22 @@ impl Logger for StdErrLogger {
                 s
             }
         };
-        let dbg = ::libc::STDERR_FILENO as ::io::fd_t;
-        dbg.write_str(s);
-        dbg.write_str("\n");
-        dbg.flush();
+
+        // Truncate the string
+        let buf_bytes = 256;
+        if s.len() > buf_bytes {
+            let s = s.slice(0, buf_bytes) + "[...]";
+            print(s);
+        } else {
+            print(s)
+        };
+
+        fn print(s: &str) {
+            let dbg = ::libc::STDERR_FILENO as ::io::fd_t;
+            dbg.write_str(s);
+            dbg.write_str("\n");
+            dbg.flush();
+        }
     }
 }
 
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index 4cfe0efacfe..33e83fd9040 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -432,13 +432,3 @@ pub fn context() -> RuntimeContext {
         pub fn rust_try_get_task() -> *rust_task;
     }
 }
-
-#[test]
-fn test_context() {
-    use unstable::run_in_bare_thread;
-
-    assert_eq!(context(), OldTaskContext);
-    do run_in_bare_thread {
-        assert_eq!(context(), GlobalContext);
-    }
-}
diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs
index 18cfeade157..1a75f2569b5 100644
--- a/src/libstd/rt/sched.rs
+++ b/src/libstd/rt/sched.rs
@@ -172,6 +172,10 @@ impl Scheduler {
 
         rtdebug!("stopping scheduler %u", stask.sched.get_ref().sched_id());
 
+        // Should not have any messages
+        let message = stask.sched.get_mut_ref().message_queue.pop();
+        assert!(message.is_none());
+
         stask.destroyed = true;
     }
 
@@ -335,19 +339,24 @@ impl Scheduler {
         let mut this = self;
         match this.message_queue.pop() {
             Some(PinnedTask(task)) => {
+                this.event_loop.callback(Scheduler::run_sched_once);
                 let mut task = task;
                 task.give_home(Sched(this.make_handle()));
                 this.resume_task_immediately(task);
                 return None;
             }
             Some(TaskFromFriend(task)) => {
+                this.event_loop.callback(Scheduler::run_sched_once);
+                rtdebug!("got a task from a friend. lovely!");
                 return this.sched_schedule_task(task);
             }
             Some(Wake) => {
+                this.event_loop.callback(Scheduler::run_sched_once);
                 this.sleepy = false;
                 return Some(this);
             }
             Some(Shutdown) => {
+                this.event_loop.callback(Scheduler::run_sched_once);
                 if this.sleepy {
                     // There may be an outstanding handle on the
                     // sleeper list.  Pop them all to make sure that's
@@ -395,6 +404,7 @@ impl Scheduler {
     /// Take a non-homed task we aren't allowed to run here and send
     /// it to the designated friend scheduler to execute.
     fn send_to_friend(&mut self, task: ~Task) {
+        rtdebug!("sending a task to friend");
         match self.friend_handle {
             Some(ref mut handle) => {
                 handle.send(TaskFromFriend(task));
@@ -426,12 +436,14 @@ impl Scheduler {
                             Scheduler::send_task_home(task);
                             return Some(this);
                         } else {
+                            this.event_loop.callback(Scheduler::run_sched_once);
                             task.give_home(Sched(home_handle));
                             this.resume_task_immediately(task);
                             return None;
                         }
                     }
                     AnySched if this.run_anything => {
+                        this.event_loop.callback(Scheduler::run_sched_once);
                         task.give_home(AnySched);
                         this.resume_task_immediately(task);
                         return None;
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index abafe1cf209..cb949edd7bb 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -228,6 +228,19 @@ impl Task {
                     _ => ()
                 }
 
+                // FIXME #8302: Dear diary. I'm so tired and confused.
+                // There's some interaction in rustc between the box
+                // annihilator and the TLS dtor by which TLS is
+                // accessed from annihilated box dtors *after* TLS is
+                // destroyed. Somehow setting TLS back to null, as the
+                // old runtime did, makes this work, but I don't currently
+                // understand how. I would expect that, if the annihilator
+                // reinvokes TLS while TLS is uninitialized, that
+                // TLS would be reinitialized but never destroyed,
+                // but somehow this works. I have no idea what's going
+                // on but this seems to make things magically work. FML.
+                self.storage = LocalStorage(ptr::null(), None);
+
                 // Destroy remaining boxes. Also may run user dtors.
                 unsafe { cleanup::annihilate(); }
             }
@@ -303,7 +316,7 @@ impl Task {
 impl Drop for Task {
     fn drop(&self) {
         rtdebug!("called drop for a task: %u", borrow::to_uint(self));
-        assert!(self.destroyed)
+        rtassert!(self.destroyed)
     }
 }
 
@@ -313,7 +326,7 @@ impl Drop for Task {
 impl Coroutine {
 
     pub fn new(stack_pool: &mut StackPool, start: ~fn()) -> Coroutine {
-        static MIN_STACK_SIZE: uint = 2000000; // XXX: Too much stack
+        static MIN_STACK_SIZE: uint = 3000000; // XXX: Too much stack
 
         let start = Coroutine::build_start_wrapper(start);
         let mut stack = stack_pool.take_segment(MIN_STACK_SIZE);
diff --git a/src/libstd/stackwalk.rs b/src/libstd/stackwalk.rs
deleted file mode 100644
index cc516fb559e..00000000000
--- a/src/libstd/stackwalk.rs
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[allow(missing_doc)];
-
-use cast::transmute;
-use unstable::intrinsics;
-
-pub type Word = uint;
-
-pub struct Frame {
-    fp: *Word
-}
-
-pub fn Frame(fp: *Word) -> Frame {
-    Frame {
-        fp: fp
-    }
-}
-
-pub fn walk_stack(visit: &fn(Frame)) {
-
-    debug!("beginning stack walk");
-
-    do frame_address |frame_pointer| {
-        let mut frame_address: *Word = unsafe {
-            transmute(frame_pointer)
-        };
-        loop {
-            let fr = Frame(frame_address);
-
-            debug!("frame: %x", unsafe { transmute(fr.fp) });
-            visit(fr);
-
-            unsafe {
-                let next_fp: **Word = transmute(frame_address);
-                frame_address = *next_fp;
-                if *frame_address == 0u {
-                    debug!("encountered task_start_wrapper. ending walk");
-                    // This is the task_start_wrapper_frame. There is
-                    // no stack beneath it and it is a foreign frame.
-                    break;
-                }
-            }
-        }
-    }
-}
-
-#[test]
-fn test_simple() {
-    do walk_stack |_frame| {
-    }
-}
-
-#[test]
-fn test_simple_deep() {
-    fn run(i: int) {
-        if i == 0 { return }
-
-        do walk_stack |_frame| {
-            // Would be nice to test something here...
-        }
-        run(i - 1);
-    }
-
-    run(10);
-}
-
-fn frame_address(f: &fn(x: *u8)) {
-    unsafe {
-        intrinsics::frame_address(f)
-    }
-}
diff --git a/src/libstd/std.rs b/src/libstd/std.rs
index 76d65192e01..568709c89da 100644
--- a/src/libstd/std.rs
+++ b/src/libstd/std.rs
@@ -170,7 +170,6 @@ pub mod local_data;
 
 /* Runtime and platform support */
 
-pub mod gc;
 pub mod libc;
 pub mod os;
 pub mod path;
@@ -196,7 +195,6 @@ pub mod unstable;
 mod unicode;
 #[path = "num/cmath.rs"]
 mod cmath;
-mod stackwalk;
 
 // XXX: This shouldn't be pub, and it should be reexported under 'unstable'
 // but name resolution doesn't work without it being pub.
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index 5c6895fea43..1a913fb4e99 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -902,7 +902,7 @@ pub mod raw {
         let new_len = s.len() + 1;
         s.reserve_at_least(new_len);
         do s.as_mut_buf |buf, len| {
-            *ptr::mut_offset(buf, len as int) = b;
+            *ptr::mut_offset(buf, (len-1) as int) = b;
         }
         set_len(&mut *s, new_len);
     }
@@ -2826,6 +2826,13 @@ mod tests {
     }
 
     #[test]
+    fn test_push_byte() {
+        let mut s = ~"ABC";
+        unsafe{raw::push_byte(&mut s, 'D' as u8)};
+        assert_eq!(s, ~"ABCD");
+    }
+
+    #[test]
     fn test_shift_byte() {
         let mut s = ~"ABC";
         let b = unsafe{raw::shift_byte(&mut s)};
diff --git a/src/libstd/sys.rs b/src/libstd/sys.rs
index 51609709cdb..9d853087123 100644
--- a/src/libstd/sys.rs
+++ b/src/libstd/sys.rs
@@ -13,7 +13,6 @@
 #[allow(missing_doc)];
 
 use cast;
-use gc;
 use io;
 use libc;
 use libc::{c_char, size_t};
@@ -147,7 +146,6 @@ pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! {
     match context {
         OldTaskContext => {
             unsafe {
-                gc::cleanup_stack_for_failure();
                 rustrt::rust_upcall_fail(msg, file, line);
                 cast::transmute(())
             }
@@ -180,8 +178,6 @@ pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! {
                              msg, file, line as int);
                 }
 
-                gc::cleanup_stack_for_failure();
-
                 let task = Local::unsafe_borrow::<Task>();
                 if (*task).unwinder.unwinding {
                     rtabort!("unwinding again");
diff --git a/src/rt/arch/arm/record_sp.S b/src/rt/arch/arm/record_sp.S
index 8d5f24bc5a8..3c5c7644beb 100644
--- a/src/rt/arch/arm/record_sp.S
+++ b/src/rt/arch/arm/record_sp.S
@@ -14,22 +14,36 @@
 .globl get_sp
 
 record_sp_limit:
+	// First, try to read TLS address from coprocessor
 	mrc p15, #0, r3, c13, c0, #3
+	cmp r3, #0
+	// Otherwise, try to read from magic address 0xFFFF0FF0
+	mvneq r3, #0xF000
+	ldreq r3, [r3, #-15]
+
 #if __ANDROID__
 	add r3, r3, #252
 #elif __linux__
 	add r3, r3, #4
 #endif
+
 	str r0, [r3]
 	mov pc, lr
 
 get_sp_limit:
+	// First, try to read TLS address from coprocessor
 	mrc p15, #0, r3, c13, c0, #3
+	cmp r3, #0
+	// Otherwise, try to read from magic address 0xFFFF0FF0
+	mvneq r3, #0xF000
+	ldreq r3, [r3, #-15]
+
 #if __ANDROID__
 	add r3, r3, #252
 #elif __linux__
 	add r3, r3, #4
 #endif
+
 	ldr r0, [r3]
 	mov pc, lr
 
diff --git a/src/test/bench/shootout-binarytrees.rs b/src/test/bench/shootout-binarytrees.rs
index 596a5b5422a..57bf33fb2fd 100644
--- a/src/test/bench/shootout-binarytrees.rs
+++ b/src/test/bench/shootout-binarytrees.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 extern mod extra;
-use extra::arena;
+use extra::arena::Arena;
 
 enum Tree<'self> {
     Nil,
@@ -25,7 +25,7 @@ fn item_check(t: &Tree) -> int {
     }
 }
 
-fn bottom_up_tree<'r>(arena: &'r arena::Arena, item: int, depth: int)
+fn bottom_up_tree<'r>(arena: &'r Arena, item: int, depth: int)
                    -> &'r Tree<'r> {
     if depth > 0 {
         return arena.alloc(
@@ -57,7 +57,7 @@ fn main() {
         max_depth = n;
     }
 
-    let stretch_arena = arena::Arena();
+    let stretch_arena = Arena::new();
     let stretch_depth = max_depth + 1;
     let stretch_tree = bottom_up_tree(&stretch_arena, 0, stretch_depth);
 
@@ -65,7 +65,7 @@ fn main() {
               stretch_depth,
               item_check(stretch_tree));
 
-    let long_lived_arena = arena::Arena();
+    let long_lived_arena = Arena::new();
     let long_lived_tree = bottom_up_tree(&long_lived_arena, 0, max_depth);
     let mut depth = min_depth;
     while depth <= max_depth {
diff --git a/src/test/run-pass/issue-3176.rs b/src/test/run-pass/issue-3176.rs
deleted file mode 100644
index df242ee3d30..00000000000
--- a/src/test/run-pass/issue-3176.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// xfail-fast
-// xfail-win32 #7999
-
-use std::comm::{Select2, Selectable};
-use std::comm;
-use std::task;
-
-pub fn main() {
-    let (p,c) = comm::stream();
-    do task::try || {
-        let (p2,c2) = comm::stream();
-        do task::spawn || {
-            p2.recv();
-            error!("sibling fails");
-            fail!();
-        }
-        let (p3,c3) = comm::stream();
-        c.send(c3);
-        c2.send(());
-        error!("child blocks");
-        let (p, c) = comm::stream();
-        let mut tuple = (p, p3);
-        tuple.select();
-        c.send(());
-    };
-    error!("parent tries");
-    assert!(!p.recv().try_send(()));
-    error!("all done!");
-}
diff --git a/src/test/run-pass/placement-new-arena.rs b/src/test/run-pass/placement-new-arena.rs
index 9500f83b76b..f2063b583e4 100644
--- a/src/test/run-pass/placement-new-arena.rs
+++ b/src/test/run-pass/placement-new-arena.rs
@@ -11,10 +11,10 @@
 // except according to those terms.
 
 extern mod extra;
-use extra::arena;
+use extra::arena::Arena;
 
 pub fn main() {
-    let mut arena = arena::Arena();
+    let mut arena = Arena::new();
     let p = &mut arena;
     let x = p.alloc(|| 4u);
     printf!("%u", *x);