Auto merge of #18754 - mbrubeck:unsafe-flow, r=nox

Use raw pointers instead of transmute for UnsafeFlow

This makes the code depend a bit less on rustc implementation details.

r? pcwalton

---
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes do not require tests because they are refactoring only

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18754)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-10-05 21:24:24 -05:00 committed by GitHub
commit 8338df1c70

View file

@ -8,6 +8,7 @@
#![allow(unsafe_code)] #![allow(unsafe_code)]
use block::BlockFlow;
use context::LayoutContext; use context::LayoutContext;
use flow::{self, Flow}; use flow::{self, Flow};
use flow_ref::FlowRef; use flow_ref::FlowRef;
@ -16,6 +17,7 @@ use rayon;
use servo_config::opts; use servo_config::opts;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::mem; use std::mem;
use std::ptr;
use std::sync::atomic::{AtomicIsize, Ordering}; use std::sync::atomic::{AtomicIsize, Ordering};
use traversal::{AssignBSizes, AssignISizes, BubbleISizes}; use traversal::{AssignBSizes, AssignISizes, BubbleISizes};
use traversal::{PostorderFlowTraversal, PreorderFlowTraversal}; use traversal::{PostorderFlowTraversal, PreorderFlowTraversal};
@ -26,22 +28,18 @@ const CHUNK_SIZE: usize = 16;
pub type FlowList = SmallVec<[UnsafeFlow; CHUNK_SIZE]>; pub type FlowList = SmallVec<[UnsafeFlow; CHUNK_SIZE]>;
/// Vtable + pointer representation of a Flow trait object. /// Vtable + pointer representation of a Flow trait object.
pub type UnsafeFlow = (usize, usize); #[derive(Clone, Copy, Eq, PartialEq)]
pub struct UnsafeFlow(*const Flow);
unsafe impl Sync for UnsafeFlow {}
unsafe impl Send for UnsafeFlow {}
fn null_unsafe_flow() -> UnsafeFlow { fn null_unsafe_flow() -> UnsafeFlow {
(0, 0) UnsafeFlow(ptr::null::<BlockFlow>())
} }
pub fn mut_owned_flow_to_unsafe_flow(flow: *mut FlowRef) -> UnsafeFlow { pub fn mut_owned_flow_to_unsafe_flow(flow: *mut FlowRef) -> UnsafeFlow {
unsafe { unsafe { UnsafeFlow(&**flow) }
mem::transmute::<&Flow, UnsafeFlow>(&**flow)
}
}
pub fn borrowed_flow_to_unsafe_flow(flow: &Flow) -> UnsafeFlow {
unsafe {
mem::transmute::<&Flow, UnsafeFlow>(flow)
}
} }
/// Information that we need stored in each flow. /// Information that we need stored in each flow.
@ -103,7 +101,7 @@ fn bottom_up_flow(mut unsafe_flow: UnsafeFlow,
// of our parent to finish processing? If so, we can continue // of our parent to finish processing? If so, we can continue
// on with our parent; otherwise, we've gotta wait. // on with our parent; otherwise, we've gotta wait.
let parent: &mut Flow = unsafe { let parent: &mut Flow = unsafe {
mem::transmute(unsafe_parent) &mut *(unsafe_parent.0 as *mut Flow)
}; };
let parent_base = flow::mut_base(parent); let parent_base = flow::mut_base(parent);
if parent_base.parallel.children_count.fetch_sub(1, Ordering::Relaxed) == 1 { if parent_base.parallel.children_count.fetch_sub(1, Ordering::Relaxed) == 1 {
@ -140,7 +138,7 @@ fn top_down_flow<'scope>(unsafe_flows: &[UnsafeFlow],
// Possibly enqueue the children. // Possibly enqueue the children.
for kid in flow::child_iter_mut(flow) { for kid in flow::child_iter_mut(flow) {
had_children = true; had_children = true;
discovered_child_flows.push(borrowed_flow_to_unsafe_flow(kid)); discovered_child_flows.push(UnsafeFlow(kid));
} }
} }
@ -191,7 +189,7 @@ pub fn reflow(
let assign_isize_traversal = &AssignISizes { layout_context: &context }; let assign_isize_traversal = &AssignISizes { layout_context: &context };
let assign_bsize_traversal = &AssignBSizes { layout_context: &context }; let assign_bsize_traversal = &AssignBSizes { layout_context: &context };
let nodes = [borrowed_flow_to_unsafe_flow(root)]; let nodes = [UnsafeFlow(root)];
queue.install(move || { queue.install(move || {
rayon::scope(move |scope| { rayon::scope(move |scope| {