servo: Merge #13029 - Use &mut Flow more (from servo:flowref); r=nox
authorMs2ger <Ms2ger@gmail.com>
Thu, 25 Aug 2016 04:52:24 -0500
changeset 339567 61d177a688e8807e10eeb5e7bc6414755942f786
parent 339566 3fd4373a34f0a74573f15bc0b97d8b89ad9140e8
child 339568 a9296140e6a1de9fbeadffb8a83ad40d789318b0
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)
reviewersnox
servo: Merge #13029 - Use &mut Flow more (from servo:flowref); r=nox The double indirection in `&mut FlowRef` is not useful. Source-Repo: https://github.com/servo/servo Source-Revision: d29f61af317d3ab9e8233f0327c25b4925b4f053
servo/components/layout/parallel.rs
servo/components/layout/query.rs
servo/components/layout/sequential.rs
servo/components/layout_thread/lib.rs
--- a/servo/components/layout/parallel.rs
+++ b/servo/components/layout/parallel.rs
@@ -5,17 +5,17 @@
 //! Implements parallel traversals over the DOM and flow trees.
 //!
 //! This code is highly unsafe. Keep this file small and easy to audit.
 
 #![allow(unsafe_code)]
 
 use context::{LayoutContext, SharedLayoutContext};
 use flow::{self, Flow, MutableFlowUtils, PostorderFlowTraversal, PreorderFlowTraversal};
-use flow_ref::{self, FlowRef};
+use flow_ref::FlowRef;
 use profile_traits::time::{self, TimerMetadata, profile};
 use std::mem;
 use std::sync::atomic::{AtomicIsize, Ordering};
 use style::dom::UnsafeNode;
 use style::parallel::run_queue_with_custom_work_data_type;
 use style::parallel::{CHUNK_SIZE, WorkQueueData};
 use style::workqueue::{WorkQueue, WorkUnit, WorkerProxy};
 use traversal::AssignBSizes;
@@ -215,29 +215,29 @@ fn assign_block_sizes_and_store_overflow
     let layout_context = LayoutContext::new(shared_layout_context);
     let assign_block_sizes_traversal = AssignBSizes {
         layout_context: &layout_context,
     };
     assign_block_sizes_traversal.run_parallel(unsafe_flow)
 }
 
 pub fn traverse_flow_tree_preorder(
-        root: &mut FlowRef,
+        root: &mut Flow,
         profiler_metadata: Option<TimerMetadata>,
         time_profiler_chan: time::ProfilerChan,
         shared_layout_context: &SharedLayoutContext,
         queue: &mut WorkQueue<SharedLayoutContext, WorkQueueData>) {
     if opts::get().bubble_inline_sizes_separately {
         let layout_context = LayoutContext::new(shared_layout_context);
         let bubble_inline_sizes = BubbleISizes { layout_context: &layout_context };
-        flow_ref::deref_mut(root).traverse_postorder(&bubble_inline_sizes);
+        root.traverse_postorder(&bubble_inline_sizes);
     }
 
     run_queue_with_custom_work_data_type(queue, |queue| {
         profile(time::ProfilerCategory::LayoutParallelWarmup, profiler_metadata,
                 time_profiler_chan, || {
             queue.push(WorkUnit {
                 fun: assign_inline_sizes,
-                data: (box vec![mut_owned_flow_to_unsafe_flow(root)], 0),
+                data: (box vec![borrowed_flow_to_unsafe_flow(root)], 0),
             })
         });
     }, shared_layout_context);
 }
--- a/servo/components/layout/query.rs
+++ b/servo/components/layout/query.rs
@@ -4,18 +4,17 @@
 
 //! Utilities for querying the layout, as needed by the layout thread.
 
 use app_units::Au;
 use construct::ConstructionResult;
 use euclid::point::Point2D;
 use euclid::rect::Rect;
 use euclid::size::Size2D;
