about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-05-08 21:01:42 -0700
committerbors <bors@rust-lang.org>2014-05-08 21:01:42 -0700
commita990920c6fff9b762c3d0968ff0a5fdcce6d2b39 (patch)
tree8b4cb2edb2e48660ca6e6c0f6a660951f00c1e02 /src/libstd/rt
parentc0a25e4fdc1fcdde8378b4177a6f06c58001a3be (diff)
parentdc30c483810ca0ee3641f4bab8e6f2a44a883fee (diff)
downloadrust-a990920c6fff9b762c3d0968ff0a5fdcce6d2b39.tar.gz
rust-a990920c6fff9b762c3d0968ff0a5fdcce6d2b39.zip
auto merge of #13963 : kballard/rust/remove_owned_vec_from_iterator, r=pcwalton
With `~[T]` no longer growable, the `FromIterator` impl for `~[T]` doesn't make
much sense. Not only that, but nearly everywhere it is used is to convert from
a `Vec<T>` into a `~[T]`, for the sake of maintaining existing APIs. This turns
out to be a performance loss, as it means every API that returns `~[T]`, even a
supposedly non-copying one, is in fact doing extra allocations and memcpy's.
Even `&[T].to_owned()` is going through `Vec<T>` first.

Remove the `FromIterator` impl for `~[T]`, and adjust all the APIs that relied
on it to start using `Vec<T>` instead. This includes rewriting
`&[T].to_owned()` to be more efficient, among other performance wins.

Also add a new mechanism to go from `Vec<T>` -> `~[T]`, just in case anyone
truly needs that, using the new trait `FromVec`.

[breaking-change]
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/args.rs43
-rw-r--r--src/libstd/rt/rtio.rs4
2 files changed, 25 insertions, 22 deletions
diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs
index ac1692e6bb3..df0f1d8d449 100644
--- a/src/libstd/rt/args.rs
+++ b/src/libstd/rt/args.rs
@@ -21,6 +21,7 @@
 //! FIXME #7756: This has a lot of C glue for lack of globals.
 
 use option::Option;
+use vec::Vec;
 #[cfg(test)] use option::{Some, None};
 #[cfg(test)] use realstd;
 #[cfg(test)] use realargs = realstd::rt::args;
@@ -36,10 +37,10 @@ pub unsafe fn init(argc: int, argv: **u8) { realargs::init(argc, argv) }
 #[cfg(test)]      pub unsafe fn cleanup() { realargs::cleanup() }
 
 /// Take the global arguments from global storage.
-#[cfg(not(test))] pub fn take() -> Option<~[~[u8]]> { imp::take() }
-#[cfg(test)]      pub fn take() -> Option<~[~[u8]]> {
+#[cfg(not(test))] pub fn take() -> Option<Vec<~[u8]>> { imp::take() }
+#[cfg(test)]      pub fn take() -> Option<Vec<~[u8]>> {
     match realargs::take() {
-        realstd::option::Some(a) => Some(a),
+        realstd::option::Some(v) => Some(unsafe{ ::cast::transmute(v) }),
         realstd::option::None => None,
     }
 }
@@ -47,14 +48,14 @@ pub unsafe fn init(argc: int, argv: **u8) { realargs::init(argc, argv) }
 /// Give the global arguments to global storage.
 ///
 /// It is an error if the arguments already exist.
-#[cfg(not(test))] pub fn put(args: ~[~[u8]]) { imp::put(args) }
-#[cfg(test)]      pub fn put(args: ~[~[u8]]) { realargs::put(args) }
+#[cfg(not(test))] pub fn put(args: Vec<~[u8]>) { imp::put(args) }
+#[cfg(test)]      pub fn put(args: Vec<~[u8]>) { realargs::put(unsafe { ::cast::transmute(args) }) }
 
 /// Make a clone of the global arguments.
-#[cfg(not(test))] pub fn clone() -> Option<~[~[u8]]> { imp::clone() }
-#[cfg(test)]      pub fn clone() -> Option<~[~[u8]]> {
+#[cfg(not(test))] pub fn clone() -> Option<Vec<~[u8]>> { imp::clone() }
+#[cfg(test)]      pub fn clone() -> Option<Vec<~[u8]>> {
     match realargs::clone() {
-        realstd::option::Some(a) => Some(a),
+        realstd::option::Some(v) => Some(unsafe { ::cast::transmute(v) }),
         realstd::option::None => None,
     }
 }
