diff options
Diffstat (limited to 'components/util')
-rw-r--r-- | components/util/Cargo.toml | 8 | ||||
-rw-r--r-- | components/util/bloom.rs | 12 | ||||
-rw-r--r-- | components/util/cache.rs | 99 | ||||
-rw-r--r-- | components/util/cursor.rs | 5 | ||||
-rw-r--r-- | components/util/deque/mod.rs | 268 | ||||
-rw-r--r-- | components/util/fnv.rs | 34 | ||||
-rw-r--r-- | components/util/geometry.rs | 78 | ||||
-rw-r--r-- | components/util/lib.rs | 21 | ||||
-rw-r--r-- | components/util/logical_geometry.rs | 85 | ||||
-rw-r--r-- | components/util/memory.rs | 24 | ||||
-rw-r--r-- | components/util/opts.rs | 18 | ||||
-rw-r--r-- | components/util/persistent_list.rs | 4 | ||||
-rw-r--r-- | components/util/range.rs | 92 | ||||
-rw-r--r-- | components/util/smallvec.rs | 73 | ||||
-rw-r--r-- | components/util/sort.rs | 3 | ||||
-rw-r--r-- | components/util/str.rs | 37 | ||||
-rw-r--r-- | components/util/task.rs | 47 | ||||
-rw-r--r-- | components/util/task_state.rs | 8 | ||||
-rw-r--r-- | components/util/taskpool.rs | 18 | ||||
-rw-r--r-- | components/util/tid.rs | 6 | ||||
-rw-r--r-- | components/util/time.rs | 50 | ||||
-rw-r--r-- | components/util/vec.rs | 2 | ||||
-rw-r--r-- | components/util/workqueue.rs | 33 |
23 files changed, 421 insertions, 604 deletions
diff --git a/components/util/Cargo.toml b/components/util/Cargo.toml index c418d0b2880..d9209c74e4f 100644 --- a/components/util/Cargo.toml +++ b/components/util/Cargo.toml @@ -36,11 +36,7 @@ git = "https://github.com/servo/string-cache" [dependencies.string_cache_macros] git = "https://github.com/servo/string-cache" -[dependencies.url] -git = "https://github.com/servo/rust-url" - -[dependencies.time] -git = "https://github.com/rust-lang/time" - [dependencies] text_writer = "0.1.1" +url = "*" +time = "*"
\ No newline at end of file diff --git a/components/util/bloom.rs b/components/util/bloom.rs index 2bed80e9e13..6fd5d17e775 100644 --- a/components/util/bloom.rs +++ b/components/util/bloom.rs @@ -58,7 +58,7 @@ const KEY_SHIFT: uint = 16; /// positive rate for N == 100 and to quite bad false positive /// rates for larger N. pub struct BloomFilter { - counters: [u8, ..ARRAY_SIZE], + counters: [u8; ARRAY_SIZE], } impl Clone for BloomFilter { @@ -75,7 +75,7 @@ impl BloomFilter { #[inline] pub fn new() -> BloomFilter { BloomFilter { - counters: [0, ..ARRAY_SIZE], + counters: [0; ARRAY_SIZE], } } @@ -101,7 +101,7 @@ impl BloomFilter { #[inline] pub fn clear(&mut self) { - self.counters = [0, ..ARRAY_SIZE] + self.counters = [0; ARRAY_SIZE] } #[inline] @@ -231,7 +231,7 @@ fn create_and_insert_some_stuff() { let false_positives = range(1001u, 2000).filter(|i| bf.might_contain(i)).count(); - assert!(false_positives < 10) // 1%. + assert!(false_positives < 10); // 1%. for i in range(0u, 100) { bf.remove(&i); @@ -256,7 +256,7 @@ fn create_and_insert_some_stuff() { mod bench { extern crate test; - use std::hash::hash; + use std::hash::{hash, SipHasher}; use std::iter; use super::BloomFilter; @@ -331,7 +331,7 @@ mod bench { fn hash_a_uint(b: &mut test::Bencher) { let mut i = 0u; b.iter(|| { - test::black_box(hash(&i)); + test::black_box(hash::<uint, SipHasher>(&i)); i += 1; }) } diff --git a/components/util/cache.rs b/components/util/cache.rs index 35390d309bf..99e086cdbfe 100644 --- a/components/util/cache.rs +++ b/components/util/cache.rs @@ -2,69 +2,59 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#![old_impl_check] + use std::collections::HashMap; -use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::hash_map::Entry::{Occupied, Vacant}; +use std::collections::hash_state::DefaultState; use rand::Rng; -use std::hash::{Hash, sip}; +use std::hash::{Hash, SipHasher}; use std::iter::repeat; -use std::rand::task_rng; -use std::slice::Items; +use std::rand; +use std::slice::Iter; #[cfg(test)] use std::cell::Cell; -pub trait Cache<K: PartialEq, V: Clone> { - fn insert(&mut self, key: K, value: V); - fn find(&mut self, key: &K) -> Option<V>; - fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V; - fn evict_all(&mut self); -} - pub struct HashCache<K, V> { - entries: HashMap<K, V>, + entries: HashMap<K, V, DefaultState<SipHasher>>, } -impl<K: Clone + PartialEq + Eq + Hash, V: Clone> HashCache<K,V> { - pub fn new() -> HashCache<K, V> { +impl<K, V> HashCache<K,V> + where K: Clone + PartialEq + Eq + Hash<SipHasher>, + V: Clone, +{ + pub fn new() -> HashCache<K,V> { HashCache { - entries: HashMap::new(), + entries: HashMap::with_hash_state(DefaultState), } } -} -impl<K: Clone + PartialEq + Eq + Hash, V: Clone> Cache<K,V> for HashCache<K,V> { - fn insert(&mut self, key: K, value: V) { + pub fn insert(&mut self, key: K, value: V) { self.entries.insert(key, value); } - fn find(&mut self, key: &K) -> Option<V> { + pub fn find(&self, key: &K) -> Option<V> { match self.entries.get(key) { Some(v) => Some(v.clone()), - None => None, + None => None, } } - fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V { + pub fn find_or_create<F>(&mut self, key: &K, blk: F) -> V where F: Fn(&K) -> V { match self.entries.entry(key.clone()) { Occupied(occupied) => { (*occupied.get()).clone() } Vacant(vacant) => { - (*vacant.set(blk(key))).clone() + (*vacant.insert(blk(key))).clone() } } } - fn evict_all(&mut self) { + pub fn evict_all(&mut self) { self.entries.clear(); } - -} - -impl<K,V> HashCache<K,V> where K: Clone + PartialEq + Eq + Hash, V: Clone { - pub fn find_equiv<'a,Sized? Q>(&'a self, key: &Q) -> Option<&'a V> where Q: Hash + Equiv<K> { - self.entries.find_equiv(key) - } } #[test] @@ -98,32 +88,30 @@ impl<K: Clone + PartialEq, V: Clone> LRUCache<K,V> { let last_index = self.entries.len() - 1; if pos != last_index { let entry = self.entries.remove(pos); - self.entries.push(entry.unwrap()); + self.entries.push(entry); } - self.entries[last_index].ref1().clone() + self.entries[last_index].1.clone() } - pub fn iter<'a>(&'a self) -> Items<'a,(K,V)> { + pub fn iter<'a>(&'a self) -> Iter<'a,(K,V)> { self.entries.iter() } -} -impl<K: Clone + PartialEq, V: Clone> Cache<K,V> for LRUCache<K,V> { - fn insert(&mut self, key: K, val: V) { + pub fn insert(&mut self, key: K, val: V) { if self.entries.len() == self.cache_size { self.entries.remove(0); } self.entries.push((key, val)); } - fn find(&mut self, key: &K) -> Option<V> { - match self.entries.iter().position(|&(ref k, _)| *k == *key) { + pub fn find(&mut self, key: &K) -> Option<V> { + match self.entries.iter().position(|&(ref k, _)| key == k) { Some(pos) => Some(self.touch(pos)), None => None, } } - fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V { + pub fn find_or_create<F>(&mut self, key: &K, blk: F) -> V where F: Fn(&K) -> V { match self.entries.iter().position(|&(ref k, _)| *k == *key) { Some(pos) => self.touch(pos), None => { @@ -134,7 +122,7 @@ impl<K: Clone + PartialEq, V: Clone> Cache<K,V> for LRUCache<K,V> { } } - fn evict_all(&mut self) { + pub fn evict_all(&mut self) { self.entries.clear(); } } @@ -145,9 +133,9 @@ pub struct SimpleHashCache<K,V> { k1: u64, } -impl<K:Clone+PartialEq+Hash,V:Clone> SimpleHashCache<K,V> { +impl<K:Clone+Eq+Hash<SipHasher>,V:Clone> SimpleHashCache<K,V> { pub fn new(cache_size: uint) -> SimpleHashCache<K,V> { - let mut r = task_rng(); + let mut r = rand::thread_rng(); SimpleHashCache { entries: repeat(None).take(cache_size).collect(), k0: r.gen(), @@ -161,35 +149,26 @@ impl<K:Clone+PartialEq+Hash,V:Clone> SimpleHashCache<K,V> { } #[inline] - fn bucket_for_key<Q:Hash>(&self, key: &Q) -> uint { - self.to_bucket(sip::hash_with_keys(self.k0, self.k1, key) as uint) + fn bucket_for_key<Q:Hash<SipHasher>>(&self, key: &Q) -> uint { + let mut hasher = SipHasher::new_with_keys(self.k0, self.k1); + key.hash(&mut hasher); + self.to_bucket(hasher.result() as uint) } - #[inline] - pub fn find_equiv<'a,Q:Hash+Equiv<K>>(&'a self, key: &Q) -> Option<&'a V> { - let bucket_index = self.bucket_for_key(key); - match self.entries[bucket_index] { - Some((ref existing_key, ref value)) if key.equiv(existing_key) => Some(value), - _ => None, - } - } -} - -impl<K:Clone+PartialEq+Hash,V:Clone> Cache<K,V> for SimpleHashCache<K,V> { - fn insert(&mut self, key: K, value: V) { + pub fn insert(&mut self, key: K, value: V) { let bucket_index = self.bucket_for_key(&key); self.entries[bucket_index] = Some((key, value)); } - fn find(&mut self, key: &K) -> Option<V> { + pub fn find<Q>(&self, key: &Q) -> Option<V> where Q: PartialEq<K> + Hash<SipHasher> + Eq { let bucket_index = self.bucket_for_key(key); match self.entries[bucket_index] { - Some((ref existing_key, ref value)) if existing_key == key => Some((*value).clone()), + Some((ref existing_key, ref value)) if key == existing_key => Some((*value).clone()), _ => None, } } - fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V { + pub fn find_or_create<F>(&mut self, key: &K, blk: F) -> V where F: Fn(&K) -> V { match self.find(key) { Some(value) => return value, None => {} @@ -199,7 +178,7 @@ impl<K:Clone+PartialEq+Hash,V:Clone> Cache<K,V> for SimpleHashCache<K,V> { value } - fn evict_all(&mut self) { + pub fn evict_all(&mut self) { for slot in self.entries.iter_mut() { *slot = None } diff --git a/components/util/cursor.rs b/components/util/cursor.rs index 23ca2c0af4a..ff203f1a0e7 100644 --- a/components/util/cursor.rs +++ b/components/util/cursor.rs @@ -8,10 +8,9 @@ use cssparser::ToCss; use std::ascii::AsciiExt; use text_writer::TextWriter; - macro_rules! define_cursor { ($( $css: expr => $variant: ident = $value: expr, )+) => { - #[deriving(Clone, Copy, PartialEq, Eq, FromPrimitive, Show)] + #[derive(Clone, Copy, PartialEq, Eq, FromPrimitive, Show)] #[repr(u8)] pub enum Cursor { $( $variant = $value ),+ @@ -19,7 +18,7 @@ macro_rules! define_cursor { impl Cursor { pub fn from_css_keyword(keyword: &str) -> Result<Cursor, ()> { - match_ignore_ascii_case! { keyword: + match_ignore_ascii_case! { keyword, $( concat!($css) => Ok(Cursor::$variant) ),+ _ => Err(()) } diff --git a/components/util/deque/mod.rs b/components/util/deque/mod.rs index b98c872cf0f..505b09ab021 100644 --- a/components/util/deque/mod.rs +++ b/components/util/deque/mod.rs @@ -54,12 +54,13 @@ pub use self::Stolen::{Empty, Abort, Data}; use alloc::arc::Arc; use alloc::heap::{allocate, deallocate}; -use std::kinds::marker; +use std::marker; use std::mem::{forget, min_align_of, size_of, transmute}; use std::ptr; use std::sync::Mutex; -use std::sync::atomic::{AtomicInt, AtomicPtr, SeqCst}; +use std::sync::atomic::{AtomicInt, AtomicPtr}; +use std::sync::atomic::Ordering::SeqCst; // Once the queue is less than 1/K full, then it will be downsized. Note that // the deque requires that this number be less than 2. @@ -97,7 +98,7 @@ pub struct Stealer<T> { } /// When stealing some data, this is an enumeration of the possible outcomes. -#[deriving(PartialEq, Show)] +#[derive(PartialEq, Show)] pub enum Stolen<T> { /// The deque was empty at the time of stealing Empty, @@ -141,6 +142,8 @@ struct Buffer<T> { log_size: uint, } +unsafe impl<T: 'static> Send for Buffer<T> { } + impl<T: Send> BufferPool<T> { /// Allocates a new buffer pool which in turn can be used to allocate new /// deques. @@ -159,16 +162,16 @@ impl<T: Send> BufferPool<T> { fn alloc(&mut self, bits: uint) -> Box<Buffer<T>> { unsafe { - let mut pool = self.pool.lock(); + let mut pool = self.pool.lock().unwrap(); match pool.iter().position(|x| x.size() >= (1 << bits)) { - Some(i) => pool.remove(i).unwrap(), + Some(i) => pool.remove(i), None => box Buffer::new(bits) } } } fn free(&self, buf: Box<Buffer<T>>) { - let mut pool = self.pool.lock(); + let mut pool = self.pool.lock().unwrap(); match pool.iter().position(|v| v.size() > buf.size()) { Some(i) => pool.insert(i, buf), None => pool.push(buf), @@ -403,256 +406,3 @@ impl<T: Send> Drop for Buffer<T> { unsafe { deallocate(self.storage as *mut u8, size, min_align_of::<T>()) } } } - -#[cfg(test)] -mod tests { - use super::{Data, BufferPool, Abort, Empty, Worker, Stealer}; - - use std::mem; - use rustrt::thread::Thread; - use std::rand; - use std::rand::Rng; - use std::sync::atomic::{AtomicBool, INIT_ATOMIC_BOOL, SeqCst, - AtomicUint, INIT_ATOMIC_UINT}; - use std::vec; - - #[test] - fn smoke() { - let pool = BufferPool::new(); - let (w, s) = pool.deque(); - assert_eq!(w.pop(), None); - assert_eq!(s.steal(), Empty); - w.push(1i); - assert_eq!(w.pop(), Some(1)); - w.push(1); - assert_eq!(s.steal(), Data(1)); - w.push(1); - assert_eq!(s.clone().steal(), Data(1)); - } - - #[test] - fn stealpush() { - static AMT: int = 100000; - let pool = BufferPool::<int>::new(); - let (w, s) = pool.deque(); - let t = Thread::start(proc() { - let mut left = AMT; - while left > 0 { - match s.steal() { - Data(i) => { - assert_eq!(i, 1); - left -= 1; - } - Abort | Empty => {} - } - } - }); - - for _ in range(0, AMT) { - w.push(1); - } - - t.join(); - } - - #[test] - fn stealpush_large() { - static AMT: int = 100000; - let pool = BufferPool::<(int, int)>::new(); - let (w, s) = pool.deque(); - let t = Thread::start(proc() { - let mut left = AMT; - while left > 0 { - match s.steal() { - Data((1, 10)) => { left -= 1; } - Data(..) => panic!(), - Abort | Empty => {} - } - } - }); - - for _ in range(0, AMT) { - w.push((1, 10)); - } - - t.join(); - } - - fn stampede(w: Worker<Box<int>>, s: Stealer<Box<int>>, - nthreads: int, amt: uint) { - for _ in range(0, amt) { - w.push(box 20); - } - let mut remaining = AtomicUint::new(amt); - let unsafe_remaining: *mut AtomicUint = &mut remaining; - - let threads = range(0, nthreads).map(|_| { - let s = s.clone(); - Thread::start(proc() { - unsafe { - while (*unsafe_remaining).load(SeqCst) > 0 { - match s.steal() { - Data(box 20) => { - (*unsafe_remaining).fetch_sub(1, SeqCst); - } - Data(..) => panic!(), - Abort | Empty => {} - } - } - } - }) - }).collect::<Vec<Thread<()>>>(); - - while remaining.load(SeqCst) > 0 { - match w.pop() { - Some(box 20) => { remaining.fetch_sub(1, SeqCst); } - Some(..) => panic!(), - None => {} - } - } - - for thread in threads.into_iter() { - thread.join(); - } - } - - #[test] - fn run_stampede() { - let pool = BufferPool::<Box<int>>::new(); - let (w, s) = pool.deque(); - stampede(w, s, 8, 10000); - } - - #[test] - fn many_stampede() { - static AMT: uint = 4; - let pool = BufferPool::<Box<int>>::new(); - let threads = range(0, AMT).map(|_| { - let (w, s) = pool.deque(); - Thread::start(proc() { - stampede(w, s, 4, 10000); - }) - }).collect::<Vec<Thread<()>>>(); - - for thread in threads.into_iter() { - thread.join(); - } - } - - #[test] - fn stress() { - static AMT: int = 100000; - static NTHREADS: int = 8; - static DONE: AtomicBool = INIT_ATOMIC_BOOL; - static HITS: AtomicUint = INIT_ATOMIC_UINT; - let pool = BufferPool::<int>::new(); - let (w, s) = pool.deque(); - - let threads = range(0, NTHREADS).map(|_| { - let s = s.clone(); - Thread::start(proc() { - loop { - match s.steal() { - Data(2) => { HITS.fetch_add(1, SeqCst); } - Data(..) => panic!(), - _ if DONE.load(SeqCst) => break, - _ => {} - } - } - }) - }).collect::<Vec<Thread<()>>>(); - - let mut rng = rand::task_rng(); - let mut expected = 0; - while expected < AMT { - if rng.gen_range(0i, 3) == 2 { - match w.pop() { - None => {} - Some(2) => { HITS.fetch_add(1, SeqCst); }, - Some(_) => panic!(), - } - } else { - expected += 1; - w.push(2); - } - } - - while HITS.load(SeqCst) < AMT as uint { - match w.pop() { - None => {} - Some(2) => { HITS.fetch_add(1, SeqCst); }, - Some(_) => panic!(), - } - } - DONE.store(true, SeqCst); - - for thread in threads.into_iter() { - thread.join(); - } - - assert_eq!(HITS.load(SeqCst), expected as uint); - } - - #[test] - #[cfg_attr(windows, ignore)] // apparently windows scheduling is weird? - fn no_starvation() { - static AMT: int = 10000; - static NTHREADS: int = 4; - static DONE: AtomicBool = INIT_ATOMIC_BOOL; - let pool = BufferPool::<(int, uint)>::new(); - let (w, s) = pool.deque(); - - let (threads, hits) = vec::unzip(range(0, NTHREADS).map(|_| { - let s = s.clone(); - let unique_box = box AtomicUint::new(0); - let thread_box = unsafe { - *mem::transmute::<&Box<AtomicUint>, - *const *mut AtomicUint>(&unique_box) - }; - (Thread::start(proc() { - unsafe { - loop { - match s.steal() { - Data((1, 2)) => { - (*thread_box).fetch_add(1, SeqCst); - } - Data(..) => panic!(), - _ if DONE.load(SeqCst) => break, - _ => {} - } - } - } - }), unique_box) - })); - - let mut rng = rand::task_rng(); - let mut myhit = false; - 'outer: loop { - for _ in range(0, rng.gen_range(0, AMT)) { - if !myhit && rng.gen_range(0i, 3) == 2 { - match w.pop() { - None => {} - Some((1, 2)) => myhit = true, - Some(_) => panic!(), - } - } else { - w.push((1, 2)); - } - } - - for slot in hits.iter() { - let amt = slot.load(SeqCst); - if amt == 0 { continue 'outer; } - } - if myhit { - break - } - } - - DONE.store(true, SeqCst); - - for thread in threads.into_iter() { - thread.join(); - } - } -} diff --git a/components/util/fnv.rs b/components/util/fnv.rs index 13c8e1c28ad..61b4cd73d48 100644 --- a/components/util/fnv.rs +++ b/components/util/fnv.rs @@ -4,7 +4,8 @@ //! This file stolen wholesale from rustc/src/librustc/util/nodemap.rs -pub use std::hash::{Hash, Hasher, Writer}; +use std::default::Default; +use std::hash::{Hasher, Writer}; /// A speedy hash algorithm for node ids and def ids. The hashmap in /// libcollections by default uses SipHash which isn't quite as speedy as we @@ -13,33 +14,26 @@ pub use std::hash::{Hash, Hasher, Writer}; /// /// This uses FNV hashing, as described here: /// http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function -#[deriving(Clone)] -pub struct FnvHasher; +#[allow(missing_copy_implementations)] +pub struct FnvHasher(u64); -pub struct FnvState(u64); +impl Default for FnvHasher { + fn default() -> FnvHasher { FnvHasher(0xcbf29ce484222325) } +} -impl Hasher<FnvState> for FnvHasher { - fn hash<Sized? T: Hash<FnvState>>(&self, t: &T) -> u64 { - let mut state = FnvState(0xcbf29ce484222325); - t.hash(&mut state); - let FnvState(ret) = state; - return ret; - } +impl Hasher for FnvHasher { + type Output = u64; + fn reset(&mut self) { *self = Default::default(); } + fn finish(&self) -> u64 { self.0 } } -impl Writer for FnvState { +impl Writer for FnvHasher { fn write(&mut self, bytes: &[u8]) { - let FnvState(mut hash) = *self; + let FnvHasher(mut hash) = *self; for byte in bytes.iter() { hash = hash ^ (*byte as u64); hash = hash * 0x100000001b3; } - *self = FnvState(hash); + *self = FnvHasher(hash); } } - -#[inline(always)] -pub fn hash<T: Hash<FnvState>>(t: &T) -> u64 { - let s = FnvHasher; - s.hash(t) -} diff --git a/components/util/geometry.rs b/components/util/geometry.rs index 5c3ee808b43..a30849eaf5d 100644 --- a/components/util/geometry.rs +++ b/components/util/geometry.rs @@ -8,11 +8,13 @@ use geom::rect::Rect; use geom::size::Size2D; use geom::num::Zero; -use serialize::{Encodable, Encoder}; use std::default::Default; use std::i32; -use std::num::{Float, NumCast}; +use std::num::{Float, NumCast, ToPrimitive}; use std::fmt; +use std::ops::{Add, Sub, Neg, Mul, Div, Rem}; + +use rustc_serialize::{Encoder, Encodable}; // Units for use with geom::length and geom::scale_factor. @@ -29,7 +31,7 @@ use std::fmt; /// /// The ratio between ScreenPx and DevicePixel for a given display be found by calling /// `servo::windowing::WindowMethods::hidpi_factor`. -#[deriving(Show, Copy)] +#[derive(Show, Copy)] pub enum ScreenPx {} /// One CSS "px" in the coordinate system of the "initial viewport": @@ -41,7 +43,7 @@ pub enum ScreenPx {} /// /// At the default zoom level of 100%, one PagePx is equal to one ScreenPx. However, if the /// document is zoomed in or out then this scale may be larger or smaller. -#[deriving(Encodable, Show, Copy)] +#[derive(RustcEncodable, Show, Copy)] pub enum ViewportPx {} /// One CSS "px" in the root coordinate system for the content document. @@ -50,7 +52,7 @@ pub enum ViewportPx {} /// This is the mobile-style "pinch zoom" that enlarges content without reflowing it. When the /// viewport zoom is not equal to 1.0, then the layout viewport is no longer the same physical size /// as the viewable area. -#[deriving(Encodable, Show, Copy)] +#[derive(RustcEncodable, Show, Copy)] pub enum PagePx {} // In summary, the hierarchy of pixel units and the factors to convert from one to the next: @@ -65,7 +67,7 @@ pub enum PagePx {} // See https://bugzilla.mozilla.org/show_bug.cgi?id=177805 for more info. // // FIXME: Implement Au using Length and ScaleFactor instead of a custom type. -#[deriving(Clone, Copy, Hash, PartialEq, PartialOrd, Eq, Ord)] +#[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Eq, Ord)] pub struct Au(pub i32); impl Default for Au { @@ -112,8 +114,8 @@ pub static MAX_RECT: Rect<Au> = Rect { pub const MIN_AU: Au = Au(i32::MIN); pub const MAX_AU: Au = Au(i32::MAX); -impl<E, S: Encoder<E>> Encodable<S, E> for Au { - fn encode(&self, e: &mut S) -> Result<(), E> { +impl Encodable for Au { + fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> { e.emit_f64(to_frac_px(*self)) } } @@ -123,53 +125,65 @@ impl fmt::Show for Au { write!(f, "{}px", to_frac_px(*self)) }} -impl Add<Au,Au> for Au { +impl Add for Au { + type Output = Au; + #[inline] - fn add(&self, other: &Au) -> Au { - let Au(s) = *self; - let Au(o) = *other; + fn add(self, other: Au) -> Au { + let Au(s) = self; + let Au(o) = other; Au(s + o) } } -impl Sub<Au,Au> for Au { +impl Sub for Au { + type Output = Au; + #[inline] - fn sub(&self, other: &Au) -> Au { - let Au(s) = *self; - let Au(o) = *other; + fn sub(self, other: Au) -> Au { + let Au(s) = self; + let Au(o) = other; Au(s - o) } } -impl Mul<i32, Au> for Au { +impl Mul<i32> for Au { + type Output = Au; + #[inline] - fn mul(&self, other: &i32) -> Au { - let Au(s) = *self; - Au(s * *other) + fn mul(self, other: i32) -> Au { + let Au(s) = self; + Au(s * other) } } -impl Div<i32, Au> for Au { +impl Div<i32> for Au { + type Output = Au; + #[inline] - fn div(&self, other: &i32) -> Au { - let Au(s) = *self; - Au(s / *other) + fn div(self, other: i32) -> Au { + let Au(s) = self; + Au(s / other) } } -impl Rem<i32, Au> for Au { +impl Rem<i32> for Au { + type Output = Au; + #[inline] - fn rem(&self, other: &i32) -> Au { - let Au(s) = *self; - Au(s % *other) + fn rem(self, other: i32) -> Au { + let Au(s) = self; + Au(s % other) } } -impl Neg<Au> for Au { +impl Neg for Au { + type Output = Au; + #[inline] - fn neg(&self) -> Au { - let Au(s) = *self; + fn neg(self) -> Au { + let Au(s) = self; Au(-s) } } @@ -323,7 +337,7 @@ pub fn to_pt(au: Au) -> f64 { /// Returns true if the rect contains the given point. Points on the top or left sides of the rect /// are considered inside the rectangle, while points on the right or bottom sides of the rect are /// not considered inside the rectangle. -pub fn rect_contains_point<T:PartialOrd + Add<T,T>>(rect: Rect<T>, point: Point2D<T>) -> bool { +pub fn rect_contains_point<T:PartialOrd + Add<T, Output=T>>(rect: Rect<T>, point: Point2D<T>) -> bool { point.x >= rect.origin.x && point.x < rect.origin.x + rect.size.width && point.y >= rect.origin.y && point.y < rect.origin.y + rect.size.height } diff --git a/components/util/lib.rs b/components/util/lib.rs index 9a97bdbbf78..bceab7a3014 100644 --- a/components/util/lib.rs +++ b/components/util/lib.rs @@ -2,15 +2,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#![feature(default_type_params,macro_rules,unsafe_destructor)] +#![feature(unsafe_destructor)] +#![feature(plugin)] +#![feature(int_uint)] +#![feature(old_impl_check)] +#![feature(box_syntax)] #![deny(unused_imports)] #![deny(unused_variables)] #![allow(missing_copy_implementations)] +#![allow(unstable)] -#![feature(phase)] -#[phase(plugin, link)] -extern crate log; +#[macro_use] extern crate log; extern crate alloc; extern crate collections; @@ -19,9 +22,9 @@ extern crate geom; extern crate getopts; extern crate layers; extern crate libc; +#[no_link] #[macro_use] extern crate cssparser; extern crate rand; -extern crate rustrt; -extern crate serialize; +extern crate "serialize" as rustc_serialize; #[cfg(target_os="macos")] extern crate task_info; extern crate "time" as std_time; @@ -30,9 +33,9 @@ extern crate string_cache; extern crate unicode; extern crate url; -#[phase(plugin)] extern crate plugins; -#[phase(plugin)] extern crate string_cache_macros; -#[phase(plugin)] extern crate lazy_static; +#[no_link] #[macro_use] #[plugin] +extern crate string_cache_macros; +extern crate lazy_static; use std::sync::Arc; diff --git a/components/util/logical_geometry.rs b/components/util/logical_geometry.rs index eebd0735b81..a76bd1ca21e 100644 --- a/components/util/logical_geometry.rs +++ b/components/util/logical_geometry.rs @@ -8,16 +8,17 @@ use geom::{Size2D, Point2D, SideOffsets2D, Rect}; use geom::num::Zero; use std::cmp::{min, max}; use std::fmt::{Show, Formatter, Error}; +use std::ops::{Add, Sub}; bitflags!( - #[deriving(Encodable, Copy)] + #[derive(RustcEncodable)] flags WritingMode: u8 { const FLAG_RTL = 1 << 0, const FLAG_VERTICAL = 1 << 1, const FLAG_VERTICAL_LR = 1 << 2, const FLAG_SIDEWAYS_LEFT = 1 << 3 } -) +); impl WritingMode { #[inline] @@ -79,11 +80,11 @@ impl Show for WritingMode { /// (in addition to taking it as a parameter to methods) and check it. /// In non-debug builds, make this storage zero-size and the checks no-ops. #[cfg(ndebug)] -#[deriving(Encodable, PartialEq, Eq, Clone, Copy)] +#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)] struct DebugWritingMode; #[cfg(not(ndebug))] -#[deriving(Encodable, PartialEq, Eq, Clone, Copy)] +#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)] struct DebugWritingMode { mode: WritingMode } @@ -134,7 +135,7 @@ impl Show for DebugWritingMode { /// A 2D size in flow-relative dimensions -#[deriving(Encodable, PartialEq, Eq, Clone, Copy)] +#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)] pub struct LogicalSize<T> { pub inline: T, // inline-size, a.k.a. logical width, a.k.a. measure pub block: T, // block-size, a.k.a. logical height, a.k.a. extent @@ -143,7 +144,7 @@ pub struct LogicalSize<T> { impl<T: Show> Show for LogicalSize<T> { fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> { - write!(formatter, "LogicalSize({}, i{}×b{})", + write!(formatter, "LogicalSize({:?}, i{:?}×b{:?})", self.debug_writing_mode, self.inline, self.block) } } @@ -240,9 +241,11 @@ impl<T: Copy> LogicalSize<T> { } } -impl<T: Add<T, T>> Add<LogicalSize<T>, LogicalSize<T>> for LogicalSize<T> { +impl<T: Add<T, Output=T>> Add for LogicalSize<T> { + type Output = LogicalSize<T>; + #[inline] - fn add(&self, other: &LogicalSize<T>) -> LogicalSize<T> { + fn add(self, other: LogicalSize<T>) -> LogicalSize<T> { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalSize { debug_writing_mode: self.debug_writing_mode, @@ -252,9 +255,11 @@ impl<T: Add<T, T>> Add<LogicalSize<T>, LogicalSize<T>> for LogicalSize<T> { } } -impl<T: Sub<T, T>> Sub<LogicalSize<T>, LogicalSize<T>> for LogicalSize<T> { +impl<T: Sub<T, Output=T>> Sub for LogicalSize<T> { + type Output = LogicalSize<T>; + #[inline] - fn sub(&self, other: &LogicalSize<T>) -> LogicalSize<T> { + fn sub(self, other: LogicalSize<T>) -> LogicalSize<T> { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalSize { debug_writing_mode: self.debug_writing_mode, @@ -266,7 +271,7 @@ impl<T: Sub<T, T>> Sub<LogicalSize<T>, LogicalSize<T>> for LogicalSize<T> { /// A 2D point in flow-relative dimensions -#[deriving(PartialEq, Encodable, Eq, Clone, Copy)] +#[derive(PartialEq, RustcEncodable, Eq, Clone, Copy)] pub struct LogicalPoint<T> { pub i: T, /// inline-axis coordinate pub b: T, /// block-axis coordinate @@ -275,7 +280,7 @@ pub struct LogicalPoint<T> { impl<T: Show> Show for LogicalPoint<T> { fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> { - write!(formatter, "LogicalPoint({} (i{}, b{}))", + write!(formatter, "LogicalPoint({:?} (i{:?}, b{:?}))", self.debug_writing_mode, self.i, self.b) } } @@ -303,7 +308,7 @@ impl<T: Copy> LogicalPoint<T> { } } -impl<T: Copy + Sub<T, T>> LogicalPoint<T> { +impl<T: Copy + Sub<T, Output=T>> LogicalPoint<T> { #[inline] pub fn from_physical(mode: WritingMode, point: Point2D<T>, container_size: Size2D<T>) -> LogicalPoint<T> { @@ -391,7 +396,7 @@ impl<T: Copy + Sub<T, T>> LogicalPoint<T> { } } -impl<T: Add<T,T>> LogicalPoint<T> { +impl<T: Copy + Add<T, Output=T>> LogicalPoint<T> { /// This doesn’t really makes sense, /// but happens when dealing with multiple origins. #[inline] @@ -405,9 +410,11 @@ impl<T: Add<T,T>> LogicalPoint<T> { } } -impl<T: Add<T,T>> Add<LogicalSize<T>, LogicalPoint<T>> for LogicalPoint<T> { +impl<T: Copy + Add<T,Output=T>> Add<LogicalSize<T>> for LogicalPoint<T> { + type Output = LogicalPoint<T>; + #[inline] - fn add(&self, other: &LogicalSize<T>) -> LogicalPoint<T> { + fn add(self, other: LogicalSize<T>) -> LogicalPoint<T> { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalPoint { debug_writing_mode: self.debug_writing_mode, @@ -417,9 +424,11 @@ impl<T: Add<T,T>> Add<LogicalSize<T>, LogicalPoint<T>> for LogicalPoint<T> { } } -impl<T: Sub<T,T>> Sub<LogicalSize<T>, LogicalPoint<T>> for LogicalPoint<T> { +impl<T: Copy + Sub<T,Output=T>> Sub<LogicalSize<T>> for LogicalPoint<T> { + type Output = LogicalPoint<T>; + #[inline] - fn sub(&self, other: &LogicalSize<T>) -> LogicalPoint<T> { + fn sub(self, other: LogicalSize<T>) -> LogicalPoint<T> { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalPoint { debug_writing_mode: self.debug_writing_mode, @@ -434,7 +443,7 @@ impl<T: Sub<T,T>> Sub<LogicalSize<T>, LogicalPoint<T>> for LogicalPoint<T> { /// Represents the four sides of the margins, borders, or padding of a CSS box, /// or a combination of those. /// A positive "margin" can be added to a rectangle to obtain a bigger rectangle. -#[deriving(Encodable, PartialEq, Eq, Clone, Copy)] +#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)] pub struct LogicalMargin<T> { pub block_start: T, pub inline_end: T, @@ -446,7 +455,7 @@ pub struct LogicalMargin<T> { impl<T: Show> Show for LogicalMargin<T> { fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> { write!(formatter, - "LogicalMargin({}, inline: {}..{} block: {}..{})", + "LogicalMargin({:?}, inline: {:?}..{:?} block: {:?}..{:?})", self.debug_writing_mode, self.inline_start, self.inline_end, @@ -656,7 +665,7 @@ impl<T: PartialEq + Zero> LogicalMargin<T> { } } -impl<T: Add<T, T>> LogicalMargin<T> { +impl<T: Copy + Add<T, Output=T>> LogicalMargin<T> { #[inline] pub fn inline_start_end(&self) -> T { self.inline_start + self.inline_end @@ -688,9 +697,11 @@ impl<T: Add<T, T>> LogicalMargin<T> { } } -impl<T: Add<T, T>> Add<LogicalMargin<T>, LogicalMargin<T>> for LogicalMargin<T> { +impl<T: Add<T, Output=T>> Add for LogicalMargin<T> { + type Output = LogicalMargin<T>; + #[inline] - fn add(&self, other: &LogicalMargin<T>) -> LogicalMargin<T> { + fn add(self, other: LogicalMargin<T>) -> LogicalMargin<T> { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalMargin { debug_writing_mode: self.debug_writing_mode, @@ -702,9 +713,11 @@ impl<T: Add<T, T>> Add<LogicalMargin<T>, LogicalMargin<T>> for LogicalMargin<T> } } -impl<T: Sub<T, T>> Sub<LogicalMargin<T>, LogicalMargin<T>> for LogicalMargin<T> { +impl<T: Sub<T, Output=T>> Sub for LogicalMargin<T> { + type Output = LogicalMargin<T>; + #[inline] - fn sub(&self, other: &LogicalMargin<T>) -> LogicalMargin<T> { + fn sub(self, other: LogicalMargin<T>) -> LogicalMargin<T> { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalMargin { debug_writing_mode: self.debug_writing_mode, @@ -718,7 +731,7 @@ impl<T: Sub<T, T>> Sub<LogicalMargin<T>, LogicalMargin<T>> for LogicalMargin<T> /// A rectangle in flow-relative dimensions -#[deriving(Encodable, PartialEq, Eq, Clone, Copy)] +#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)] pub struct LogicalRect<T> { pub start: LogicalPoint<T>, pub size: LogicalSize<T>, @@ -728,7 +741,7 @@ pub struct LogicalRect<T> { impl<T: Show> Show for LogicalRect<T> { fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> { write!(formatter, - "LogicalRect({}, i{}×b{}, @ (i{},b{}))", + "LogicalRect({:?}, i{:?}×b{:?}, @ (i{:?},b{:?}))", self.debug_writing_mode, self.size.inline, self.size.block, @@ -772,7 +785,7 @@ impl<T: Copy> LogicalRect<T> { } } -impl<T: Copy + Add<T, T> + Sub<T, T>> LogicalRect<T> { +impl<T: Copy + Add<T, Output=T> + Sub<T, Output=T>> LogicalRect<T> { #[inline] pub fn from_physical(mode: WritingMode, rect: Rect<T>, container_size: Size2D<T>) -> LogicalRect<T> { @@ -881,7 +894,7 @@ impl<T: Copy + Add<T, T> + Sub<T, T>> LogicalRect<T> { } } -impl<T: Copy + Ord + Add<T, T> + Sub<T, T>> LogicalRect<T> { +impl<T: Copy + Ord + Add<T, Output=T> + Sub<T, Output=T>> LogicalRect<T> { #[inline] pub fn union(&self, other: &LogicalRect<T>) -> LogicalRect<T> { self.debug_writing_mode.check_debug(other.debug_writing_mode); @@ -904,9 +917,11 @@ impl<T: Copy + Ord + Add<T, T> + Sub<T, T>> LogicalRect<T> { } } -impl<T: Add<T, T> + Sub<T, T>> Add<LogicalMargin<T>, LogicalRect<T>> for LogicalRect<T> { +impl<T: Copy + Add<T, Output=T> + Sub<T, Output=T>> Add<LogicalMargin<T>> for LogicalRect<T> { + type Output = LogicalRect<T>; + #[inline] - fn add(&self, other: &LogicalMargin<T>) -> LogicalRect<T> { + fn add(self, other: LogicalMargin<T>) -> LogicalRect<T> { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalRect { start: LogicalPoint { @@ -927,9 +942,11 @@ impl<T: Add<T, T> + Sub<T, T>> Add<LogicalMargin<T>, LogicalRect<T>> for Logical } -impl<T: Add<T, T> + Sub<T, T>> Sub<LogicalMargin<T>, LogicalRect<T>> for LogicalRect<T> { +impl<T: Copy + Add<T, Output=T> + Sub<T, Output=T>> Sub<LogicalMargin<T>> for LogicalRect<T> { + type Output = LogicalRect<T>; + #[inline] - fn sub(&self, other: &LogicalMargin<T>) -> LogicalRect<T> { + fn sub(self, other: LogicalMargin<T>) -> LogicalRect<T> { self.debug_writing_mode.check_debug(other.debug_writing_mode); LogicalRect { start: LogicalPoint { @@ -950,7 +967,7 @@ impl<T: Add<T, T> + Sub<T, T>> Sub<LogicalMargin<T>, LogicalRect<T>> for Logical } #[cfg(test)] -fn modes() -> [WritingMode, ..10] { +fn modes() -> [WritingMode; 10] { [ WritingMode::empty(), FLAG_VERTICAL, diff --git a/components/util/memory.rs b/components/util/memory.rs index 278a5a448fb..5e3033e2aa5 100644 --- a/components/util/memory.rs +++ b/components/util/memory.rs @@ -6,13 +6,16 @@ use libc::{c_char,c_int,c_void,size_t}; use std::borrow::ToOwned; +use std::ffi::CString; use std::io::timer::sleep; #[cfg(target_os="linux")] use std::io::File; +use std::mem; use std::mem::size_of; #[cfg(target_os="linux")] use std::os::page_size; use std::ptr::null_mut; +use std::sync::mpsc::{Sender, channel, Receiver}; use std::time::duration::Duration; use task::spawn_named; #[cfg(target_os="macos")] @@ -45,16 +48,16 @@ impl MemoryProfiler { Some(period) => { let period = Duration::milliseconds((period * 1000f64) as i64); let chan = chan.clone(); - spawn_named("Memory profiler timer".to_owned(), proc() { + spawn_named("Memory profiler timer".to_owned(), move || { loop { sleep(period); - if chan.send_opt(MemoryProfilerMsg::Print).is_err() { + if chan.send(MemoryProfilerMsg::Print).is_err() { break; } } }); // Spawn the memory profiler. - spawn_named("Memory profiler".to_owned(), proc() { + spawn_named("Memory profiler".to_owned(), move || { let memory_profiler = MemoryProfiler::new(port); memory_profiler.start(); }); @@ -62,9 +65,9 @@ impl MemoryProfiler { None => { // No-op to handle messages when the memory profiler is // inactive. - spawn_named("Memory profiler".to_owned(), proc() { + spawn_named("Memory profiler".to_owned(), move || { loop { - match port.recv_opt() { + match port.recv() { Err(_) | Ok(MemoryProfilerMsg::Exit) => break, _ => {} } @@ -84,7 +87,7 @@ impl MemoryProfiler { pub fn start(&self) { loop { - match self.port.recv_opt() { + match self.port.recv() { Ok(msg) => { if !self.handle_msg(msg) { break @@ -151,12 +154,13 @@ extern { fn get_jemalloc_stat(name: &'static str) -> Option<u64> { let mut old: size_t = 0; - let c_name = name.to_c_str(); + let c_name = CString::from_slice(name.as_bytes()); let oldp = &mut old as *mut _ as *mut c_void; let mut oldlen = size_of::<size_t>() as size_t; let rv: c_int; unsafe { - rv = je_mallctl(c_name.into_inner(), oldp, &mut oldlen, null_mut(), 0); + rv = je_mallctl(c_name.as_ptr(), oldp, &mut oldlen, null_mut(), 0); + mem::forget(c_name); // XXX correct? } if rv == 0 { Some(old as u64) } else { None } } @@ -164,7 +168,7 @@ fn get_jemalloc_stat(name: &'static str) -> Option<u64> { // Like std::macros::try!, but for Option<>. macro_rules! option_try( ($e:expr) => (match $e { Some(e) => e, None => return None }) -) +); #[cfg(target_os="linux")] fn get_proc_self_statm_field(field: uint) -> Option<u64> { @@ -172,7 +176,7 @@ fn get_proc_self_statm_field(field: uint) -> Option<u64> { match f.read_to_string() { Ok(contents) => { let s = option_try!(contents.as_slice().words().nth(field)); - let npages: u64 = option_try!(from_str(s)); + let npages: u64 = option_try!(s.parse()); Some(npages * (page_size() as u64)) } Err(_) => None diff --git a/components/util/opts.rs b/components/util/opts.rs index 1ed2eae0608..ae19723b975 100644 --- a/components/util/opts.rs +++ b/components/util/opts.rs @@ -20,7 +20,7 @@ use std::ptr; use std::rt; /// Global flags for Servo, currently set on the command line. -#[deriving(Clone)] +#[derive(Clone)] pub struct Opts { /// The initial URLs to load. pub urls: Vec<String>, @@ -241,31 +241,31 @@ pub fn from_cmdline_args(args: &[String]) -> bool { }; let tile_size: uint = match opt_match.opt_str("s") { - Some(tile_size_str) => from_str(tile_size_str.as_slice()).unwrap(), + Some(tile_size_str) => tile_size_str.parse().unwrap(), None => 512, }; let device_pixels_per_px = opt_match.opt_str("device-pixel-ratio").map(|dppx_str| - ScaleFactor(from_str(dppx_str.as_slice()).unwrap()) + ScaleFactor(dppx_str.parse().unwrap()) ); let mut n_paint_threads: uint = match opt_match.opt_str("t") { - Some(n_paint_threads_str) => from_str(n_paint_threads_str.as_slice()).unwrap(), + Some(n_paint_threads_str) => n_paint_threads_str.parse().unwrap(), None => 1, // FIXME: Number of cores. }; // If only the flag is present, default to a 5 second period for both profilers. let time_profiler_period = opt_match.opt_default("p", "5").map(|period| { - from_str(period.as_slice()).unwrap() + period.parse().unwrap() }); let memory_profiler_period = opt_match.opt_default("m", "5").map(|period| { - from_str(period.as_slice()).unwrap() + period.parse().unwrap() }); let gpu_painting = !FORCE_CPU_PAINTING && opt_match.opt_present("g"); let mut layout_threads: uint = match opt_match.opt_str("y") { - Some(layout_threads_str) => from_str(layout_threads_str.as_slice()).unwrap(), + Some(layout_threads_str) => layout_threads_str.parse().unwrap(), None => cmp::max(rt::default_sched_threads() * 3 / 4, 1), }; @@ -280,12 +280,12 @@ pub fn from_cmdline_args(args: &[String]) -> bool { } let devtools_port = opt_match.opt_default("devtools", "6000").map(|port| { - from_str(port.as_slice()).unwrap() + port.parse().unwrap() }); let initial_window_size = match opt_match.opt_str("resolution") { Some(res_string) => { - let res: Vec<uint> = res_string.as_slice().split('x').map(|r| from_str(r).unwrap()).collect(); + let res: Vec<uint> = res_string.split('x').map(|r| r.parse().unwrap()).collect(); TypedSize2D(res[0], res[1]) } None => { diff --git a/components/util/persistent_list.rs b/components/util/persistent_list.rs index 458c4c96a2a..f20edff3d38 100644 --- a/components/util/persistent_list.rs +++ b/components/util/persistent_list.rs @@ -74,7 +74,9 @@ pub struct PersistentListIterator<'a,T> where T: 'a + Send + Sync { entry: Option<&'a PersistentListEntry<T>>, } -impl<'a,T> Iterator<&'a T> for PersistentListIterator<'a,T> where T: Send + Sync { +impl<'a,T> Iterator for PersistentListIterator<'a,T> where T: Send + Sync { + type Item = &'a T; + #[inline] fn next(&mut self) -> Option<&'a T> { let entry = match self.entry { diff --git a/components/util/range.rs b/components/util/range.rs index ef6e7e0ff47..fbf14f38400 100644 --- a/components/util/range.rs +++ b/components/util/range.rs @@ -26,7 +26,7 @@ impl RangeIndex<int> for int { #[macro_export] macro_rules! int_range_index { ($(#[$attr:meta])* struct $Self:ident($T:ty)) => ( - #[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Show, Copy)] + #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Show, Copy)] $(#[$attr])* pub struct $Self(pub $T); @@ -74,40 +74,42 @@ macro_rules! int_range_index { } } - impl Add<$Self, $Self> for $Self { + impl Add<$Self> for $Self { + type Output = $Self; + #[inline] - fn add(&self, other: &$Self) -> $Self { + fn add(self, other: $Self) -> $Self { $Self(self.get() + other.get()) } } - impl Sub<$Self, $Self> for $Self { + impl Sub<$Self> for $Self { + type Output = $Self; + #[inline] - fn sub(&self, other: &$Self) -> $Self { + fn sub(self, other: $Self) -> $Self { $Self(self.get() - other.get()) } } - impl Mul<$Self, $Self> for $Self { + impl Mul<$Self> for $Self { + type Output = $Self; + #[inline] - fn mul(&self, other: &$Self) -> $Self { + fn mul(self, other: $Self) -> $Self { $Self(self.get() * other.get()) } } - impl Neg<$Self> for $Self { + impl Neg for $Self { + type Output = $Self; + #[inline] - fn neg(&self) -> $Self { + fn neg(self) -> $Self { $Self(-self.get()) } } - impl ::std::num::One for $Self { - fn one() -> $Self { - $Self(1) - } - } - impl ToPrimitive for $Self { fn to_i64(&self) -> Option<i64> { Some(self.get() as i64) @@ -124,66 +126,75 @@ macro_rules! int_range_index { } } - impl Div<$Self, $Self> for $Self { - fn div(&self, other: &$Self) -> $Self { + impl Div<$Self> for $Self { + type Output = $Self; + fn div(self, other: $Self) -> $Self { $Self(self.get() / other.get()) } } - impl Rem<$Self, $Self> for $Self { - fn rem(&self, other: &$Self) -> $Self { + impl Rem<$Self> for $Self { + type Output = $Self; + fn rem(self, other: $Self) -> $Self { $Self(self.get() % other.get()) } } - impl Not<$Self> for $Self { - fn not(&self) -> $Self { + impl Not for $Self { + type Output = $Self; + fn not(self) -> $Self { $Self(!self.get()) } } - impl BitAnd<$Self, $Self> for $Self { - fn bitand(&self, other: &$Self) -> $Self { + impl BitAnd<$Self> for $Self { + type Output = $Self; + fn bitand(self, other: $Self) -> $Self { $Self(self.get() & other.get()) } } - impl BitOr<$Self, $Self> for $Self { - fn bitor(&self, other: &$Self) -> $Self { + impl BitOr<$Self> for $Self { + type Output = $Self; + fn bitor(self, other: $Self) -> $Self { $Self(self.get() | other.get()) } } - impl BitXor<$Self, $Self> for $Self { - fn bitxor(&self, other: &$Self) -> $Self { + impl BitXor<$Self> for $Self { + type Output = $Self; + fn bitxor(self, other: $Self) -> $Self { $Self(self.get() ^ other.get()) } } - impl Shl<uint, $Self> for $Self { - fn shl(&self, n: &uint) -> $Self { - $Self(self.get() << *n) + impl Shl<uint> for $Self { + type Output = $Self; + fn shl(self, n: uint) -> $Self { + $Self(self.get() << n) } } - impl Shr<uint, $Self> for $Self { - fn shr(&self, n: &uint) -> $Self { - $Self(self.get() >> *n) + impl Shr<uint> for $Self { + type Output = $Self; + fn shr(self, n: uint) -> $Self { + $Self(self.get() >> n) } } ) } /// A range of indices -#[deriving(Clone, Encodable, Copy)] +#[derive(Clone, RustcEncodable, Copy)] pub struct Range<I> { begin: I, length: I, } +#[old_impl_check] impl<I: RangeIndex<T>, T> fmt::Show for Range<I> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "[{} .. {})", self.begin(), self.end()) + write!(f, "[{:?} .. {:?})", self.begin(), self.end()) } } @@ -196,7 +207,9 @@ pub fn each_index<T: Int, I: RangeIndex<T>>(start: I, stop: I) -> EachIndex<T, I EachIndex { it: iter::range(start.get(), stop.get()) } } -impl<T: Int, I: RangeIndex<T>> Iterator<I> for EachIndex<T, I> { +impl<T: Int, I: RangeIndex<T>> Iterator for EachIndex<T, I> { + type Item = I; + #[inline] fn next(&mut self) -> Option<I> { self.it.next().map(|i| RangeIndex::new(i)) @@ -208,6 +221,7 @@ impl<T: Int, I: RangeIndex<T>> Iterator<I> for EachIndex<T, I> { } } +#[old_impl_check] impl<I: RangeIndex<T>, T> Range<I> { /// Create a new range from beginning and length offsets. This could be /// denoted as `[begin, begin + length)`. @@ -345,6 +359,7 @@ impl<I: RangeIndex<T>, T> Range<I> { } /// Methods for `Range`s with indices based on integer values +#[old_impl_check] impl<T: Int, I: RangeIndex<T>> Range<I> { /// Returns an iterater that increments over `[begin, end)`. #[inline] @@ -363,8 +378,9 @@ impl<T: Int, I: RangeIndex<T>> Range<I> { && self.length() <= len }, None => { - debug!("Range<T>::is_valid_for_string: string length (len={}) is longer than the \ - max value for the range index (max={})", s_len, + debug!("Range<T>::is_valid_for_string: string length \ + (len={:?}) is longer than the max value for the range \ + index (max={:?})", s_len, { let max: T = Int::max_value(); let val: I = RangeIndex::new(max); diff --git a/components/util/smallvec.rs b/components/util/smallvec.rs index 2153398d3c3..efd1bfc7f35 100644 --- a/components/util/smallvec.rs +++ b/components/util/smallvec.rs @@ -9,7 +9,8 @@ use std::mem::zeroed as i; use std::cmp; use std::fmt; use std::intrinsics; -use std::kinds::marker::ContravariantLifetime; +use std::iter::FromIterator; +use std::marker::ContravariantLifetime; use std::mem; use std::ptr; use std::raw::Slice; @@ -249,7 +250,9 @@ pub struct SmallVecIterator<'a,T> { lifetime: ContravariantLifetime<'a> } -impl<'a,T> Iterator<&'a T> for SmallVecIterator<'a,T> { +impl<'a,T> Iterator for SmallVecIterator<'a,T> { + type Item = &'a T; + #[inline] fn next(&mut self) -> Option<&'a T> { unsafe { @@ -273,7 +276,9 @@ pub struct SmallVecMutIterator<'a,T> { lifetime: ContravariantLifetime<'a>, } -impl<'a,T> Iterator<&'a mut T> for SmallVecMutIterator<'a,T> { +impl<'a,T> Iterator for SmallVecMutIterator<'a,T> { + type Item = &'a mut T; + #[inline] fn next(&mut self) -> Option<&'a mut T> { unsafe { @@ -298,7 +303,9 @@ pub struct SmallVecMoveIterator<'a,T> { lifetime: ContravariantLifetime<'a>, } -impl<'a, T: 'a> Iterator<T> for SmallVecMoveIterator<'a,T> { +impl<'a, T: 'a> Iterator for SmallVecMoveIterator<'a,T> { + type Item = T; + #[inline] fn next(&mut self) -> Option<T> { unsafe { @@ -341,7 +348,7 @@ macro_rules! def_small_vector( len: uint, cap: uint, ptr: *const T, - data: [T, ..$size], + data: [T; $size], } impl<T> SmallVecPrivate<T> for $name<T> { @@ -403,7 +410,7 @@ macro_rules! def_small_vector( } impl<T> FromIterator<T> for $name<T> { - fn from_iter<I: Iterator<T>>(mut iter: I) -> $name<T> { + fn from_iter<I: Iterator<Item=T>>(mut iter: I) -> $name<T> { let mut v = $name::new(); let (lower_size_bound, _) = iter.size_hint(); @@ -421,7 +428,7 @@ macro_rules! def_small_vector( } impl<T> $name<T> { - pub fn extend<I: Iterator<T>>(&mut self, mut iter: I) { + pub fn extend<I: Iterator<Item=T>>(&mut self, mut iter: I) { let (lower_size_bound, _) = iter.size_hint(); let target_len = self.len() + lower_size_bound; @@ -438,7 +445,7 @@ macro_rules! def_small_vector( impl<T: fmt::Show> fmt::Show for $name<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.as_slice()) + write!(f, "{:?}", self.as_slice()) } } @@ -456,15 +463,15 @@ macro_rules! def_small_vector( } } ) -) +); -def_small_vector!(SmallVec1, 1) -def_small_vector!(SmallVec2, 2) -def_small_vector!(SmallVec4, 4) -def_small_vector!(SmallVec8, 8) -def_small_vector!(SmallVec16, 16) -def_small_vector!(SmallVec24, 24) -def_small_vector!(SmallVec32, 32) +def_small_vector!(SmallVec1, 1); +def_small_vector!(SmallVec2, 2); +def_small_vector!(SmallVec4, 4); +def_small_vector!(SmallVec8, 8); +def_small_vector!(SmallVec16, 16); +def_small_vector!(SmallVec24, 24); +def_small_vector!(SmallVec32, 32); macro_rules! def_small_vector_drop_impl( ($name:ident, $size:expr) => ( @@ -488,15 +495,15 @@ macro_rules! def_small_vector_drop_impl( } } ) -) +); -def_small_vector_drop_impl!(SmallVec1, 1) -def_small_vector_drop_impl!(SmallVec2, 2) -def_small_vector_drop_impl!(SmallVec4, 4) -def_small_vector_drop_impl!(SmallVec8, 8) -def_small_vector_drop_impl!(SmallVec16, 16) -def_small_vector_drop_impl!(SmallVec24, 24) -def_small_vector_drop_impl!(SmallVec32, 32) +def_small_vector_drop_impl!(SmallVec1, 1); +def_small_vector_drop_impl!(SmallVec2, 2); +def_small_vector_drop_impl!(SmallVec4, 4); +def_small_vector_drop_impl!(SmallVec8, 8); +def_small_vector_drop_impl!(SmallVec16, 16); +def_small_vector_drop_impl!(SmallVec24, 24); +def_small_vector_drop_impl!(SmallVec32, 32); macro_rules! def_small_vector_clone_impl( ($name:ident) => ( @@ -510,15 +517,15 @@ macro_rules! def_small_vector_clone_impl( } } ) -) - -def_small_vector_clone_impl!(SmallVec1) -def_small_vector_clone_impl!(SmallVec2) -def_small_vector_clone_impl!(SmallVec4) -def_small_vector_clone_impl!(SmallVec8) -def_small_vector_clone_impl!(SmallVec16) -def_small_vector_clone_impl!(SmallVec24) -def_small_vector_clone_impl!(SmallVec32) +); + +def_small_vector_clone_impl!(SmallVec1); +def_small_vector_clone_impl!(SmallVec2); +def_small_vector_clone_impl!(SmallVec4); +def_small_vector_clone_impl!(SmallVec8); +def_small_vector_clone_impl!(SmallVec16); +def_small_vector_clone_impl!(SmallVec24); +def_small_vector_clone_impl!(SmallVec32); #[cfg(test)] pub mod tests { diff --git a/components/util/sort.rs b/components/util/sort.rs index d31948cb0e8..ce7ab4d86c9 100644 --- a/components/util/sort.rs +++ b/components/util/sort.rs @@ -81,6 +81,7 @@ pub fn quicksort_by<T>(arr: &mut [T], compare: fn(&T, &T) -> Ordering) { #[cfg(test)] pub mod test { + use std::cmp::Ordering; use std::rand; use std::rand::Rng; @@ -88,7 +89,7 @@ pub mod test { #[test] pub fn random() { - let mut rng = rand::task_rng(); + let mut rng = rand::thread_rng(); for _ in range(0u32, 50000u32) { let len: uint = rng.gen(); let mut v: Vec<int> = rng.gen_iter::<int>().take((len % 32) + 1).collect(); diff --git a/components/util/str.rs b/components/util/str.rs index db5a6328cdb..352876919d4 100644 --- a/components/util/str.rs +++ b/components/util/str.rs @@ -5,12 +5,14 @@ use geometry::Au; use cssparser::{mod, RGBA, Color}; + +use libc::c_char; use std::ascii::AsciiExt; use std::borrow::ToOwned; +use std::ffi::c_str_to_bytes; use std::iter::Filter; -use std::num::Int; -use std::str::{CharEq, CharSplits, FromStr}; -use unicode::char::UnicodeChar; +use std::num::{Int, ToPrimitive}; +use std::str::{from_utf8, CharEq, FromStr, Split}; pub type DOMString = String; pub type StaticCharVec = &'static [char]; @@ -65,15 +67,16 @@ pub static HTML_SPACE_CHARACTERS: StaticCharVec = &[ '\u{000d}', ]; -pub fn split_html_space_chars<'a>(s: &'a str) - -> Filter<'a, &'a str, CharSplits<'a, StaticCharVec>> { - s.split(HTML_SPACE_CHARACTERS).filter(|&split| !split.is_empty()) +pub fn split_html_space_chars<'a>(s: &'a str) -> + Filter<&'a str, Split<'a, StaticCharVec>, fn(&&str) -> bool> { + fn not_empty(&split: &&str) -> bool { !split.is_empty() } + s.split(HTML_SPACE_CHARACTERS).filter(not_empty as fn(&&str) -> bool) } /// Shared implementation to parse an integer according to /// <http://www.whatwg.org/html/#rules-for-parsing-integers> or /// <http://www.whatwg.org/html/#rules-for-parsing-non-negative-integers>. -fn do_parse_integer<T: Iterator<char>>(input: T) -> Option<i64> { +fn do_parse_integer<T: Iterator<Item=char>>(input: T) -> Option<i64> { fn is_ascii_digit(c: &char) -> bool { match *c { '0'...'9' => true, @@ -118,7 +121,7 @@ fn do_parse_integer<T: Iterator<char>>(input: T) -> Option<i64> { /// Parse an integer according to /// <http://www.whatwg.org/html/#rules-for-parsing-integers>. -pub fn parse_integer<T: Iterator<char>>(input: T) -> Option<i32> { +pub fn parse_integer<T: Iterator<Item=char>>(input: T) -> Option<i32> { do_parse_integer(input).and_then(|result| { result.to_i32() }) @@ -126,13 +129,13 @@ pub fn parse_integer<T: Iterator<char>>(input: T) -> Option<i32> { /// Parse an integer according to /// <http://www.whatwg.org/html/#rules-for-parsing-non-negative-integers>. -pub fn parse_unsigned_integer<T: Iterator<char>>(input: T) -> Option<u32> { +pub fn parse_unsigned_integer<T: Iterator<Item=char>>(input: T) -> Option<u32> { do_parse_integer(input).and_then(|result| { result.to_u32() }) } -#[deriving(Copy)] +#[derive(Copy)] pub enum LengthOrPercentageOrAuto { Auto, Percentage(f64), @@ -141,14 +144,14 @@ pub enum LengthOrPercentageOrAuto { /// Parses a length per HTML5 § 2.4.4.4. If unparseable, `Auto` is returned. pub fn parse_length(mut value: &str) -> LengthOrPercentageOrAuto { - value = value.trim_left_chars(Whitespace); + value = value.trim_left_matches(Whitespace); if value.len() == 0 { return LengthOrPercentageOrAuto::Auto } if value.starts_with("+") { value = value.slice_from(1) } - value = value.trim_left_chars('0'); + value = value.trim_left_matches('0'); if value.len() == 0 { return LengthOrPercentageOrAuto::Auto } @@ -197,7 +200,7 @@ pub fn parse_legacy_color(mut input: &str) -> Result<RGBA,()> { } // Step 3. - input = input.trim_left_chars(Whitespace).trim_right_chars(Whitespace); + input = input.trim_left_matches(Whitespace).trim_right_matches(Whitespace); // Step 4. if input.eq_ignore_ascii_case("transparent") { @@ -321,7 +324,7 @@ pub fn parse_legacy_color(mut input: &str) -> Result<RGBA,()> { } -#[deriving(Clone, Eq, PartialEq, Hash, Show)] +#[derive(Clone, Eq, PartialEq, Hash, Show)] pub struct LowercaseString { inner: String, } @@ -340,3 +343,9 @@ impl Str for LowercaseString { self.inner.as_slice() } } + +/// Creates a String from the given null-terminated buffer. +/// Panics if the buffer does not contain UTF-8. +pub unsafe fn c_str_to_string(s: *const c_char) -> String { + from_utf8(c_str_to_bytes(&s)).unwrap().to_owned() +} diff --git a/components/util/task.rs b/components/util/task.rs index 44c2ff284dc..2045d0c3e83 100644 --- a/components/util/task.rs +++ b/components/util/task.rs @@ -3,33 +3,37 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use std::borrow::ToOwned; -use std::task; -use std::comm::Sender; -use std::task::TaskBuilder; use task_state; +use std::thread; +use std::sync::mpsc::Sender; +use std::thread::Builder; -pub fn spawn_named(name: String, f: proc():Send) { - let builder = task::TaskBuilder::new().named(name); - builder.spawn(proc() { - f(); +pub fn spawn_named<F>(name: String, f: F) + where F: FnOnce() + Send +{ + let builder = thread::Builder::new().name(name); + builder.spawn(move || { + f() }); } /// Arrange to send a particular message to a channel if the task fails. -pub fn spawn_named_with_send_on_failure<T: Send>(name: &'static str, - state: task_state::TaskState, - f: proc(): Send, - msg: T, - dest: Sender<T>) { - let future_result = TaskBuilder::new().named(name).try_future(proc() { +pub fn spawn_named_with_send_on_failure<F, T>(name: &'static str, + state: task_state::TaskState, + f: F, + msg: T, + dest: Sender<T>) + where F: FnOnce() + Send, + T: Send +{ + let future_handle = thread::Builder::new().name(name.to_owned()).scoped(move || { task_state::initialize(state); - f(); + f() }); - let watched_name = name.to_owned(); - let watcher_name = format!("{}Watcher", watched_name); - TaskBuilder::new().named(watcher_name).spawn(proc() { - match future_result.into_inner() { + let watcher_name = format!("{}Watcher", name); + Builder::new().name(watcher_name).spawn(move || { + match future_handle.join() { Ok(()) => (), Err(..) => { debug!("{} failed, notifying constellation", name); @@ -38,3 +42,10 @@ pub fn spawn_named_with_send_on_failure<T: Send>(name: &'static str, } }); } + +#[test] +fn spawn_named_test() { + spawn_named("Test".to_owned(), move || { + debug!("I can run!"); + }); +} diff --git a/components/util/task_state.rs b/components/util/task_state.rs index 3915eeb3059..ef1dbb2ed3e 100644 --- a/components/util/task_state.rs +++ b/components/util/task_state.rs @@ -11,7 +11,7 @@ pub use self::imp::{initialize, get, enter, exit}; bitflags! { - #[deriving(Show, Copy)] + #[derive(Show)] flags TaskState: u32 { const SCRIPT = 0x01, const LAYOUT = 0x02, @@ -35,7 +35,7 @@ macro_rules! task_types ( ( $( $fun:ident = $flag:ident ; )* ) => ( #[cfg(not(ndebug))] static TYPES: &'static [TaskState] = &[ $( $flag ),* ]; -)) +)); task_types! { is_script = SCRIPT; @@ -48,12 +48,12 @@ mod imp { use super::{TaskState, TYPES}; use std::cell::RefCell; - thread_local!(static STATE: RefCell<Option<TaskState>> = RefCell::new(None)) + thread_local!(static STATE: RefCell<Option<TaskState>> = RefCell::new(None)); pub fn initialize(x: TaskState) { STATE.with(|ref k| { match *k.borrow() { - Some(s) => panic!("Task state already initialized as {}", s), + Some(s) => panic!("Task state already initialized as {:?}", s), None => () }; *k.borrow_mut() = Some(x); diff --git a/components/util/taskpool.rs b/components/util/taskpool.rs index 8521ef9dc93..7f2d36be936 100644 --- a/components/util/taskpool.rs +++ b/components/util/taskpool.rs @@ -17,9 +17,11 @@ use task::spawn_named; use std::sync::{Arc, Mutex}; +use std::sync::mpsc::{channel, Sender, Receiver}; +use std::thunk::Thunk; pub struct TaskPool { - tx: Sender<proc():Send>, + tx: Sender<Thunk<()>>, } impl TaskPool { @@ -33,23 +35,25 @@ impl TaskPool { let state = state.clone(); spawn_named( format!("TaskPoolWorker {}/{}", i+1, tasks), - proc() worker(&*state)); + move || worker(&*state)); } return TaskPool { tx: tx }; - fn worker(rx: &Mutex<Receiver<proc():Send>>) { + fn worker(rx: &Mutex<Receiver<Thunk<()>>>) { loop { - let job = rx.lock().recv_opt(); + let job = rx.lock().unwrap().recv(); match job { - Ok(job) => job(), + Ok(job) => job.invoke(()), Err(..) => break, } } } } - pub fn execute(&self, job: proc():Send) { - self.tx.send(job); + pub fn execute<F>(&self, job: F) + where F: FnOnce() + Send + { + self.tx.send(Thunk::new(job)); } } diff --git a/components/util/tid.rs b/components/util/tid.rs index 62723941fcb..e52dbf7fd61 100644 --- a/components/util/tid.rs +++ b/components/util/tid.rs @@ -2,13 +2,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use std::sync::atomic::{AtomicUint, INIT_ATOMIC_UINT, Ordering}; +use std::sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Ordering}; use std::rc::Rc; use std::cell::RefCell; -static mut next_tid: AtomicUint = INIT_ATOMIC_UINT; +static mut next_tid: AtomicUint = ATOMIC_UINT_INIT; -thread_local!(static TASK_LOCAL_TID: Rc<RefCell<Option<uint>>> = Rc::new(RefCell::new(None))) +thread_local!(static TASK_LOCAL_TID: Rc<RefCell<Option<uint>>> = Rc::new(RefCell::new(None))); /// Every task gets one, that's unique. pub fn tid() -> uint { diff --git a/components/util/time.rs b/components/util/time.rs index a47f3a98c8c..b5805dfa092 100644 --- a/components/util/time.rs +++ b/components/util/time.rs @@ -4,21 +4,21 @@ //! Timing functions. -use collections::TreeMap; +use collections::BTreeMap; use std::borrow::ToOwned; use std::cmp::Ordering; -use std::comm::{Sender, channel, Receiver}; use std::f64; use std::io::timer::sleep; use std::iter::AdditiveIterator; -use std::num::FloatMath; +use std::num::Float; +use std::sync::mpsc::{Sender, channel, Receiver}; use std::time::duration::Duration; use std_time::precise_time_ns; use task::{spawn_named}; use url::Url; // front-end representation of the profiler used to communicate with the profiler -#[deriving(Clone)] +#[derive(Clone)] pub struct TimeProfilerChan(pub Sender<TimeProfilerMsg>); impl TimeProfilerChan { @@ -28,7 +28,7 @@ impl TimeProfilerChan { } } -#[deriving(PartialEq, Clone, PartialOrd, Eq, Ord)] +#[derive(PartialEq, Clone, PartialOrd, Eq, Ord)] pub struct TimerMetadata { url: String, iframe: bool, @@ -60,7 +60,7 @@ impl Formatable for Option<TimerMetadata> { } } -#[deriving(Clone)] +#[derive(Clone)] pub enum TimeProfilerMsg { /// Normal message used for reporting time Time((TimeProfilerCategory, Option<TimerMetadata>), f64), @@ -71,7 +71,7 @@ pub enum TimeProfilerMsg { } #[repr(u32)] -#[deriving(PartialEq, Clone, PartialOrd, Eq, Ord)] +#[derive(PartialEq, Clone, PartialOrd, Eq, Ord)] pub enum TimeProfilerCategory { Compositing, LayoutPerform, @@ -130,7 +130,7 @@ impl Formatable for TimeProfilerCategory { } } -type TimeProfilerBuckets = TreeMap<(TimeProfilerCategory, Option<TimerMetadata>), Vec<f64>>; +type TimeProfilerBuckets = BTreeMap<(TimeProfilerCategory, Option<TimerMetadata>), Vec<f64>>; // back end of the profiler that handles data aggregation and performance metrics pub struct TimeProfiler { @@ -146,25 +146,25 @@ impl TimeProfiler { Some(period) => { let period = Duration::milliseconds((period * 1000f64) as i64); let chan = chan.clone(); - spawn_named("Time profiler timer".to_owned(), proc() { + spawn_named("Time profiler timer".to_owned(), move || { loop { sleep(period); - if chan.send_opt(TimeProfilerMsg::Print).is_err() { + if chan.send(TimeProfilerMsg::Print).is_err() { break; } } }); // Spawn the time profiler. - spawn_named("Time profiler".to_owned(), proc() { + spawn_named("Time profiler".to_owned(), move || { let mut profiler = TimeProfiler::new(port); profiler.start(); }); } None => { // No-op to handle messages when the time profiler is inactive. - spawn_named("Time profiler".to_owned(), proc() { + spawn_named("Time profiler".to_owned(), move || { loop { - match port.recv_opt() { + match port.recv() { Err(_) | Ok(TimeProfilerMsg::Exit) => break, _ => {} } @@ -179,14 +179,14 @@ impl TimeProfiler { pub fn new(port: Receiver<TimeProfilerMsg>) -> TimeProfiler { TimeProfiler { port: port, - buckets: TreeMap::new(), + buckets: BTreeMap::new(), last_msg: None, } } pub fn start(&mut self) { loop { - let msg = self.port.recv_opt(); + let msg = self.port.recv(); match msg { Ok(msg) => { if !self.handle_msg(msg) { @@ -249,13 +249,13 @@ impl TimeProfiler { } } -#[deriving(Eq, PartialEq)] +#[derive(Eq, PartialEq)] pub enum TimerMetadataFrameType { RootWindow, IFrame, } -#[deriving(Eq, PartialEq)] +#[derive(Eq, PartialEq)] pub enum TimerMetadataReflowType { Incremental, FirstReflow, @@ -263,11 +263,13 @@ pub enum TimerMetadataReflowType { pub type ProfilerMetadata<'a> = Option<(&'a Url, TimerMetadataFrameType, TimerMetadataReflowType)>; -pub fn profile<T>(category: TimeProfilerCategory, - meta: ProfilerMetadata, - time_profiler_chan: TimeProfilerChan, - callback: || -> T) - -> T { +pub fn profile<T, F>(category: TimeProfilerCategory, + meta: ProfilerMetadata, + time_profiler_chan: TimeProfilerChan, + callback: F) + -> T + where F: FnOnce() -> T +{ let start_time = precise_time_ns(); let val = callback(); let end_time = precise_time_ns(); @@ -282,7 +284,9 @@ pub fn profile<T>(category: TimeProfilerCategory, return val; } -pub fn time<T>(msg: &str, callback: || -> T) -> T{ +pub fn time<T, F>(msg: &str, callback: F) -> T + where F: Fn() -> T +{ let start_time = precise_time_ns(); let val = callback(); let end_time = precise_time_ns(); diff --git a/components/util/vec.rs b/components/util/vec.rs index c34b76a9794..a902a3133df 100644 --- a/components/util/vec.rs +++ b/components/util/vec.rs @@ -78,7 +78,7 @@ fn test_miss_all_elems<T: PartialEq + PartialOrd + Eq + Ord + Show>(arr: &[T], m let mut i = 0; while i < misses.len() { let res = arr.binary_search_(&misses[i]); - debug!("{} == {} ?", misses[i], res); + debug!("{:?} == {:?} ?", misses[i], res); assert!(!test_match(&misses[i], arr.binary_search_(&misses[i]))); i += 1; } diff --git a/components/util/workqueue.rs b/components/util/workqueue.rs index ee14a4d1a50..c83902526fd 100644 --- a/components/util/workqueue.rs +++ b/components/util/workqueue.rs @@ -15,6 +15,7 @@ use rand::{Rng, XorShiftRng}; use std::mem; use std::rand::weak_rng; use std::sync::atomic::{AtomicUint, Ordering}; +use std::sync::mpsc::{channel, Sender, Receiver}; use deque::{Abort, BufferPool, Data, Empty, Stealer, Worker}; /// A unit of work. @@ -31,7 +32,7 @@ pub struct WorkUnit<QueueData, WorkData> { } /// Messages from the supervisor to the worker. -enum WorkerMsg<QueueData, WorkData> { +enum WorkerMsg<QueueData: 'static, WorkData: 'static> { /// Tells the worker to start work. Start(Worker<WorkUnit<QueueData, WorkData>>, *mut AtomicUint, *const QueueData), /// Tells the worker to stop. It can be restarted again with a `WorkerMsg::Start`. @@ -40,14 +41,18 @@ enum WorkerMsg<QueueData, WorkData> { Exit, } +unsafe impl<QueueData: 'static, WorkData: 'static> Send for WorkerMsg<QueueData, WorkData> {} + /// Messages to the supervisor. -enum SupervisorMsg<QueueData, WorkData> { +enum SupervisorMsg<QueueData: 'static, WorkData: 'static> { Finished, ReturnDeque(uint, Worker<WorkUnit<QueueData, WorkData>>), } +unsafe impl<QueueData: 'static, WorkData: 'static> Send for SupervisorMsg<QueueData, WorkData> {} + /// Information that the supervisor thread keeps about the worker threads. -struct WorkerInfo<QueueData, WorkData> { +struct WorkerInfo<QueueData: 'static, WorkData: 'static> { /// The communication channel to the workers. chan: Sender<WorkerMsg<QueueData, WorkData>>, /// The worker end of the deque, if we have it. @@ -57,7 +62,7 @@ struct WorkerInfo<QueueData, WorkData> { } /// Information specific to each worker thread that the thread keeps. -struct WorkerThread<QueueData, WorkData> { +struct WorkerThread<QueueData: 'static, WorkData: 'static> { /// The index of this worker. index: uint, /// The communication port from the supervisor. @@ -70,6 +75,8 @@ struct WorkerThread<QueueData, WorkData> { rng: XorShiftRng, } +unsafe impl<QueueData: 'static, WorkData: 'static> Send for WorkerThread<QueueData, WorkData> {} + static SPIN_COUNT: u32 = 128; static SPINS_UNTIL_BACKOFF: u32 = 100; static BACKOFF_INCREMENT_IN_US: u32 = 5; @@ -80,7 +87,7 @@ impl<QueueData: Send, WorkData: Send> WorkerThread<QueueData, WorkData> { fn start(&mut self) { loop { // Wait for a start message. - let (mut deque, ref_count, queue_data) = match self.port.recv() { + let (mut deque, ref_count, queue_data) = match self.port.recv().unwrap() { WorkerMsg::Start(deque, ref_count, queue_data) => (deque, ref_count, queue_data), WorkerMsg::Stop => panic!("unexpected stop message"), WorkerMsg::Exit => return, @@ -158,13 +165,13 @@ impl<QueueData: Send, WorkData: Send> WorkerThread<QueueData, WorkData> { // the last work unit in the queue, then send a message on the channel. unsafe { if (*ref_count).fetch_sub(1, Ordering::SeqCst) == 1 { - self.chan.send(SupervisorMsg::Finished) + self.chan.send(SupervisorMsg::Finished).unwrap() } } } // Give the deque back to the supervisor. - self.chan.send(SupervisorMsg::ReturnDeque(self.index, deque)) + self.chan.send(SupervisorMsg::ReturnDeque(self.index, deque)).unwrap() } } } @@ -196,7 +203,7 @@ impl<'a, QueueData: 'static, WorkData: Send> WorkerProxy<'a, QueueData, WorkData } /// A work queue on which units of work can be submitted. -pub struct WorkQueue<QueueData, WorkData> { +pub struct WorkQueue<QueueData: 'static, WorkData: 'static> { /// Information about each of the workers. workers: Vec<WorkerInfo<QueueData, WorkData>>, /// A port on which deques can be received from the workers. @@ -250,7 +257,7 @@ impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> { spawn_named( format!("{} worker {}/{}", task_name, i+1, thread_count), - proc() { + move || { task_state::initialize(state | task_state::IN_WORKER); let mut thread = thread; thread.start() @@ -283,7 +290,7 @@ impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> { // Tell the workers to start. let mut work_count = AtomicUint::new(self.work_count); for worker in self.workers.iter_mut() { - worker.chan.send(WorkerMsg::Start(worker.deque.take().unwrap(), &mut work_count, &self.data)) + worker.chan.send(WorkerMsg::Start(worker.deque.take().unwrap(), &mut work_count, &self.data)).unwrap() } // Wait for the work to finish. @@ -292,12 +299,12 @@ impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> { // Tell everyone to stop. for worker in self.workers.iter() { - worker.chan.send(WorkerMsg::Stop) + worker.chan.send(WorkerMsg::Stop).unwrap() } // Get our deques back. for _ in range(0, self.workers.len()) { - match self.port.recv() { + match self.port.recv().unwrap() { SupervisorMsg::ReturnDeque(index, deque) => self.workers[index].deque = Some(deque), SupervisorMsg::Finished => panic!("unexpected finished message!"), } @@ -306,7 +313,7 @@ impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> { pub fn shutdown(&mut self) { for worker in self.workers.iter() { - worker.chan.send(WorkerMsg::Exit) + worker.chan.send(WorkerMsg::Exit).unwrap() } } } |