-use flow;
-use flow_ref::FlowRef;
+use flow::{self, Flow};
 use fragment::{Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo};
 use gfx::display_list::{DisplayItemMetadata, DisplayList, OpaqueNode, ScrollOffsetMap};
 use gfx_traits::LayerId;
 use ipc_channel::ipc::IpcSender;
 use opaque_node::OpaqueNodeMethods;
 use script_layout_interface::rpc::{ContentBoxResponse, ContentBoxesResponse};
 use script_layout_interface::rpc::{HitTestResponse, LayoutRPC};
 use script_layout_interface::rpc::{MarginStyleResponse, NodeGeometryResponse};
@@ -370,28 +369,28 @@ impl FragmentBorderBoxIterator for Margi
     }
 
     fn should_process(&mut self, fragment: &Fragment) -> bool {
         fragment.contains_node(self.node_address)
     }
 }
 
 pub fn process_content_box_request<N: LayoutNode>(
-        requested_node: N, layout_root: &mut FlowRef) -> Rect<Au> {
+        requested_node: N, layout_root: &mut Flow) -> Rect<Au> {
     // FIXME(pcwalton): This has not been updated to handle the stacking context relative
     // stuff. So the position is wrong in most cases.
     let mut iterator = UnioningFragmentBorderBoxIterator::new(requested_node.opaque());
     sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator);
     match iterator.rect {
         Some(rect) => rect,
         None       => Rect::zero()
     }
 }
 
-pub fn process_content_boxes_request<N: LayoutNode>(requested_node: N, layout_root: &mut FlowRef)
+pub fn process_content_boxes_request<N: LayoutNode>(requested_node: N, layout_root: &mut Flow)
         -> Vec<Rect<Au>> {
     // FIXME(pcwalton): This has not been updated to handle the stacking context relative
     // stuff. So the position is wrong in most cases.
     let mut iterator = CollectingFragmentBorderBoxIterator::new(requested_node.opaque());
     sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator);
     iterator.rects
 }
 
@@ -576,29 +575,29 @@ impl FragmentBorderBoxIterator for Paren
         }
     }
 
     fn should_process(&mut self, _: &Fragment) -> bool {
         !self.has_found_node
     }
 }
 
-pub fn process_node_geometry_request<N: LayoutNode>(requested_node: N, layout_root: &mut FlowRef)
+pub fn process_node_geometry_request<N: LayoutNode>(requested_node: N, layout_root: &mut Flow)
         -> Rect<i32> {
     let mut iterator = FragmentLocatingFragmentIterator::new(requested_node.opaque());
     sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator);
     iterator.client_rect
 }
 
 pub fn process_node_layer_id_request<N: LayoutNode>(requested_node: N) -> LayerId {
     let layout_node = requested_node.to_threadsafe();
     layout_node.layer_id()
 }
 