@@ -70,6 +71,7 @@ mod imp {
     use owned::Box;
     use unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
     use mem;
+    use vec::Vec;
     #[cfg(not(test))] use ptr::RawPtr;
 
     static mut global_args_ptr: uint = 0;
@@ -87,15 +89,15 @@ mod imp {
         lock.destroy();
     }
 
-    pub fn take() -> Option<~[~[u8]]> {
+    pub fn take() -> Option<Vec<~[u8]>> {
         with_lock(|| unsafe {
             let ptr = get_global_ptr();
             let val = mem::replace(&mut *ptr, None);
-            val.as_ref().map(|s: &Box<~[~[u8]]>| (**s).clone())
+            val.as_ref().map(|s: &Box<Vec<~[u8]>>| (**s).clone())
         })
     }
 
-    pub fn put(args: ~[~[u8]]) {
+    pub fn put(args: Vec<~[u8]>) {
         with_lock(|| unsafe {
             let ptr = get_global_ptr();
             rtassert!((*ptr).is_none());
@@ -103,10 +105,10 @@ mod imp {
         })
     }
 
-    pub fn clone() -> Option<~[~[u8]]> {
+    pub fn clone() -> Option<Vec<~[u8]>> {
         with_lock(|| unsafe {
             let ptr = get_global_ptr();
-            (*ptr).as_ref().map(|s: &Box<~[~[u8]]>| (**s).clone())
+            (*ptr).as_ref().map(|s: &Box<Vec<~[u8]>>| (**s).clone())
         })
     }
 
@@ -117,13 +119,13 @@ mod imp {
         }
     }
 
-    fn get_global_ptr() -> *mut Option<Box<~[~[u8]]>> {
+    fn get_global_ptr() -> *mut Option<Box<Vec<~[u8]>>> {
         unsafe { cast::transmute(&global_args_ptr) }
     }
 
     // Copied from `os`.
     #[cfg(not(test))]
-    unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~[u8]] {
+    unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> Vec<~[u8]> {
         use c_str::CString;
         use ptr::RawPtr;
         use libc;
@@ -133,7 +135,7 @@ mod imp {
         Vec::from_fn(argc as uint, |i| {
             let cs = CString::new(*(argv as **libc::c_char).offset(i as int), false);
             cs.as_bytes_no_nul().to_owned()
-        }).move_iter().collect()
+        })
     }
 
     #[cfg(test)]
@@ -147,7 +149,7 @@ mod imp {
             // Preserve the actual global state.
             let saved_value = take();
 
-            let expected = box [bytes!("happy").to_owned(), bytes!("today?").to_owned()];
+            let expected = vec![bytes!("happy").to_owned(), bytes!("today?").to_owned()];
 
             put(expected.clone());
             assert!(clone() == Some(expected.clone()));
@@ -170,6 +172,7 @@ mod imp {
 #[cfg(target_os = "win32", not(test))]
 mod imp {
     use option::Option;
+    use vec::Vec;
 
     pub unsafe fn init(_argc: int, _argv: **u8) {
     }
@@ -177,15 +180,15 @@ mod imp {
     pub fn cleanup() {
     }
 
-    pub fn take() -> Option<~[~[u8]]> {
+    pub fn take() -> Option<Vec<~[u8]>> {
         fail!()
     }
 
-    pub fn put(_args: ~[~[u8]]) {
+    pub fn put(_args: Vec<~[u8]>) {
         fail!()
     }
 
-    pub fn clone() -> Option<~[~[u8]]> {
+    pub fn clone() -> Option<Vec<~[u8]>> {
         fail!()
     }
 }
diff --git a/src/libstd/rt/rtio.rs b/src/libstd/rt/rtio.rs
index 16882624ab7..ccde8d9c96a 100644
--- a/src/libstd/rt/rtio.rs
+++ b/src/libstd/rt/rtio.rs
@@ -161,7 +161,7 @@ pub trait IoFactory {
     fn unix_connect(&mut self, path: &CString,
                     timeout: Option<u64>) -> IoResult<Box<RtioPipe:Send>>;
     fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
-                          hint: Option<ai::Hint>) -> IoResult<~[ai::Info]>;
+                          hint: Option<ai::Hint>) -> IoResult<Vec<ai::Info>>;
 
     // filesystem operations
     fn fs_from_raw_fd(&mut self, fd: c_int, close: CloseBehavior)
@@ -191,7 +191,7 @@ pub trait IoFactory {
     fn timer_init(&mut self) -> IoResult<Box<RtioTimer:Send>>;
     fn spawn(&mut self, config: ProcessConfig)
             -> IoResult<(Box<RtioProcess:Send>,
-                         ~[Option<Box<RtioPipe:Send>>])>;
+                         Vec<Option<Box<RtioPipe:Send>>>)>;
     fn kill(&mut self, pid: libc::pid_t, signal: int) -> IoResult<()>;
     fn pipe_open(&mut self, fd: c_int) -> IoResult<Box<RtioPipe:Send>>;
     fn tty_open(&mut self, fd: c_int, readable: bool)