servo: Merge #10918 - Avoid some clones (from Ms2ger:clones); r=SimonSapin
authorMs2ger <Ms2ger@gmail.com>
Fri, 29 Apr 2016 06:33:34 -0700
changeset 338662 469552340c1654bec34dc3dc90ad4e71f6c1db70
parent 338661 8c96e9b12f5356049432a471d2e003e95a088e40
child 338663 ceee6f2a1ab66537339fc1442a820b9be37462e2
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersSimonSapin
servo: Merge #10918 - Avoid some clones (from Ms2ger:clones); r=SimonSapin Source-Repo: https://github.com/servo/servo Source-Revision: 9770e3c1e37a29c4b01ebfc243db2c7be58ec006
servo/components/script/document_loader.rs
servo/components/script/dom/bindings/global.rs
servo/components/script/dom/document.rs
servo/components/script/dom/htmlbodyelement.rs
servo/components/script/dom/htmliframeelement.rs
servo/components/script/dom/htmlinputelement.rs
servo/components/script/dom/htmllinkelement.rs
servo/components/script/dom/htmlstyleelement.rs
servo/components/script/dom/htmltextareaelement.rs
servo/components/script/dom/node.rs
servo/components/script/dom/servohtmlparser.rs
servo/components/script/dom/window.rs
servo/components/script/dom/worker.rs
servo/components/script/dom/workerglobalscope.rs
servo/components/script/script_thread.rs
--- a/servo/components/script/document_loader.rs
+++ b/servo/components/script/document_loader.rs
@@ -141,18 +141,18 @@ impl DocumentLoader {
 
     /// Create and initiate a new network request.
     pub fn load_async(&mut self, load: LoadType, listener: AsyncResponseTarget, referrer: &Document) {
         let pending = self.prepare_async_load(load, referrer);
         pending.load_async(listener)
     }
 
     /// Mark an in-progress network request complete.
-    pub fn finish_load(&mut self, load: LoadType) {
-        let idx = self.blocking_loads.iter().position(|unfinished| *unfinished == load);
+    pub fn finish_load(&mut self, load: &LoadType) {
+        let idx = self.blocking_loads.iter().position(|unfinished| *unfinished == *load);
         self.blocking_loads.remove(idx.expect(&format!("unknown completed load {:?}", load)));
     }
 
     pub fn is_blocked(&self) -> bool {
         // TODO: Ensure that we report blocked if parsing is still ongoing.
         !self.blocking_loads.is_empty()
     }
 
--- a/servo/components/script/dom/bindings/global.rs
+++ b/servo/components/script/dom/bindings/global.rs
@@ -69,33 +69,33 @@ impl<'a> GlobalRef<'a> {
     pub fn pipeline(&self) -> PipelineId {
         match *self {
             GlobalRef::Window(window) => window.pipeline(),
             GlobalRef::Worker(worker) => worker.pipeline(),
         }
     }
 
     /// Get a `mem::ProfilerChan` to send messages to the memory profiler thread.
-    pub fn mem_profiler_chan(&self) -> mem::ProfilerChan {
+    pub fn mem_profiler_chan(&self) -> &mem::ProfilerChan {
         match *self {
             GlobalRef::Window(window) => window.mem_profiler_chan(),
             GlobalRef::Worker(worker) => worker.mem_profiler_chan(),
         }
     }
 
     /// Get a `ConstellationChan` to send messages to the constellation channel when available.
-    pub fn constellation_chan(&self) -> ConstellationChan<ConstellationMsg> {
+    pub fn constellation_chan(&self) -> &ConstellationChan<ConstellationMsg> {
         match *self {
             GlobalRef::Window(window) => window.constellation_chan(),
             GlobalRef::Worker(worker) => worker.constellation_chan(),
         }
     }
 
     /// Get the scheduler channel to request timer events.
-    pub fn scheduler_chan(&self) -> IpcSender<TimerEventRequest> {
+    pub fn scheduler_chan(&self) -> &IpcSender<TimerEventRequest> {
         match *self {
             GlobalRef::Window(window) => window.scheduler_chan(),
             GlobalRef::Worker(worker) => worker.scheduler_chan(),
         }
     }
 
     /// Get an `IpcSender<ScriptToDevtoolsControlMsg>` to send messages to Devtools
     /// thread when available.
--- a/servo/components/script/dom/document.rs
+++ b/servo/components/script/dom/document.rs
@@ -396,17 +396,17 @@ impl Document {
     pub fn quirks_mode(&self) -> QuirksMode {
         self.quirks_mode.get()
     }
 
     pub fn set_quirks_mode(&self, mode: QuirksMode) {
         self.quirks_mode.set(mode);
 
         if mode == Quirks {
-            let LayoutChan(ref layout_chan) = self.window.layout_chan();
+            let LayoutChan(ref layout_chan) = *self.window.layout_chan();
             layout_chan.send(Msg::SetQuirksMode).unwrap();
         }
     }
 
     pub fn encoding(&self) -> EncodingRef {
         self.encoding.get()
     }
 
@@ -610,17 +610,17 @@ impl Document {
         if let Some(ref elem) = self.focused.get() {
             elem.set_focus_state(true);
             let node = elem.upcast::<Node>();
             // FIXME: pass appropriate relatedTarget
             self.fire_focus_event(FocusEventType::Focus, node, None);
             // Update the focus state for all elements in the focus chain.
             // https://html.spec.whatwg.org/multipage/#focus-chain
             if focus_type == FocusType::Element {
-                let ConstellationChan(ref chan) = self.window.constellation_chan();
+                let ConstellationChan(ref chan) = *self.window.constellation_chan();
                 let event = ConstellationMsg::Focus(self.window.pipeline());
                 chan.send(event).unwrap();
             }
         }
     }
 
     /// Handles any updates when the document's title has changed.
     pub fn title_changed(&self) {
@@ -1255,46 +1255,46 @@ impl Document {
 
     pub fn push_asap_in_order_script(&self, script: &HTMLScriptElement) {
         self.asap_in_order_scripts_list.borrow_mut().push(JS::from_ref(script));
     }
 
     pub fn trigger_mozbrowser_event(&self, event: MozBrowserEvent) {
         if htmliframeelement::mozbrowser_enabled() {
             if let Some((containing_pipeline_id, subpage_id)) = self.window.parent_info() {
-                let ConstellationChan(ref chan) = self.window.constellation_chan();
+                let ConstellationChan(ref chan) = *self.window.constellation_chan();
                 let event = ConstellationMsg::MozBrowserEvent(containing_pipeline_id,
                                                               subpage_id,
                                                               event);
                 chan.send(event).unwrap();
             }
         }
     }
 
     /// https://html.spec.whatwg.org/multipage/#dom-window-requestanimationframe
     pub fn request_animation_frame(&self, callback: Box<FnBox(f64)>) -> u32 {
         let ident = self.animation_frame_ident.get() + 1;
 
         self.animation_frame_ident.set(ident);
         self.animation_frame_list.borrow_mut().insert(ident, callback);
 
         // TODO: Should tick animation only when document is visible
-        let ConstellationChan(ref chan) = self.window.constellation_chan();
+        let ConstellationChan(ref chan) = *self.window.constellation_chan();
         let event = ConstellationMsg::ChangeRunningAnimationsState(self.window.pipeline(),
                                                                    AnimationState::AnimationCallbacksPresent);
         chan.send(event).unwrap();
 
         ident
     }
 
     /// https://html.spec.whatwg.org/multipage/#dom-window-cancelanimationframe
     pub fn cancel_animation_frame(&self, ident: u32) {
         self.animation_frame_list.borrow_mut().remove(&ident);
         if self.animation_frame_list.borrow().is_empty() {
-            let ConstellationChan(ref chan) = self.window.constellation_chan();
+            let ConstellationChan(ref chan) = *self.window.constellation_chan();
             let event = ConstellationMsg::ChangeRunningAnimationsState(self.window.pipeline(),
                                                                        AnimationState::NoAnimationCallbacksPresent);
             chan.send(event).unwrap();
         }
     }
 
     /// https://html.spec.whatwg.org/multipage/#run-the-animation-frame-callbacks
     pub fn run_the_animation_frame_callbacks(&self) {
@@ -1308,17 +1308,17 @@ impl Document {
             callback(*timing);
         }
 
         // Only send the animation change state message after running any callbacks.
         // This means that if the animation callback adds a new callback for
         // the next frame (which is the common case), we won't send a NoAnimationCallbacksPresent
         // message quickly followed by an AnimationCallbacksPresent message.
         if self.animation_frame_list.borrow().is_empty() {
-            let ConstellationChan(ref chan) = self.window.constellation_chan();
+            let ConstellationChan(ref chan) = *self.window.constellation_chan();
             let event = ConstellationMsg::ChangeRunningAnimationsState(self.window.pipeline(),
                                                                        AnimationState::NoAnimationCallbacksPresent);
             chan.send(event).unwrap();
         }
 
         self.window.reflow(ReflowGoal::ForDisplay,
                            ReflowQueryType::NoQuery,
                            ReflowReason::RequestAnimationFrame);
@@ -1339,17 +1339,17 @@ impl Document {
         let mut loader = self.loader.borrow_mut();
         loader.load_async(load, listener, self)
     }
 
     pub fn finish_load(&self, load: LoadType) {
         // The parser might need the loader, so restrict the lifetime of the borrow.
         {
             let mut loader = self.loader.borrow_mut();
-            loader.finish_load(load.clone());
+            loader.finish_load(&load);
         }
 
         if let LoadType::Script(_) = load {
             self.process_deferred_scripts();
             self.process_asap_scripts();
         }
 
         if self.maybe_execute_parser_blocking_script() == ParserBlockedByScript::Blocked {
@@ -1468,17 +1468,17 @@ impl Document {
                              ReflowQueryType::NoQuery,
                              ReflowReason::DOMContentLoaded);
 
         update_with_current_time_ms(&self.dom_content_loaded_event_end);
     }
 
     pub fn notify_constellation_load(&self) {
         let pipeline_id = self.window.pipeline();
-        let ConstellationChan(ref chan) = self.window.constellation_chan();
+        let ConstellationChan(ref chan) = *self.window.constellation_chan();
         let event = ConstellationMsg::DOMLoad(pipeline_id);
         chan.send(event).unwrap();
 
     }
 
     pub fn set_current_parser(&self, script: Option<ParserRef>) {
         self.current_parser.set(script);
     }
--- a/servo/components/script/dom/htmlbodyelement.rs
+++ b/servo/components/script/dom/htmlbodyelement.rs
@@ -149,17 +149,17 @@ impl VirtualMethods for HTMLBodyElement 
 
         if !tree_in_doc {
             return
         }
 
         let window = window_from_node(self);
         let document = window.Document();
         document.set_reflow_timeout(time::precise_time_ns() + INITIAL_REFLOW_DELAY);
-        let ConstellationChan(ref chan) = window.constellation_chan();
+        let ConstellationChan(ref chan) = *window.constellation_chan();
         let event = ConstellationMsg::HeadParsed;
         chan.send(event).unwrap();
     }
 
     fn parse_plain_attribute(&self, name: &Atom, value: DOMString) -> AttrValue {
         match *name {
             atom!("bgcolor") |
             atom!("text") => AttrValue::from_legacy_color(value),
--- a/servo/components/script/dom/htmliframeelement.rs
+++ b/servo/components/script/dom/htmliframeelement.rs
@@ -119,17 +119,17 @@ impl HTMLIFrameElement {
         }
 
         let window = window_from_node(self);
         let window = window.r();
         let (new_subpage_id, old_subpage_id) = self.generate_new_subpage_id();
         let new_pipeline_id = self.pipeline_id.get().unwrap();
         let private_iframe = self.privatebrowsing();
 
-        let ConstellationChan(ref chan) = window.constellation_chan();
+        let ConstellationChan(ref chan) = *window.constellation_chan();
         let load_info = IFrameLoadInfo {
             url: url,
             containing_pipeline_id: window.pipeline(),
             new_subpage_id: new_subpage_id,
             old_subpage_id: old_subpage_id,
             new_pipeline_id: new_pipeline_id,
             sandbox: sandboxed,
             is_private: private_iframe,
@@ -139,17 +139,17 @@ impl HTMLIFrameElement {
         if mozbrowser_enabled() {
             // https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserloadstart
             self.dispatch_mozbrowser_event(MozBrowserEvent::LoadStart);
         }
     }
 
     pub fn process_the_iframe_attributes(&self) {
         let url = match self.get_url() {
-            Some(url) => url.clone(),
+            Some(url) => url,
             None => Url::parse("about:blank").unwrap(),
         };
 
         self.navigate_or_reload_child_browsing_context(Some(url));
     }
 
     #[allow(unsafe_code)]
     pub fn dispatch_mozbrowser_event(&self, event: MozBrowserEvent) {
@@ -366,17 +366,17 @@ impl MozBrowserEventDetailBuilder for HT
 pub fn Navigate(iframe: &HTMLIFrameElement, direction: NavigationDirection) -> ErrorResult {
     if iframe.Mozbrowser() {
         if iframe.upcast::<Node>().is_in_doc() {
             let window = window_from_node(iframe);
             let window = window.r();
 
             let pipeline_info = Some((window.pipeline(),
                                       iframe.subpage_id().unwrap()));
-            let ConstellationChan(ref chan) = window.constellation_chan();
+            let ConstellationChan(ref chan) = *window.constellation_chan();
             let msg = ConstellationMsg::Navigate(pipeline_info, direction);
             chan.send(msg).unwrap();
         }
 
         Ok(())
     } else {
         debug!("this frame is not mozbrowser: mozbrowser attribute missing, or not a top
             level window, or mozbrowser preference not set (use --pref dom.mozbrowser.enabled)");
@@ -570,17 +570,17 @@ impl VirtualMethods for HTMLIFrameElemen
             let window = window.r();
 
             // The only reason we're waiting for the iframe to be totally
             // removed is to ensure the script thread can't add iframes faster
             // than the compositor can remove them.
             //
             // Since most of this cleanup doesn't happen on same-origin
             // iframes, and since that would cause a deadlock, don't do it.
-            let ConstellationChan(ref chan) = window.constellation_chan();
+            let ConstellationChan(ref chan) = *window.constellation_chan();
             let same_origin = if let Some(self_url) = self.get_url() {
                 let win_url = window_from_node(self).get_url();
                 UrlHelper::SameOrigin(&self_url, &win_url)
             } else {
                 false
             };
             let (sender, receiver) = if same_origin {
                 (None, None)
--- a/servo/components/script/dom/htmlinputelement.rs
+++ b/servo/components/script/dom/htmlinputelement.rs
@@ -117,17 +117,17 @@ impl InputActivationState {
     }
 }
 
 static DEFAULT_INPUT_SIZE: u32 = 20;
 static DEFAULT_MAX_LENGTH: i32 = -1;
 
 impl HTMLInputElement {
     fn new_inherited(localName: Atom, prefix: Option<DOMString>, document: &Document) -> HTMLInputElement {
-        let chan = document.window().constellation_chan();
+        let chan = document.window().constellation_chan().clone();
         HTMLInputElement {
             htmlelement:
                 HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
                                                       localName, prefix, document),
             input_type: Cell::new(InputType::InputText),
             placeholder: DOMRefCell::new(DOMString::new()),
             checked_changed: Cell::new(false),
             value_changed: Cell::new(false),
--- a/servo/components/script/dom/htmllinkelement.rs
+++ b/servo/components/script/dom/htmllinkelement.rs
@@ -237,17 +237,17 @@ impl HTMLLinkElement {
             Err(e) => debug!("Parsing url {} failed: {}", href, e)
         }
     }
 
     fn handle_favicon_url(&self, rel: &str, href: &str, sizes: &Option<String>) {
         let document = document_from_node(self);
         match document.base_url().join(href) {
             Ok(url) => {
-                let ConstellationChan(ref chan) = document.window().constellation_chan();
+                let ConstellationChan(ref chan) = *document.window().constellation_chan();
                 let event = ConstellationMsg::NewFavicon(url.clone());
                 chan.send(event).unwrap();
 
                 let mozbrowser_event = match *sizes {
                     Some(ref sizes) => MozBrowserEvent::IconChange(rel.to_owned(), url.to_string(), sizes.to_owned()),
                     None => MozBrowserEvent::IconChange(rel.to_owned(), url.to_string(), "".to_owned())
                 };
                 document.trigger_mozbrowser_event(mozbrowser_event);
@@ -313,17 +313,17 @@ impl AsyncResponseListener for Styleshee
         sheet.set_media(Some(media));
         let sheet = Arc::new(sheet);
 
         let elem = elem.r();
         let document = document_from_node(elem);
         let document = document.r();
 
         let win = window_from_node(elem);
-        let LayoutChan(ref layout_chan) = win.r().layout_chan();
+        let LayoutChan(ref layout_chan) = *win.layout_chan();
         layout_chan.send(Msg::AddStylesheet(sheet.clone())).unwrap();
 
         *elem.stylesheet.borrow_mut() = Some(sheet);
         document.invalidate_stylesheets();
         if elem.parser_inserted.get() {
             document.decrement_script_blocking_stylesheet_count();
         }
         document.finish_load(LoadType::Stylesheet(self.url.clone()));
--- a/servo/components/script/dom/htmlstyleelement.rs
+++ b/servo/components/script/dom/htmlstyleelement.rs
@@ -61,17 +61,17 @@ impl HTMLStyleElement {
 
         let data = node.GetTextContent().expect("Element.textContent must be a string");
         let mut sheet = Stylesheet::from_str(&data, url, Origin::Author, win.css_error_reporter());
         let mut css_parser = CssParser::new(&mq_str);
         let media = parse_media_query_list(&mut css_parser);
         sheet.set_media(Some(media));
         let sheet = Arc::new(sheet);
 
-        let LayoutChan(ref layout_chan) = win.layout_chan();
+        let LayoutChan(ref layout_chan) = *win.layout_chan();
         layout_chan.send(Msg::AddStylesheet(sheet.clone())).unwrap();
         *self.stylesheet.borrow_mut() = Some(sheet);
         let doc = document_from_node(self);
         doc.r().invalidate_stylesheets();
     }
 
     pub fn get_stylesheet(&self) -> Option<Arc<Stylesheet>> {
         self.stylesheet.borrow().clone()
--- a/servo/components/script/dom/htmltextareaelement.rs
+++ b/servo/components/script/dom/htmltextareaelement.rs
@@ -95,17 +95,17 @@ static DEFAULT_COLS: u32 = 20;
 
 // https://html.spec.whatwg.org/multipage/#attr-textarea-rows-value
 static DEFAULT_ROWS: u32 = 2;
 
 impl HTMLTextAreaElement {
     fn new_inherited(localName: Atom,
                      prefix: Option<DOMString>,
                      document: &Document) -> HTMLTextAreaElement {
-        let chan = document.window().constellation_chan();
+        let chan = document.window().constellation_chan().clone();
         HTMLTextAreaElement {
             htmlelement:
                 HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
                                                       localName, prefix, document),
             textinput: DOMRefCell::new(TextInput::new(
                     Lines::Multiple, DOMString::new(), chan, None, SelectionDirection::None)),
             value_changed: Cell::new(false),
         }
--- a/servo/components/script/dom/node.rs
+++ b/servo/components/script/dom/node.rs
@@ -190,17 +190,17 @@ unsafe impl Send for OpaqueStyleAndLayou
 
 no_jsmanaged_fields!(OpaqueStyleAndLayoutData);
 
 impl OpaqueStyleAndLayoutData {
     /// Sends the style and layout data, if any, back to the layout thread to be destroyed.
     pub fn dispose(self, node: &Node) {
         debug_assert!(thread_state::get().is_script());
         let win = window_from_node(node);
-        let LayoutChan(chan) = win.layout_chan();
+        let LayoutChan(ref chan) = *win.layout_chan();
         node.style_and_layout_data.set(None);
         chan.send(Msg::ReapStyleAndLayoutData(self)).unwrap();
     }
 }
 
 impl Node {
     /// Adds a new child to the end of this node's list of children.
     ///
--- a/servo/components/script/dom/servohtmlparser.rs
+++ b/servo/components/script/dom/servohtmlparser.rs
@@ -88,18 +88,18 @@ impl AsyncResponseListener for ParserCon
                 let mut meta = Metadata::default(url);
                 let mime: Option<Mime> = "text/html".parse().ok();
                 meta.set_content_type(mime.as_ref());
                 Some(meta)
             },
             Err(_) => None,
         };
         let content_type = metadata.clone().and_then(|meta| meta.content_type);
-        let parser = match ScriptThread::page_fetch_complete(self.id.clone(),
-                                                             self.subpage.clone(),
+        let parser = match ScriptThread::page_fetch_complete(&self.id,
+                                                             self.subpage.as_ref(),
                                                              metadata) {
             Some(parser) => parser,
             None => return,
         };
 
         let parser = parser.r();
         self.parser = Some(match parser {
             ParserRef::HTML(parser) => TrustedParser::HTML(
--- a/servo/components/script/dom/window.rs
+++ b/servo/components/script/dom/window.rs
@@ -1229,34 +1229,34 @@ impl Window {
     pub fn get_url(&self) -> Url {
         (*self.Document().url()).clone()
     }
 
     pub fn resource_thread(&self) -> ResourceThread {
         (*self.resource_thread).clone()
     }
 
-    pub fn mem_profiler_chan(&self) -> mem::ProfilerChan {
-        self.mem_profiler_chan.clone()
+    pub fn mem_profiler_chan(&self) -> &mem::ProfilerChan {
+        &self.mem_profiler_chan
     }
 
     pub fn devtools_chan(&self) -> Option<IpcSender<ScriptToDevtoolsControlMsg>> {
         self.devtools_chan.clone()
     }
 
-    pub fn layout_chan(&self) -> LayoutChan {
-        self.layout_chan.clone()
+    pub fn layout_chan(&self) -> &LayoutChan {
+        &self.layout_chan
     }
 
-    pub fn constellation_chan(&self) -> ConstellationChan<ConstellationMsg> {
-        self.constellation_chan.clone()
+    pub fn constellation_chan(&self) -> &ConstellationChan<ConstellationMsg> {
+        &self.constellation_chan
     }
 
-    pub fn scheduler_chan(&self) -> IpcSender<TimerEventRequest> {
-        self.scheduler_chan.clone()
+    pub fn scheduler_chan(&self) -> &IpcSender<TimerEventRequest> {
+        &self.scheduler_chan
     }
 
     pub fn schedule_callback(&self, callback: OneshotTimerCallback, duration: MsDuration) -> OneshotTimerHandle {
         self.timers.schedule_callback(callback,
                                       duration,
                                       TimerSource::FromWindow(self.id.clone()))
     }
 
--- a/servo/components/script/dom/worker.rs
+++ b/servo/components/script/dom/worker.rs
@@ -70,18 +70,18 @@ impl Worker {
     pub fn Constructor(global: GlobalRef, script_url: DOMString) -> Fallible<Root<Worker>> {
         // Step 2-4.
         let worker_url = match global.api_base_url().join(&script_url) {
             Ok(url) => url,
             Err(_) => return Err(Error::Syntax),
         };
 
         let resource_thread = global.resource_thread();
-        let constellation_chan = global.constellation_chan();
-        let scheduler_chan = global.scheduler_chan();
+        let constellation_chan = global.constellation_chan().clone();
+        let scheduler_chan = global.scheduler_chan().clone();
 
         let (sender, receiver) = channel();
         let closing = Arc::new(AtomicBool::new(false));
         let worker = Worker::new(global, sender.clone(), closing.clone());
         let worker_ref = Trusted::new(worker.r());
         let worker_id = global.get_next_worker_id();
 
         let (devtools_sender, devtools_receiver) = ipc::channel().unwrap();
@@ -98,17 +98,17 @@ impl Worker {
                                                                 page_info)).unwrap();
                 Some(devtools_sender)
             },
             None => None,
         };
 
         let init = WorkerGlobalScopeInit {
             resource_thread: resource_thread,
-            mem_profiler_chan: global.mem_profiler_chan(),
+            mem_profiler_chan: global.mem_profiler_chan().clone(),
             to_devtools_sender: global.devtools_chan(),
             from_devtools_sender: optional_sender,
             constellation_chan: constellation_chan,
             scheduler_chan: scheduler_chan,
             worker_id: worker_id,
             closing: closing,
         };
 
--- a/servo/components/script/dom/workerglobalscope.rs
+++ b/servo/components/script/dom/workerglobalscope.rs
@@ -121,38 +121,38 @@ impl WorkerGlobalScope {
             from_devtools_sender: init.from_devtools_sender,
             from_devtools_receiver: from_devtools_receiver,
             devtools_wants_updates: Cell::new(false),
             constellation_chan: init.constellation_chan,
             scheduler_chan: init.scheduler_chan,
         }
     }
 
-    pub fn mem_profiler_chan(&self) -> mem::ProfilerChan {
-        self.mem_profiler_chan.clone()
+    pub fn mem_profiler_chan(&self) -> &mem::ProfilerChan {
+        &self.mem_profiler_chan
     }
 
     pub fn devtools_chan(&self) -> Option<IpcSender<ScriptToDevtoolsControlMsg>> {
         self.to_devtools_sender.clone()
     }
 
     pub fn from_devtools_sender(&self) -> Option<IpcSender<DevtoolScriptControlMsg>> {
         self.from_devtools_sender.clone()
     }
 
     pub fn from_devtools_receiver(&self) -> &Receiver<DevtoolScriptControlMsg> {
         &self.from_devtools_receiver
     }
 
-    pub fn constellation_chan(&self) -> ConstellationChan<ConstellationMsg> {
-        self.constellation_chan.clone()
+    pub fn constellation_chan(&self) -> &ConstellationChan<ConstellationMsg> {
+        &self.constellation_chan
     }
 
-    pub fn scheduler_chan(&self) -> IpcSender<TimerEventRequest> {
-        self.scheduler_chan.clone()
+    pub fn scheduler_chan(&self) -> &IpcSender<TimerEventRequest> {
+        &self.scheduler_chan
     }
 
     pub fn schedule_callback(&self, callback: OneshotTimerCallback, duration: MsDuration) -> OneshotTimerHandle {
         self.timers.schedule_callback(callback,
                                       duration,
                                       TimerSource::FromWorker)
     }
 
--- a/servo/components/script/script_thread.rs
+++ b/servo/components/script/script_thread.rs
@@ -270,43 +270,33 @@ impl ScriptChan for SendableMainThreadSc
         self.0.send(msg).map_err(|_| ())
     }
 
     fn clone(&self) -> Box<ScriptChan + Send> {
         box SendableMainThreadScriptChan((&self.0).clone())
     }
 }
 
-impl SendableMainThreadScriptChan {
-    /// Creates a new script chan.
-    pub fn new() -> (Receiver<CommonScriptMsg>, Box<SendableMainThreadScriptChan>) {
-        let (chan, port) = channel();
-        (port, box SendableMainThreadScriptChan(chan))
-    }
-}
-
 /// Encapsulates internal communication of main thread messages within the script thread.
 #[derive(JSTraceable)]
 pub struct MainThreadScriptChan(pub Sender<MainThreadScriptMsg>);
 
 impl ScriptChan for MainThreadScriptChan {
     fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> {
         self.0.send(MainThreadScriptMsg::Common(msg)).map_err(|_| ())
     }
 
     fn clone(&self) -> Box<ScriptChan + Send> {
         box MainThreadScriptChan((&self.0).clone())
     }
 }
 
-impl MainThreadScriptChan {
-    /// Creates a new script chan.
-    pub fn new() -> (Receiver<MainThreadScriptMsg>, Box<MainThreadScriptChan>) {
-        let (chan, port) = channel();
-        (port, box MainThreadScriptChan(chan))
+impl OpaqueSender<CommonScriptMsg> for Sender<MainThreadScriptMsg> {
+    fn send(&self, msg: CommonScriptMsg) {
+        self.send(MainThreadScriptMsg::Common(msg)).unwrap()
     }
 }
 
 /// Information for an entire page. Pages are top-level browsing contexts and can contain multiple
 /// frames.
 #[derive(JSTraceable)]
 // ScriptThread instances are rooted on creation, so this is okay
 #[allow(unrooted_must_root)]
@@ -448,57 +438,55 @@ impl ScriptThreadFactory for ScriptThrea
         let layout_chan = LayoutChan(layout_chan.sender());
         let pipeline_id = state.id;
         thread::spawn_named_with_send_on_panic(format!("ScriptThread {:?}", state.id),
                                                thread_state::SCRIPT,
                                                move || {
             PipelineNamespace::install(state.pipeline_namespace_id);
             let roots = RootCollection::new();
             let _stack_roots_tls = StackRootTLS::new(&roots);
-            let chan = MainThreadScriptChan(script_chan.clone());
-            let channel_for_reporter = chan.clone();
             let id = state.id;
             let parent_info = state.parent_info;
             let mem_profiler_chan = state.mem_profiler_chan.clone();
             let window_size = state.window_size;
             let script_thread = ScriptThread::new(state,
                                               script_port,
-                                              script_chan);
+                                              script_chan.clone());
 
             SCRIPT_THREAD_ROOT.with(|root| {
                 *root.borrow_mut() = Some(&script_thread as *const _);
             });
 
             let mut failsafe = ScriptMemoryFailsafe::new(&script_thread);
 
             let new_load = InProgressLoad::new(id, parent_info, layout_chan, window_size,
                                                load_data.url.clone());
             script_thread.start_page_load(new_load, load_data);
 
             let reporter_name = format!("script-reporter-{}", id);
             mem_profiler_chan.run_with_memory_reporting(|| {
                 script_thread.start();
                 let _ = script_thread.compositor.borrow_mut().send(ScriptToCompositorMsg::Exited);
                 let _ = script_thread.content_process_shutdown_chan.send(());
-            }, reporter_name, channel_for_reporter, CommonScriptMsg::CollectReports);
+            }, reporter_name, script_chan, CommonScriptMsg::CollectReports);
 
             // This must always be the very last operation performed before the thread completes
             failsafe.neuter();
         }, Some(pipeline_id), panic_chan);
     }
 }
 
 pub unsafe extern "C" fn shadow_check_callback(_cx: *mut JSContext,
     _object: HandleObject, _id: HandleId) -> DOMProxyShadowsResult {
     // XXX implement me
     DOMProxyShadowsResult::ShadowCheckFailed
 }
 
 impl ScriptThread {
-    pub fn page_fetch_complete(id: PipelineId, subpage: Option<SubpageId>, metadata: Option<Metadata>)
+    pub fn page_fetch_complete(id: &PipelineId, subpage: Option<&SubpageId>, metadata: Option<Metadata>)
                                -> Option<ParserRoot> {
         SCRIPT_THREAD_ROOT.with(|root| {
             let script_thread = unsafe { &*root.borrow().unwrap() };
             script_thread.handle_page_fetch_complete(id, subpage, metadata)
         })
     }
 
     pub fn parsing_complete(id: PipelineId) {
@@ -1117,18 +1105,17 @@ impl ScriptThread {
         let doc = doc.r();
         if doc.loader().is_blocked() {
             return;
         }
 
         doc.mut_loader().inhibit_events();
 
         // https://html.spec.whatwg.org/multipage/#the-end step 7
-        let addr: Trusted<Document> = Trusted::new(doc);
-        let handler = box DocumentProgressHandler::new(addr.clone());
+        let handler = box DocumentProgressHandler::new(Trusted::new(doc));
         self.dom_manipulation_task_source.queue(DOMManipulationTask::DocumentProgress(handler)).unwrap();
 
         let ConstellationChan(ref chan) = self.constellation_chan;
         chan.send(ConstellationMsg::LoadComplete(pipeline)).unwrap();
     }
 
     fn collect_reports(&self, reports_chan: ReportsChan) {
         let mut urls = vec![];
@@ -1280,30 +1267,30 @@ impl ScriptThread {
         // TODO(tkuehn): currently there is only one window,
         // so this can afford to be naive and just shut down the
         // compositor. In the future it'll need to be smarter.
         self.compositor.borrow_mut().send(ScriptToCompositorMsg::Exit).unwrap();
     }
 
     /// We have received notification that the response associated with a load has completed.
     /// Kick off the document and frame tree creation process using the result.
-    fn handle_page_fetch_complete(&self, id: PipelineId, subpage: Option<SubpageId>,
+    fn handle_page_fetch_complete(&self, id: &PipelineId, subpage: Option<&SubpageId>,
                                   metadata: Option<Metadata>) -> Option<ParserRoot> {
         let idx = self.incomplete_loads.borrow().iter().position(|load| {
-            load.pipeline_id == id && load.parent_info.map(|info| info.1) == subpage
+            load.pipeline_id == *id && load.parent_info.as_ref().map(|info| &info.1) == subpage
         });
         // The matching in progress load structure may not exist if
         // the pipeline exited before the page load completed.
         match idx {
             Some(idx) => {
                 let load = self.incomplete_loads.borrow_mut().remove(idx);
                 metadata.map(|meta| self.load(meta, load))
             }
             None => {
-                assert!(self.closed_pipelines.borrow().contains(&id));
+                assert!(self.closed_pipelines.borrow().contains(id));
                 None
             }
         }
     }
 
     /// Handles a request for the window title.
     fn handle_get_title_msg(&self, pipeline_id: PipelineId) {
         let page = get_page(&self.root_page(), pipeline_id);
@@ -1863,37 +1850,34 @@ impl ScriptThread {
     }
 
     /// Initiate a non-blocking fetch for a specified resource. Stores the InProgressLoad
     /// argument until a notification is received that the fetch is complete.
     fn start_page_load(&self, incomplete: InProgressLoad, mut load_data: LoadData) {
         let id = incomplete.pipeline_id.clone();
         let subpage = incomplete.parent_info.clone().map(|p| p.1);
 
-        let script_chan = self.chan.clone();
-        let resource_thread = self.resource_thread.clone();
-
         let context = Arc::new(Mutex::new(ParserContext::new(id, subpage, load_data.url.clone())));
         let (action_sender, action_receiver) = ipc::channel().unwrap();
         let listener = NetworkListener {
             context: context,
-            script_chan: script_chan.clone(),
+            script_chan: self.chan.clone(),
         };
         ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
             listener.notify(message.to().unwrap());
         });
         let response_target = AsyncResponseTarget {
             sender: action_sender,
         };
 
         if load_data.url.scheme() == "javascript" {
             load_data.url = Url::parse("about:blank").unwrap();
         }
 
-        resource_thread.send(ControlMsg::Load(NetLoadData {
+        self.resource_thread.send(ControlMsg::Load(NetLoadData {
             context: LoadContext::Browsing,
             url: load_data.url,
             method: load_data.method,
             headers: Headers::new(),
             preserved_headers: load_data.headers,
             data: load_data.data,
             cors: None,
             pipeline_id: Some(id),
@@ -1977,17 +1961,17 @@ impl Drop for ScriptThread {
 fn shut_down_layout(page_tree: &Rc<Page>) {
     let mut channels = vec!();
 
     for page in page_tree.iter() {
         // Tell the layout thread to begin shutting down, and wait until it
         // processed this message.
         let (response_chan, response_port) = channel();
         let window = page.window();
-        let LayoutChan(chan) = window.layout_chan();
+        let LayoutChan(chan) = window.layout_chan().clone();
         if chan.send(layout_interface::Msg::PrepareToExit(response_chan)).is_ok() {
             channels.push(chan);
             response_port.recv().unwrap();
         }
     }
 
     // Drop our references to the JSContext and DOM objects.
     for page in page_tree.iter() {