-pub fn process_node_scroll_area_request< N: LayoutNode>(requested_node: N, layout_root: &mut FlowRef)
+pub fn process_node_scroll_area_request< N: LayoutNode>(requested_node: N, layout_root: &mut Flow)
         -> Rect<i32> {
     let mut iterator = UnioningFragmentScrollAreaIterator::new(requested_node.opaque());
     sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator);
     match iterator.overflow_direction {
         OverflowDirection::RightAndDown => {
             let right = max(iterator.union_rect.size.width, iterator.origin_rect.size.width);
             let bottom = max(iterator.union_rect.size.height, iterator.origin_rect.size.height);
             Rect::new(iterator.origin_rect.origin, Size2D::new(right, bottom))
@@ -638,17 +637,17 @@ fn ensure_node_data_initialized<N: Layou
 }
 
 /// Return the resolved value of property for a given (pseudo)element.
 /// https://drafts.csswg.org/cssom/#resolved-value
 pub fn process_resolved_style_request<'a, N, C>(requested_node: N,
                                                 style_context: &'a C,
                                                 pseudo: &Option<PseudoElement>,
                                                 property: &Atom,
-                                                layout_root: &mut FlowRef) -> Option<String>
+                                                layout_root: &mut Flow) -> Option<String>
     where N: LayoutNode,
           C: StyleContext<'a>
 {
     use style::traversal::ensure_node_styled;
 
     // This node might have display: none, or it's style might be not up to
     // date, so we might need to do style recalc.
     //
@@ -690,17 +689,17 @@ pub fn process_resolved_style_request<'a
     //      eg. width does not apply to non-replaced inline elements.
     // Existing browsers disagree about when left/top/right/bottom apply
     // (Chrome seems to think they never apply and always returns resolved values).
     // There are probably other quirks.
     let applies = true;
 
     fn used_value_for_position_property<N: LayoutNode>(
             layout_node: N::ConcreteThreadSafeLayoutNode,
-            layout_root: &mut FlowRef,
+            layout_root: &mut Flow,
             requested_node: N,
             property: &Atom) -> Option<String> {
         let maybe_data = layout_node.borrow_layout_data();
         let position = maybe_data.map_or(Point2D::zero(), |data| {
             match (*data).flow_construction_result {
                 ConstructionResult::Flow(ref flow_ref, _) =>
                     flow::base(flow_ref.deref()).stacking_relative_position,
                 // TODO(dzbarsky) search parents until we find node with a flow ref.
@@ -769,17 +768,17 @@ pub fn process_resolved_style_request<'a
         }
         // FIXME: implement used value computation for line-height
         ref property => {
             style.computed_value_to_string(&*property).ok()
         }
     }
 }
 
-pub fn process_offset_parent_query<N: LayoutNode>(requested_node: N, layout_root: &mut FlowRef)
+pub fn process_offset_parent_query<N: LayoutNode>(requested_node: N, layout_root: &mut Flow)
         -> OffsetParentResponse {
     let mut iterator = ParentOffsetBorderBoxIterator::new(requested_node.opaque());
     sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator);
     let parent_info_index = iterator.parent_nodes.iter().rposition(|info| info.is_some());
     match parent_info_index {
         Some(parent_info_index) => {
             let parent = iterator.parent_nodes[parent_info_index].as_ref().unwrap();
             let origin = iterator.node_border_box.origin - parent.border_box.origin;
--- a/servo/components/layout/sequential.rs
+++ b/servo/components/layout/sequential.rs
@@ -7,46 +7,45 @@
 use app_units::Au;
 use context::{LayoutContext, SharedLayoutContext};
 use display_list_builder::DisplayListBuildState;
 use euclid::point::Point2D;
 use floats::SpeculatedFloatPlacement;
 use flow::IS_ABSOLUTELY_POSITIONED;
 use flow::{PostorderFlowTraversal, PreorderFlowTraversal};
 use flow::{self, Flow, ImmutableFlowUtils, InorderFlowTraversal, MutableFlowUtils};
-use flow_ref::{self, FlowRef};
 use fragment::FragmentBorderBoxIterator;
 use generated_content::ResolveGeneratedContent;
 use gfx::display_list::{DisplayItem, StackingContext};
 use script_layout_interface::restyle_damage::{REFLOW, STORE_OVERFLOW};
 use style::context::StyleContext;
 use traversal::{AssignBSizes, AssignISizes, BubbleISizes, BuildDisplayList, ComputeAbsolutePositions};
 use util::opts;
 
 pub use style::sequential::traverse_dom;
 
-pub fn resolve_generated_content(root: &mut FlowRef, shared_layout_context: &SharedLayoutContext) {
+pub fn resolve_generated_content(root: &mut Flow, shared_layout_context: &SharedLayoutContext) {
     fn doit(flow: &mut Flow, level: u32, traversal: &mut ResolveGeneratedContent) {
         if !traversal.should_process(flow) {
             return
         }
 
         traversal.process(flow, level);
 
         for kid in flow::mut_base(flow).children.iter_mut() {
             doit(kid, level + 1, traversal)
         }
     }
 
     let layout_context = LayoutContext::new(shared_layout_context);
     let mut traversal = ResolveGeneratedContent::new(&layout_context);
-    doit(flow_ref::deref_mut(root), 0, &mut traversal)
+    doit(root, 0, &mut traversal)
 }
 
-pub fn traverse_flow_tree_preorder(root: &mut FlowRef,
+pub fn traverse_flow_tree_preorder(root: &mut Flow,
                                    shared_layout_context: &SharedLayoutContext) {
     fn doit(flow: &mut Flow,
             assign_inline_sizes: AssignISizes,
             assign_block_sizes: AssignBSizes) {
         if assign_inline_sizes.should_process(flow) {
             assign_inline_sizes.process(flow);
         }
 
@@ -56,51 +55,48 @@ pub fn traverse_flow_tree_preorder(root:
 
         if assign_block_sizes.should_process(flow) {
             assign_block_sizes.process(flow);
         }
     }
 
     let layout_context = LayoutContext::new(shared_layout_context);
 
-    let root = flow_ref::deref_mut(root);
-
     if opts::get().bubble_inline_sizes_separately {
         let bubble_inline_sizes = BubbleISizes { layout_context: &layout_context };
         {
             let root: &mut Flow = root;
             root.traverse_postorder(&bubble_inline_sizes);
         }
     }
 
     let assign_inline_sizes = AssignISizes { shared_context: layout_context.shared_context() };
     let assign_block_sizes  = AssignBSizes { layout_context: &layout_context };
 
     doit(root, assign_inline_sizes, assign_block_sizes);
 }
 
-pub fn build_display_list_for_subtree(root: &mut FlowRef,
+pub fn build_display_list_for_subtree(flow_root: &mut Flow,
                                       root_stacking_context: &mut StackingContext,
                                       shared_layout_context: &SharedLayoutContext)
                                       -> Vec<DisplayItem> {
-    let flow_root = flow_ref::deref_mut(root);
     flow_root.traverse_preorder(&ComputeAbsolutePositions { layout_context: shared_layout_context });
     let mut children = vec![];
     flow_root.collect_stacking_contexts(root_stacking_context.id,
                                         &mut children);
     root_stacking_context.add_children(children);
     let mut build_display_list = BuildDisplayList {
         state: DisplayListBuildState::new(shared_layout_context,
-                                          flow::base(&*flow_root).stacking_context_id),
+                                          flow::base(flow_root).stacking_context_id),
     };
-    build_display_list.traverse(&mut *flow_root);
+    build_display_list.traverse(flow_root);
     build_display_list.state.items
 }
 
-pub fn iterate_through_flow_tree_fragment_border_boxes(root: &mut FlowRef,
+pub fn iterate_through_flow_tree_fragment_border_boxes(root: &mut Flow,
                                                        iterator: &mut FragmentBorderBoxIterator) {
     fn doit(flow: &mut Flow,
             level: i32,
             iterator: &mut FragmentBorderBoxIterator,
             stacking_context_position: &Point2D<Au>) {
         flow.iterate_through_fragment_border_boxes(iterator, level, stacking_context_position);
 
         for kid in flow::mut_base(flow).child_iter_mut() {
@@ -112,17 +108,17 @@ pub fn iterate_through_flow_tree_fragmen
                     *stacking_context_position
                 };
 
             // FIXME(#2795): Get the real container size.
             doit(kid, level + 1, iterator, &stacking_context_position);
         }
     }
 
-    doit(flow_ref::deref_mut(root), 0, iterator, &Point2D::zero());
+    doit(root, 0, iterator, &Point2D::zero());
 }
 
 pub fn store_overflow(layout_context: &LayoutContext, flow: &mut Flow) {
     if !flow::base(flow).restyle_damage.contains(STORE_OVERFLOW) {
         return
     }
 
     for mut kid in flow::mut_base(flow).child_iter_mut() {
--- a/servo/components/layout_thread/lib.rs
+++ b/servo/components/layout_thread/lib.rs
@@ -867,62 +867,62 @@ impl LayoutThread {
         Some(flow)
     }
 
     /// Performs layout constraint solving.
     ///
     /// This corresponds to `Reflow()` in Gecko and `layout()` in WebKit/Blink and should be
     /// benchmarked against those two. It is marked `#[inline(never)]` to aid profiling.
     #[inline(never)]
-    fn solve_constraints(layout_root: &mut FlowRef,
+    fn solve_constraints(layout_root: &mut Flow,
                          shared_layout_context: &SharedLayoutContext) {
         let _scope = layout_debug_scope!("solve_constraints");
         sequential::traverse_flow_tree_preorder(layout_root, shared_layout_context);
     }
 
     /// Performs layout constraint solving in parallel.
     ///
     /// This corresponds to `Reflow()` in Gecko and `layout()` in WebKit/Blink and should be
     /// benchmarked against those two. It is marked `#[inline(never)]` to aid profiling.
     #[inline(never)]
     fn solve_constraints_parallel(traversal: &mut WorkQueue<SharedLayoutContext, WorkQueueData>,
-                                  layout_root: &mut FlowRef,
+                                  layout_root: &mut Flow,
                                   profiler_metadata: Option<TimerMetadata>,
                                   time_profiler_chan: time::ProfilerChan,
                                   shared_layout_context: &SharedLayoutContext) {
         let _scope = layout_debug_scope!("solve_constraints_parallel");
 
         // NOTE: this currently computes borders, so any pruning should separate that
         // operation out.
         parallel::traverse_flow_tree_preorder(layout_root,
                                               profiler_metadata,
                                               time_profiler_chan,
                                               shared_layout_context,
                                               traversal);
     }
 
     fn compute_abs_pos_and_build_display_list(&mut self,
                                               data: &Reflow,
-                                              layout_root: &mut FlowRef,
+                                              layout_root: &mut Flow,
                                               shared_layout_context: &mut SharedLayoutContext,
                                               rw_data: &mut LayoutThreadData) {
-        let writing_mode = flow::base(&**layout_root).writing_mode;
+        let writing_mode = flow::base(layout_root).writing_mode;
         let (metadata, sender) = (self.profiler_metadata(), self.time_profiler_chan.clone());
         profile(time::ProfilerCategory::LayoutDispListBuild,
                 metadata.clone(),
                 sender.clone(),
                 || {
-            flow::mut_base(flow_ref::deref_mut(layout_root)).stacking_relative_position =
+            flow::mut_base(layout_root).stacking_relative_position =
                 LogicalPoint::zero(writing_mode).to_physical(writing_mode,
                                                              self.viewport_size);
 
-            flow::mut_base(flow_ref::deref_mut(layout_root)).clip =
+            flow::mut_base(layout_root).clip =
                 ClippingRegion::from_rect(&data.page_clip_rect);
 
-            if flow::base(&**layout_root).restyle_damage.contains(REPAINT) ||
+            if flow::base(layout_root).restyle_damage.contains(REPAINT) ||
                     rw_data.display_list.is_none() {
                 let mut root_stacking_context = StackingContext::new(StackingContextId::new(0),
                                                                      StackingContextType::Real,
                                                                      &Rect::zero(),
                                                                      &Rect::zero(),
                                                                      0,
                                                                      filter::T::new(Vec::new()),
                                                                      mix_blend_mode::T::normal,
@@ -934,20 +934,19 @@ impl LayoutThread {
 
                 let display_list_entries =
                     sequential::build_display_list_for_subtree(layout_root,
                                                                &mut root_stacking_context,
                                                                shared_layout_context);
 
                 debug!("Done building display list.");
 
-                let root_background_color = get_root_flow_background_color(
-                    flow_ref::deref_mut(layout_root));
+                let root_background_color = get_root_flow_background_color(layout_root);
                 let root_size = {
-                    let root_flow = flow::base(&**layout_root);
+                    let root_flow = flow::base(layout_root);
                     if rw_data.stylist.viewport_constraints().is_some() {
                         root_flow.position.size.to_physical(root_flow.writing_mode)
                     } else {
                         root_flow.overflow.scroll.size
                     }
                 };
 
                 let origin = Rect::new(Point2D::new(Au(0), Au(0)), root_size);
@@ -987,18 +986,17 @@ impl LayoutThread {
                     let mut frame_builder = WebRenderFrameBuilder::new(pipeline_id);
                     let root_scroll_layer_id = frame_builder.next_scroll_layer_id();
                     let sc_id = rw_data.display_list.as_ref().unwrap().convert_to_webrender(
                         webrender_api,
                         pipeline_id,
                         epoch,
                         Some(root_scroll_layer_id),
                         &mut frame_builder);
-                    let root_background_color = get_root_flow_background_color(
-                        flow_ref::deref_mut(layout_root));
+                    let root_background_color = get_root_flow_background_color(layout_root);
                     let root_background_color =
                         webrender_traits::ColorF::new(root_background_color.r,
                                                       root_background_color.g,
                                                       root_background_color.b,
                                                       root_background_color.a);
 
                     let viewport_size = Size2D::new(self.viewport_size.width.to_f32_px(),
                                                     self.viewport_size.height.to_f32_px());
@@ -1206,24 +1204,25 @@ impl LayoutThread {
         }
 
         // Perform post-style recalculation layout passes.
         self.perform_post_style_recalc_layout_passes(&data.reflow_info,
                                                      &mut rw_data,
                                                      &mut shared_layout_context);
 
         if let Some(mut root_flow) = self.root_flow.clone() {
+            let root_flow = flow_ref::deref_mut(&mut root_flow);
             match data.query_type {
                 ReflowQueryType::ContentBoxQuery(node) => {
                     let node = unsafe { ServoLayoutNode::new(&node) };
-                    rw_data.content_box_response = process_content_box_request(node, &mut root_flow);
+                    rw_data.content_box_response = process_content_box_request(node, root_flow);
                 },
                 ReflowQueryType::ContentBoxesQuery(node) => {
                     let node = unsafe { ServoLayoutNode::new(&node) };
-                    rw_data.content_boxes_response = process_content_boxes_request(node, &mut root_flow);
+                    rw_data.content_boxes_response = process_content_boxes_request(node, root_flow);
                 },
                 ReflowQueryType::HitTestQuery(translated_point, client_point, update_cursor) => {
                     let translated_point =
                         Point2D::new(Au::from_f32_px(translated_point.x),
                                      Au::from_f32_px(translated_point.y));
 
                     let client_point =
                         Point2D::new(Au::from_f32_px(client_point.x),
@@ -1234,21 +1233,21 @@ impl LayoutThread {
                                         .expect("Tried to hit test with no display list")
                                         .hit_test(&translated_point,
                                                   &client_point,
                                                   &rw_data.stacking_context_scroll_offsets);
                     rw_data.hit_test_response = (result.last().cloned(), update_cursor);
                 },
                 ReflowQueryType::NodeGeometryQuery(node) => {
                     let node = unsafe { ServoLayoutNode::new(&node) };
-                    rw_data.client_rect_response = process_node_geometry_request(node, &mut root_flow);
+                    rw_data.client_rect_response = process_node_geometry_request(node, root_flow);
                 },
                 ReflowQueryType::NodeScrollGeometryQuery(node) => {
                     let node = unsafe { ServoLayoutNode::new(&node) };
-                    rw_data.scroll_area_response = process_node_scroll_area_request(node, &mut root_flow);
+                    rw_data.scroll_area_response = process_node_scroll_area_request(node, root_flow);
                 },
                 ReflowQueryType::NodeOverflowQuery(node) => {
                     let node = unsafe { ServoLayoutNode::new(&node) };
                     rw_data.overflow_response = process_node_overflow_request(node);
                 },
                 ReflowQueryType::NodeLayerIdQuery(node) => {
                     let node = unsafe { ServoLayoutNode::new(&node) };
                     rw_data.layer_id_response = Some(process_node_layer_id_request(node));
@@ -1256,21 +1255,21 @@ impl LayoutThread {
                 ReflowQueryType::ResolvedStyleQuery(node, ref pseudo, ref property) => {
                     let node = unsafe { ServoLayoutNode::new(&node) };
                     let layout_context = LayoutContext::new(&shared_layout_context);
                     rw_data.resolved_style_response =
                         process_resolved_style_request(node,
                                                        &layout_context,
                                                        pseudo,
                                                        property,
-                                                       &mut root_flow);
+                                                       root_flow);
                 },
                 ReflowQueryType::OffsetParentQuery(node) => {
                     let node = unsafe { ServoLayoutNode::new(&node) };
-                    rw_data.offset_parent_response = process_offset_parent_query(node, &mut root_flow);
+                    rw_data.offset_parent_response = process_offset_parent_query(node, root_flow);
                 },
                 ReflowQueryType::MarginStyleQuery(node) => {
                     let node = unsafe { ServoLayoutNode::new(&node) };
                     rw_data.margin_style_response = process_margin_style_query(node);
                 },
                 ReflowQueryType::NoQuery => {}
             }
         }
@@ -1441,17 +1440,17 @@ impl LayoutThread {
             if opts::get().trace_layout {
                 layout_debug::begin_trace(root_flow.clone());
             }
 
             // Resolve generated content.
             profile(time::ProfilerCategory::LayoutGeneratedContent,
                     self.profiler_metadata(),
                     self.time_profiler_chan.clone(),
-                    || sequential::resolve_generated_content(&mut root_flow, &layout_context));
+                    || sequential::resolve_generated_content(flow_ref::deref_mut(&mut root_flow), &layout_context));
 
             // Guess float placement.
             profile(time::ProfilerCategory::LayoutFloatPlacementSpeculation,
                     self.profiler_metadata(),
                     self.time_profiler_chan.clone(),
                     || sequential::guess_float_placement(flow_ref::deref_mut(&mut root_flow)));
 
             // Perform the primary layout passes over the flow tree to compute the locations of all
@@ -1460,25 +1459,25 @@ impl LayoutThread {
                 profile(time::ProfilerCategory::LayoutMain,
                         self.profiler_metadata(),
                         self.time_profiler_chan.clone(),
                         || {
                     let profiler_metadata = self.profiler_metadata();
                     match self.parallel_traversal {
                         None => {
                             // Sequential mode.
-                            LayoutThread::solve_constraints(&mut root_flow, &layout_context)
+                            LayoutThread::solve_constraints(flow_ref::deref_mut(&mut root_flow), &layout_context)
                         }
                         Some(ref mut parallel) => {
                             // Parallel mode.
                             LayoutThread::solve_constraints_parallel(parallel,
-                                                                   &mut root_flow,
-                                                                   profiler_metadata,
-                                                                   self.time_profiler_chan.clone(),
-                                                                   &*layout_context);
+                                                                     flow_ref::deref_mut(&mut root_flow),
+                                                                     profiler_metadata,
+                                                                     self.time_profiler_chan.clone(),
+                                                                     &*layout_context);
                         }
                     }
                 });
             }
 
             profile(time::ProfilerCategory::LayoutStoreOverflow,
                     self.profiler_metadata(),
                     self.time_profiler_chan.clone(),
@@ -1494,17 +1493,17 @@ impl LayoutThread {
 
     fn perform_post_main_layout_passes(&mut self,
                                        data: &Reflow,
                                        rw_data: &mut LayoutThreadData,
                                        layout_context: &mut SharedLayoutContext) {
         // Build the display list if necessary, and send it to the painter.
         if let Some(mut root_flow) = self.root_flow.clone() {
             self.compute_abs_pos_and_build_display_list(data,
-                                                        &mut root_flow,
+                                                        flow_ref::deref_mut(&mut root_flow),
                                                         &mut *layout_context,
                                                         rw_data);
             self.first_reflow = false;
 
             if opts::get().trace_layout {
                 layout_debug::end_trace();
             }