Auto merge of #13520 - bholley:atomic_refcell, r=emilio

Implement AtomicRefCell and use it for layout/style node data

See the rationale at https://bugzilla.mozilla.org/show_bug.cgi?id=1305141

<!-- 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/13520)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-10-02 21:24:11 -05:00 committed by GitHub
commit c93eaca6a3
20 changed files with 271 additions and 193 deletions

View file

@ -16,7 +16,7 @@
use app_units::Au; use app_units::Au;
use block::BlockFlow; use block::BlockFlow;
use context::LayoutContext; use context::LayoutContext;
use data::{HAS_NEWLY_CONSTRUCTED_FLOW, PrivateLayoutData}; use data::{HAS_NEWLY_CONSTRUCTED_FLOW, PersistentLayoutData};
use flex::FlexFlow; use flex::FlexFlow;
use floats::FloatKind; use floats::FloatKind;
use flow::{self, AbsoluteDescendants, IS_ABSOLUTELY_POSITIONED, ImmutableFlowUtils}; use flow::{self, AbsoluteDescendants, IS_ABSOLUTELY_POSITIONED, ImmutableFlowUtils};
@ -218,8 +218,8 @@ impl InlineFragmentsAccumulator {
enclosing_node: Some(InlineFragmentNodeInfo { enclosing_node: Some(InlineFragmentNodeInfo {
address: node.opaque(), address: node.opaque(),
pseudo: node.get_pseudo_element_type().strip(), pseudo: node.get_pseudo_element_type().strip(),
style: node.style(style_context).clone(), style: node.style(style_context),
selected_style: node.selected_style(style_context).clone(), selected_style: node.selected_style(style_context),
flags: InlineFragmentNodeFlags::empty(), flags: InlineFragmentNodeFlags::empty(),
}), }),
bidi_control_chars: None, bidi_control_chars: None,
@ -355,12 +355,12 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
let style_context = self.style_context(); let style_context = self.style_context();
if child.is_table_cell() { if child.is_table_cell() {
let mut style = child_node.style(style_context).clone(); let mut style = child_node.style(style_context);
properties::modify_style_for_anonymous_table_object(&mut style, display::T::table_row); properties::modify_style_for_anonymous_table_object(&mut style, display::T::table_row);
let fragment = Fragment::from_opaque_node_and_style(child_node.opaque(), let fragment = Fragment::from_opaque_node_and_style(child_node.opaque(),
PseudoElementType::Normal, PseudoElementType::Normal,
style, style,
child_node.selected_style(style_context).clone(), child_node.selected_style(style_context),
child_node.restyle_damage(), child_node.restyle_damage(),
SpecificFragmentInfo::TableRow); SpecificFragmentInfo::TableRow);
let mut new_child: FlowRef = Arc::new(TableRowFlow::from_fragment(fragment)); let mut new_child: FlowRef = Arc::new(TableRowFlow::from_fragment(fragment));
@ -369,12 +369,12 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
*child = new_child *child = new_child
} }
if child.is_table_row() || child.is_table_rowgroup() { if child.is_table_row() || child.is_table_rowgroup() {
let mut style = child_node.style(style_context).clone(); let mut style = child_node.style(style_context);
properties::modify_style_for_anonymous_table_object(&mut style, display::T::table); properties::modify_style_for_anonymous_table_object(&mut style, display::T::table);
let fragment = Fragment::from_opaque_node_and_style(child_node.opaque(), let fragment = Fragment::from_opaque_node_and_style(child_node.opaque(),
PseudoElementType::Normal, PseudoElementType::Normal,
style, style,
child_node.selected_style(style_context).clone(), child_node.selected_style(style_context),
child_node.restyle_damage(), child_node.restyle_damage(),
SpecificFragmentInfo::Table); SpecificFragmentInfo::Table);
let mut new_child: FlowRef = Arc::new(TableFlow::from_fragment(fragment)); let mut new_child: FlowRef = Arc::new(TableFlow::from_fragment(fragment));
@ -383,13 +383,13 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
*child = new_child *child = new_child
} }
if child.is_table() { if child.is_table() {
let mut style = child_node.style(style_context).clone(); let mut style = child_node.style(style_context);
properties::modify_style_for_anonymous_table_object(&mut style, display::T::table); properties::modify_style_for_anonymous_table_object(&mut style, display::T::table);
let fragment = let fragment =
Fragment::from_opaque_node_and_style(child_node.opaque(), Fragment::from_opaque_node_and_style(child_node.opaque(),
PseudoElementType::Normal, PseudoElementType::Normal,
style, style,
child_node.selected_style(style_context).clone(), child_node.selected_style(style_context),
child_node.restyle_damage(), child_node.restyle_damage(),
SpecificFragmentInfo::TableWrapper); SpecificFragmentInfo::TableWrapper);
let mut new_child: FlowRef = Arc::new(TableWrapperFlow::from_fragment(fragment, None)); let mut new_child: FlowRef = Arc::new(TableWrapperFlow::from_fragment(fragment, None));
@ -477,7 +477,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
let (ascent, descent) = let (ascent, descent) =
inline_flow.compute_minimum_ascent_and_descent(&mut self.layout_context inline_flow.compute_minimum_ascent_and_descent(&mut self.layout_context
.font_context(), .font_context(),
&**node.style(self.style_context())); &node.style(self.style_context()));
inline_flow.minimum_block_size_above_baseline = ascent; inline_flow.minimum_block_size_above_baseline = ascent;
inline_flow.minimum_depth_below_baseline = descent; inline_flow.minimum_depth_below_baseline = descent;
} }
@ -589,7 +589,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
let fragment = Fragment::from_opaque_node_and_style(whitespace_node, let fragment = Fragment::from_opaque_node_and_style(whitespace_node,
whitespace_pseudo, whitespace_pseudo,
whitespace_style, whitespace_style,
node.selected_style(style_context).clone(), node.selected_style(style_context),
whitespace_damage, whitespace_damage,
fragment_info); fragment_info);
inline_fragment_accumulator.fragments.fragments.push_back(fragment); inline_fragment_accumulator.fragments.fragments.push_back(fragment);
@ -692,7 +692,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
} }
} }
let mut style = node.style(self.style_context()).clone(); let mut style = node.style(self.style_context());
if node_is_input_or_text_area { if node_is_input_or_text_area {
style = self.style_context().stylist. style = self.style_context().stylist.
precomputed_values_for_pseudo(&PseudoElement::ServoInputText, Some(&style)).unwrap(); precomputed_values_for_pseudo(&PseudoElement::ServoInputText, Some(&style)).unwrap();
@ -732,7 +732,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
node.opaque(), node.opaque(),
node.get_pseudo_element_type().strip(), node.get_pseudo_element_type().strip(),
style, style,
selected_style.clone(), selected_style,
node.restyle_damage(), node.restyle_damage(),
specific_fragment_info)) specific_fragment_info))
} }
@ -806,7 +806,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
-> ConstructionResult { -> ConstructionResult {
let mut opt_inline_block_splits: LinkedList<InlineBlockSplit> = LinkedList::new(); let mut opt_inline_block_splits: LinkedList<InlineBlockSplit> = LinkedList::new();
let mut fragment_accumulator = InlineFragmentsAccumulator::from_inline_node(node, self.style_context()); let mut fragment_accumulator = InlineFragmentsAccumulator::from_inline_node(node, self.style_context());
fragment_accumulator.bidi_control_chars = bidi_control_chars(&*node.style(self.style_context())); fragment_accumulator.bidi_control_chars = bidi_control_chars(&node.style(self.style_context()));
let mut abs_descendants = AbsoluteDescendants::new(); let mut abs_descendants = AbsoluteDescendants::new();
@ -882,7 +882,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
Fragment::from_opaque_node_and_style(whitespace_node, Fragment::from_opaque_node_and_style(whitespace_node,
whitespace_pseudo, whitespace_pseudo,
whitespace_style, whitespace_style,
node.selected_style(self.style_context()).clone(), node.selected_style(self.style_context()),
whitespace_damage, whitespace_damage,
fragment_info); fragment_info);
fragment_accumulator.fragments.fragments.push_back(fragment) fragment_accumulator.fragments.fragments.push_back(fragment)
@ -905,7 +905,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
let fragment = Fragment::from_opaque_node_and_style(node.opaque(), let fragment = Fragment::from_opaque_node_and_style(node.opaque(),
node.get_pseudo_element_type().strip(), node.get_pseudo_element_type().strip(),
modified_style, modified_style,
node.selected_style(self.style_context()).clone(), node.selected_style(self.style_context()),
node.restyle_damage(), node.restyle_damage(),
info); info);
fragment_accumulator.fragments.fragments.push_back(fragment) fragment_accumulator.fragments.fragments.push_back(fragment)
@ -949,13 +949,13 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
return ConstructionResult::ConstructionItem(ConstructionItem::Whitespace( return ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(
node.opaque(), node.opaque(),
node.get_pseudo_element_type().strip(), node.get_pseudo_element_type().strip(),
node.style(self.style_context()).clone(), node.style(self.style_context()),
node.restyle_damage())) node.restyle_damage()))
} }
// Modify the style as necessary. (See the comment in // Modify the style as necessary. (See the comment in
// `properties::modify_style_for_replaced_content()`.) // `properties::modify_style_for_replaced_content()`.)
let mut style = node.style(self.style_context()).clone(); let mut style = node.style(self.style_context());
match node.get_pseudo_element_type() { match node.get_pseudo_element_type() {
PseudoElementType::Before(_) | PseudoElementType::Before(_) |
PseudoElementType::After(_) => {} PseudoElementType::After(_) => {}
@ -993,14 +993,14 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
}; };
let style_context = self.style_context(); let style_context = self.style_context();
let mut modified_style = (*node.style(self.style_context())).clone(); let mut modified_style = node.style(self.style_context());
properties::modify_style_for_outer_inline_block_fragment(&mut modified_style); properties::modify_style_for_outer_inline_block_fragment(&mut modified_style);
let fragment_info = SpecificFragmentInfo::InlineBlock(InlineBlockFragmentInfo::new( let fragment_info = SpecificFragmentInfo::InlineBlock(InlineBlockFragmentInfo::new(
block_flow)); block_flow));
let fragment = Fragment::from_opaque_node_and_style(node.opaque(), let fragment = Fragment::from_opaque_node_and_style(node.opaque(),
node.get_pseudo_element_type().strip(), node.get_pseudo_element_type().strip(),
modified_style, modified_style,
node.selected_style(style_context).clone(), node.selected_style(style_context),
node.restyle_damage(), node.restyle_damage(),
fragment_info); fragment_info);
@ -1030,12 +1030,12 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
let fragment_info = SpecificFragmentInfo::InlineAbsoluteHypothetical( let fragment_info = SpecificFragmentInfo::InlineAbsoluteHypothetical(
InlineAbsoluteHypotheticalFragmentInfo::new(block_flow)); InlineAbsoluteHypotheticalFragmentInfo::new(block_flow));
let style_context = self.style_context(); let style_context = self.style_context();
let mut style = node.style(style_context).clone(); let mut style = node.style(style_context);
properties::modify_style_for_inline_absolute_hypothetical_fragment(&mut style); properties::modify_style_for_inline_absolute_hypothetical_fragment(&mut style);
let fragment = Fragment::from_opaque_node_and_style(node.opaque(), let fragment = Fragment::from_opaque_node_and_style(node.opaque(),
PseudoElementType::Normal, PseudoElementType::Normal,
style, style,
node.selected_style(style_context).clone(), node.selected_style(style_context),
node.restyle_damage(), node.restyle_damage(),
fragment_info); fragment_info);
@ -1412,7 +1412,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
let mut set_has_newly_constructed_flow_flag = false; let mut set_has_newly_constructed_flow_flag = false;
let result = { let result = {
let mut style = node.style(self.style_context()).clone(); let mut style = node.style(self.style_context());
let mut data = node.mutate_layout_data().unwrap(); let mut data = node.mutate_layout_data().unwrap();
let damage = data.restyle_damage; let damage = data.restyle_damage;
@ -1679,7 +1679,7 @@ trait NodeUtils {
/// Returns true if this node doesn't render its kids and false otherwise. /// Returns true if this node doesn't render its kids and false otherwise.
fn is_replaced_content(&self) -> bool; fn is_replaced_content(&self) -> bool;
fn construction_result_mut(self, layout_data: &mut PrivateLayoutData) -> &mut ConstructionResult; fn construction_result_mut(self, layout_data: &mut PersistentLayoutData) -> &mut ConstructionResult;
/// Sets the construction result of a flow. /// Sets the construction result of a flow.
fn set_flow_construction_result(self, result: ConstructionResult); fn set_flow_construction_result(self, result: ConstructionResult);
@ -1708,7 +1708,7 @@ impl<ConcreteThreadSafeLayoutNode> NodeUtils for ConcreteThreadSafeLayoutNode
} }
} }
fn construction_result_mut(self, data: &mut PrivateLayoutData) -> &mut ConstructionResult { fn construction_result_mut(self, data: &mut PersistentLayoutData) -> &mut ConstructionResult {
match self.get_pseudo_element_type() { match self.get_pseudo_element_type() {
PseudoElementType::Before(_) => &mut data.before_flow_construction_result, PseudoElementType::Before(_) => &mut data.before_flow_construction_result,
PseudoElementType::After (_) => &mut data.after_flow_construction_result, PseudoElementType::After (_) => &mut data.after_flow_construction_result,

View file

@ -4,15 +4,15 @@
use construct::ConstructionResult; use construct::ConstructionResult;
use script_layout_interface::restyle_damage::RestyleDamage; use script_layout_interface::restyle_damage::RestyleDamage;
use style::data::PrivateStyleData; use style::data::PersistentStyleData;
/// Data that layout associates with a node. /// Data that layout associates with a node.
pub struct PrivateLayoutData { pub struct PersistentLayoutData {
/// Data that the style system associates with a node. When the /// Data that the style system associates with a node. When the
/// style system is being used standalone, this is all that hangs /// style system is being used standalone, this is all that hangs
/// off the node. This must be first to permit the various /// off the node. This must be first to permit the various
/// transmuations between PrivateStyleData PrivateLayoutData. /// transmutations between PersistentStyleData and PersistentLayoutData.
pub style_data: PrivateStyleData, pub style_data: PersistentStyleData,
/// Description of how to account for recent style changes. /// Description of how to account for recent style changes.
pub restyle_damage: RestyleDamage, pub restyle_damage: RestyleDamage,
@ -34,11 +34,11 @@ pub struct PrivateLayoutData {
pub flags: LayoutDataFlags, pub flags: LayoutDataFlags,
} }
impl PrivateLayoutData { impl PersistentLayoutData {
/// Creates new layout data. /// Creates new layout data.
pub fn new() -> PrivateLayoutData { pub fn new() -> PersistentLayoutData {
PrivateLayoutData { PersistentLayoutData {
style_data: PrivateStyleData::new(), style_data: PersistentStyleData::new(),
restyle_damage: RestyleDamage::empty(), restyle_damage: RestyleDamage::empty(),
flow_construction_result: ConstructionResult::None, flow_construction_result: ConstructionResult::None,
before_flow_construction_result: ConstructionResult::None, before_flow_construction_result: ConstructionResult::None,

View file

@ -1272,7 +1272,7 @@ impl<'a> ImmutableFlowUtils for &'a Flow {
/// as it's harder to understand. /// as it's harder to understand.
fn generate_missing_child_flow<N: ThreadSafeLayoutNode>(self, node: &N, ctx: &LayoutContext) -> FlowRef { fn generate_missing_child_flow<N: ThreadSafeLayoutNode>(self, node: &N, ctx: &LayoutContext) -> FlowRef {
let style_context = ctx.style_context(); let style_context = ctx.style_context();
let mut style = node.style(style_context).clone(); let mut style = node.style(style_context);
match self.class() { match self.class() {
FlowClass::Table | FlowClass::TableRowGroup => { FlowClass::Table | FlowClass::TableRowGroup => {
properties::modify_style_for_anonymous_table_object( properties::modify_style_for_anonymous_table_object(
@ -1282,7 +1282,7 @@ impl<'a> ImmutableFlowUtils for &'a Flow {
node.opaque(), node.opaque(),
PseudoElementType::Normal, PseudoElementType::Normal,
style, style,
node.selected_style(style_context).clone(), node.selected_style(style_context),
node.restyle_damage(), node.restyle_damage(),
SpecificFragmentInfo::TableRow); SpecificFragmentInfo::TableRow);
Arc::new(TableRowFlow::from_fragment(fragment)) Arc::new(TableRowFlow::from_fragment(fragment))
@ -1295,7 +1295,7 @@ impl<'a> ImmutableFlowUtils for &'a Flow {
node.opaque(), node.opaque(),
PseudoElementType::Normal, PseudoElementType::Normal,
style, style,
node.selected_style(style_context).clone(), node.selected_style(style_context),
node.restyle_damage(), node.restyle_damage(),
SpecificFragmentInfo::TableCell); SpecificFragmentInfo::TableCell);
let hide = node.style(style_context).get_inheritedtable().empty_cells == empty_cells::T::hide; let hide = node.style(style_context).get_inheritedtable().empty_cells == empty_cells::T::hide;
@ -1309,7 +1309,7 @@ impl<'a> ImmutableFlowUtils for &'a Flow {
Fragment::from_opaque_node_and_style(node.opaque(), Fragment::from_opaque_node_and_style(node.opaque(),
PseudoElementType::Normal, PseudoElementType::Normal,
style, style,
node.selected_style(style_context).clone(), node.selected_style(style_context),
node.restyle_damage(), node.restyle_damage(),
SpecificFragmentInfo::Generic); SpecificFragmentInfo::Generic);
Arc::new(BlockFlow::from_fragment(fragment, None)) Arc::new(BlockFlow::from_fragment(fragment, None))

View file

@ -856,7 +856,7 @@ impl Fragment {
/// Constructs a new `Fragment` instance. /// Constructs a new `Fragment` instance.
pub fn new<N: ThreadSafeLayoutNode>(node: &N, specific: SpecificFragmentInfo, ctx: &LayoutContext) -> Fragment { pub fn new<N: ThreadSafeLayoutNode>(node: &N, specific: SpecificFragmentInfo, ctx: &LayoutContext) -> Fragment {
let style_context = ctx.style_context(); let style_context = ctx.style_context();
let style = node.style(style_context).clone(); let style = node.style(style_context);
let writing_mode = style.writing_mode; let writing_mode = style.writing_mode;
let mut restyle_damage = node.restyle_damage(); let mut restyle_damage = node.restyle_damage();
@ -865,7 +865,7 @@ impl Fragment {
Fragment { Fragment {
node: node.opaque(), node: node.opaque(),
style: style, style: style,
selected_style: node.selected_style(style_context).clone(), selected_style: node.selected_style(style_context),
restyle_damage: restyle_damage, restyle_damage: restyle_damage,
border_box: LogicalRect::zero(writing_mode), border_box: LogicalRect::zero(writing_mode),
border_padding: LogicalMargin::zero(writing_mode), border_padding: LogicalMargin::zero(writing_mode),

View file

@ -31,33 +31,25 @@
#![allow(unsafe_code)] #![allow(unsafe_code)]
use core::nonzero::NonZero; use core::nonzero::NonZero;
use data::{LayoutDataFlags, PrivateLayoutData}; use data::{LayoutDataFlags, PersistentLayoutData};
use script_layout_interface::{OpaqueStyleAndLayoutData, PartialStyleAndLayoutData}; use script_layout_interface::{OpaqueStyleAndLayoutData, PartialPersistentLayoutData};
use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode}; use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode};
use style::atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
use style::computed_values::content::{self, ContentItem}; use style::computed_values::content::{self, ContentItem};
use style::refcell::{Ref, RefCell, RefMut};
pub type NonOpaqueStyleAndLayoutData = *mut RefCell<PrivateLayoutData>; pub type NonOpaqueStyleAndLayoutData = *mut AtomicRefCell<PersistentLayoutData>;
pub trait LayoutNodeLayoutData { pub trait LayoutNodeLayoutData {
/// Similar to borrow_data*, but returns the full PrivateLayoutData rather /// Similar to borrow_data*, but returns the full PersistentLayoutData rather
/// than only the PrivateStyleData. /// than only the PersistentStyleData.
unsafe fn borrow_layout_data_unchecked(&self) -> Option<*const PrivateLayoutData>; fn borrow_layout_data(&self) -> Option<AtomicRef<PersistentLayoutData>>;
fn borrow_layout_data(&self) -> Option<Ref<PrivateLayoutData>>; fn mutate_layout_data(&self) -> Option<AtomicRefMut<PersistentLayoutData>>;
fn mutate_layout_data(&self) -> Option<RefMut<PrivateLayoutData>>;
fn initialize_data(self); fn initialize_data(self);
fn flow_debug_id(self) -> usize; fn flow_debug_id(self) -> usize;
} }
impl<T: LayoutNode> LayoutNodeLayoutData for T { impl<T: LayoutNode> LayoutNodeLayoutData for T {
unsafe fn borrow_layout_data_unchecked(&self) -> Option<*const PrivateLayoutData> { fn borrow_layout_data(&self) -> Option<AtomicRef<PersistentLayoutData>> {
self.get_style_and_layout_data().map(|opaque| {
let container = *opaque.ptr as NonOpaqueStyleAndLayoutData;
&(*(*container).as_unsafe_cell().get()) as *const PrivateLayoutData
})
}
fn borrow_layout_data(&self) -> Option<Ref<PrivateLayoutData>> {
unsafe { unsafe {
self.get_style_and_layout_data().map(|opaque| { self.get_style_and_layout_data().map(|opaque| {
let container = *opaque.ptr as NonOpaqueStyleAndLayoutData; let container = *opaque.ptr as NonOpaqueStyleAndLayoutData;
@ -66,7 +58,7 @@ impl<T: LayoutNode> LayoutNodeLayoutData for T {
} }
} }
fn mutate_layout_data(&self) -> Option<RefMut<PrivateLayoutData>> { fn mutate_layout_data(&self) -> Option<AtomicRefMut<PersistentLayoutData>> {
unsafe { unsafe {
self.get_style_and_layout_data().map(|opaque| { self.get_style_and_layout_data().map(|opaque| {
let container = *opaque.ptr as NonOpaqueStyleAndLayoutData; let container = *opaque.ptr as NonOpaqueStyleAndLayoutData;
@ -76,11 +68,11 @@ impl<T: LayoutNode> LayoutNodeLayoutData for T {
} }
fn initialize_data(self) { fn initialize_data(self) {
if unsafe { self.borrow_data_unchecked() }.is_none() { if self.borrow_data().is_none() {
let ptr: NonOpaqueStyleAndLayoutData = let ptr: NonOpaqueStyleAndLayoutData =
Box::into_raw(box RefCell::new(PrivateLayoutData::new())); Box::into_raw(box AtomicRefCell::new(PersistentLayoutData::new()));
let opaque = OpaqueStyleAndLayoutData { let opaque = OpaqueStyleAndLayoutData {
ptr: unsafe { NonZero::new(ptr as *mut RefCell<PartialStyleAndLayoutData>) } ptr: unsafe { NonZero::new(ptr as *mut AtomicRefCell<PartialPersistentLayoutData>) }
}; };
self.init_style_and_layout_data(opaque); self.init_style_and_layout_data(opaque);
} }
@ -94,19 +86,17 @@ impl<T: LayoutNode> LayoutNodeLayoutData for T {
pub trait ThreadSafeLayoutNodeHelpers { pub trait ThreadSafeLayoutNodeHelpers {
fn flow_debug_id(self) -> usize; fn flow_debug_id(self) -> usize;
unsafe fn borrow_layout_data_unchecked(&self) -> Option<*const PrivateLayoutData>;
/// Borrows the layout data immutably. Fails on a conflicting borrow. /// Borrows the layout data immutably. Fails on a conflicting borrow.
/// ///
/// TODO(pcwalton): Make this private. It will let us avoid borrow flag checks in some cases. /// TODO(pcwalton): Make this private. It will let us avoid borrow flag checks in some cases.
#[inline(always)] #[inline(always)]
fn borrow_layout_data(&self) -> Option<Ref<PrivateLayoutData>>; fn borrow_layout_data(&self) -> Option<AtomicRef<PersistentLayoutData>>;
/// Borrows the layout data mutably. Fails on a conflicting borrow. /// Borrows the layout data mutably. Fails on a conflicting borrow.
/// ///
/// TODO(pcwalton): Make this private. It will let us avoid borrow flag checks in some cases. /// TODO(pcwalton): Make this private. It will let us avoid borrow flag checks in some cases.
#[inline(always)] #[inline(always)]
fn mutate_layout_data(&self) -> Option<RefMut<PrivateLayoutData>>; fn mutate_layout_data(&self) -> Option<AtomicRefMut<PersistentLayoutData>>;
/// Returns the layout data flags for this node. /// Returns the layout data flags for this node.
fn flags(self) -> LayoutDataFlags; fn flags(self) -> LayoutDataFlags;
@ -129,14 +119,7 @@ impl<T: ThreadSafeLayoutNode> ThreadSafeLayoutNodeHelpers for T {
self.borrow_layout_data().map_or(0, |d| d.flow_construction_result.debug_id()) self.borrow_layout_data().map_or(0, |d| d.flow_construction_result.debug_id())
} }
unsafe fn borrow_layout_data_unchecked(&self) -> Option<*const PrivateLayoutData> { fn borrow_layout_data(&self) -> Option<AtomicRef<PersistentLayoutData>> {
self.get_style_and_layout_data().map(|opaque| {
let container = *opaque.ptr as NonOpaqueStyleAndLayoutData;
&(*(*container).as_unsafe_cell().get()) as *const PrivateLayoutData
})
}
fn borrow_layout_data(&self) -> Option<Ref<PrivateLayoutData>> {
unsafe { unsafe {
self.get_style_and_layout_data().map(|opaque| { self.get_style_and_layout_data().map(|opaque| {
let container = *opaque.ptr as NonOpaqueStyleAndLayoutData; let container = *opaque.ptr as NonOpaqueStyleAndLayoutData;
@ -145,7 +128,7 @@ impl<T: ThreadSafeLayoutNode> ThreadSafeLayoutNodeHelpers for T {
} }
} }
fn mutate_layout_data(&self) -> Option<RefMut<PrivateLayoutData>> { fn mutate_layout_data(&self) -> Option<AtomicRefMut<PersistentLayoutData>> {
unsafe { unsafe {
self.get_style_and_layout_data().map(|opaque| { self.get_style_and_layout_data().map(|opaque| {
let container = *opaque.ptr as NonOpaqueStyleAndLayoutData; let container = *opaque.ptr as NonOpaqueStyleAndLayoutData;
@ -155,9 +138,7 @@ impl<T: ThreadSafeLayoutNode> ThreadSafeLayoutNodeHelpers for T {
} }
fn flags(self) -> LayoutDataFlags { fn flags(self) -> LayoutDataFlags {
unsafe { self.borrow_layout_data().as_ref().unwrap().flags
(*self.borrow_layout_data_unchecked().unwrap()).flags
}
} }
fn insert_flags(self, new_flags: LayoutDataFlags) { fn insert_flags(self, new_flags: LayoutDataFlags) {

View file

@ -86,7 +86,7 @@ use profile_traits::mem::{self, Report, ReportKind, ReportsChan};
use profile_traits::time::{self, TimerMetadata, profile}; use profile_traits::time::{self, TimerMetadata, profile};
use profile_traits::time::{TimerMetadataFrameType, TimerMetadataReflowType}; use profile_traits::time::{TimerMetadataFrameType, TimerMetadataReflowType};
use script::layout_wrapper::{ServoLayoutDocument, ServoLayoutNode}; use script::layout_wrapper::{ServoLayoutDocument, ServoLayoutNode};
use script_layout_interface::{OpaqueStyleAndLayoutData, PartialStyleAndLayoutData}; use script_layout_interface::{OpaqueStyleAndLayoutData, PartialPersistentLayoutData};
use script_layout_interface::message::{Msg, NewLayoutThreadInfo, Reflow, ReflowQueryType, ScriptReflow}; use script_layout_interface::message::{Msg, NewLayoutThreadInfo, Reflow, ReflowQueryType, ScriptReflow};
use script_layout_interface::reporter::CSSErrorReporter; use script_layout_interface::reporter::CSSErrorReporter;
use script_layout_interface::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, REPOSITION}; use script_layout_interface::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, REPOSITION};
@ -104,6 +104,7 @@ use std::sync::{Arc, Mutex, MutexGuard, RwLock};
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::mpsc::{Receiver, Sender, channel}; use std::sync::mpsc::{Receiver, Sender, channel};
use style::animation::Animation; use style::animation::Animation;
use style::atomic_refcell::AtomicRefCell;
use style::computed_values::{filter, mix_blend_mode}; use style::computed_values::{filter, mix_blend_mode};
use style::context::{LocalStyleContextCreationInfo, ReflowGoal, SharedStyleContext}; use style::context::{LocalStyleContextCreationInfo, ReflowGoal, SharedStyleContext};
use style::dom::{TDocument, TElement, TNode}; use style::dom::{TDocument, TElement, TNode};
@ -112,7 +113,6 @@ use style::logical_geometry::LogicalPoint;
use style::media_queries::{Device, MediaType}; use style::media_queries::{Device, MediaType};
use style::parallel::WorkQueueData; use style::parallel::WorkQueueData;
use style::parser::ParserContextExtraData; use style::parser::ParserContextExtraData;
use style::refcell::RefCell;
use style::selector_matching::Stylist; use style::selector_matching::Stylist;
use style::stylesheets::{CSSRuleIteratorExt, Origin, Stylesheet, UserAgentStylesheets}; use style::stylesheets::{CSSRuleIteratorExt, Origin, Stylesheet, UserAgentStylesheets};
use style::thread_state; use style::thread_state;
@ -1594,7 +1594,7 @@ impl LayoutThread {
/// Handles a message to destroy layout data. Layout data must be destroyed on *this* thread /// Handles a message to destroy layout data. Layout data must be destroyed on *this* thread
/// because the struct type is transmuted to a different type on the script side. /// because the struct type is transmuted to a different type on the script side.
unsafe fn handle_reap_style_and_layout_data(&self, data: OpaqueStyleAndLayoutData) { unsafe fn handle_reap_style_and_layout_data(&self, data: OpaqueStyleAndLayoutData) {
let ptr: *mut RefCell<PartialStyleAndLayoutData> = *data.ptr; let ptr: *mut AtomicRefCell<PartialPersistentLayoutData> = *data.ptr;
let non_opaque: NonOpaqueStyleAndLayoutData = ptr as *mut _; let non_opaque: NonOpaqueStyleAndLayoutData = ptr as *mut _;
let _ = Box::from_raw(non_opaque); let _ = Box::from_raw(non_opaque);
} }

View file

@ -43,7 +43,7 @@ use gfx_traits::ByteIndex;
use msg::constellation_msg::PipelineId; use msg::constellation_msg::PipelineId;
use range::Range; use range::Range;
use script_layout_interface::{HTMLCanvasData, LayoutNodeType, TrustedNodeAddress}; use script_layout_interface::{HTMLCanvasData, LayoutNodeType, TrustedNodeAddress};
use script_layout_interface::{OpaqueStyleAndLayoutData, PartialStyleAndLayoutData}; use script_layout_interface::{OpaqueStyleAndLayoutData, PartialPersistentLayoutData};
use script_layout_interface::restyle_damage::RestyleDamage; use script_layout_interface::restyle_damage::RestyleDamage;
use script_layout_interface::wrapper_traits::{DangerousThreadSafeLayoutNode, LayoutNode, PseudoElementType}; use script_layout_interface::wrapper_traits::{DangerousThreadSafeLayoutNode, LayoutNode, PseudoElementType};
use script_layout_interface::wrapper_traits::{ThreadSafeLayoutElement, ThreadSafeLayoutNode}; use script_layout_interface::wrapper_traits::{ThreadSafeLayoutElement, ThreadSafeLayoutNode};
@ -54,15 +54,15 @@ use std::marker::PhantomData;
use std::mem::transmute; use std::mem::transmute;
use std::sync::Arc; use std::sync::Arc;
use string_cache::{Atom, Namespace}; use string_cache::{Atom, Namespace};
use style::atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
use style::attr::AttrValue; use style::attr::AttrValue;
use style::computed_values::display; use style::computed_values::display;
use style::context::SharedStyleContext; use style::context::SharedStyleContext;
use style::data::PrivateStyleData; use style::data::PersistentStyleData;
use style::dom::{LayoutIterator, NodeInfo, OpaqueNode, PresentationalHintsSynthetizer, TDocument, TElement, TNode}; use style::dom::{LayoutIterator, NodeInfo, OpaqueNode, PresentationalHintsSynthetizer, TDocument, TElement, TNode};
use style::dom::UnsafeNode; use style::dom::UnsafeNode;
use style::element_state::*; use style::element_state::*;
use style::properties::{ComputedValues, PropertyDeclarationBlock}; use style::properties::{ComputedValues, PropertyDeclarationBlock};
use style::refcell::{Ref, RefCell, RefMut};
use style::selector_impl::{ElementSnapshot, NonTSPseudoClass, PseudoElement, ServoSelectorImpl}; use style::selector_impl::{ElementSnapshot, NonTSPseudoClass, PseudoElement, ServoSelectorImpl};
use style::selector_matching::ApplicableDeclarationBlock; use style::selector_matching::ApplicableDeclarationBlock;
use style::sink::Push; use style::sink::Push;
@ -220,30 +220,20 @@ impl<'ln> TNode for ServoLayoutNode<'ln> {
self.node.set_flag(CAN_BE_FRAGMENTED, value) self.node.set_flag(CAN_BE_FRAGMENTED, value)
} }
unsafe fn borrow_data_unchecked(&self) -> Option<*const PrivateStyleData> { fn borrow_data(&self) -> Option<AtomicRef<PersistentStyleData>> {
self.get_style_data().map(|d| { self.get_style_data().map(|d| d.borrow())
&(*d.as_unsafe_cell().get()).style_data as *const _
})
} }
fn borrow_data(&self) -> Option<Ref<PrivateStyleData>> { fn mutate_data(&self) -> Option<AtomicRefMut<PersistentStyleData>> {
self.get_style_data().map(|d| { self.get_style_data().map(|d| d.borrow_mut())
Ref::map(d.borrow(), |d| &d.style_data)
})
}
fn mutate_data(&self) -> Option<RefMut<PrivateStyleData>> {
self.get_style_data().map(|d| {
RefMut::map(d.borrow_mut(), |d| &mut d.style_data)
})
} }
fn restyle_damage(self) -> RestyleDamage { fn restyle_damage(self) -> RestyleDamage {
self.get_style_data().unwrap().borrow().restyle_damage self.get_partial_layout_data().unwrap().borrow().restyle_damage
} }
fn set_restyle_damage(self, damage: RestyleDamage) { fn set_restyle_damage(self, damage: RestyleDamage) {
self.get_style_data().unwrap().borrow_mut().restyle_damage = damage; self.get_partial_layout_data().unwrap().borrow_mut().restyle_damage = damage;
} }
fn parent_node(&self) -> Option<ServoLayoutNode<'ln>> { fn parent_node(&self) -> Option<ServoLayoutNode<'ln>> {
@ -309,10 +299,12 @@ impl<'ln> LayoutNode for ServoLayoutNode<'ln> {
self.script_type_id().into() self.script_type_id().into()
} }
fn get_style_data(&self) -> Option<&RefCell<PartialStyleAndLayoutData>> { fn get_style_data(&self) -> Option<&AtomicRefCell<PersistentStyleData>> {
unsafe { unsafe {
self.get_jsmanaged().get_style_and_layout_data().map(|d| { self.get_jsmanaged().get_style_and_layout_data().map(|d| {
&**d.ptr let ppld: &AtomicRefCell<PartialPersistentLayoutData> = &**d.ptr;
let psd: &AtomicRefCell<PersistentStyleData> = transmute(ppld);
psd
}) })
} }
} }
@ -331,6 +323,14 @@ impl<'ln> LayoutNode for ServoLayoutNode<'ln> {
} }
impl<'ln> ServoLayoutNode<'ln> { impl<'ln> ServoLayoutNode<'ln> {
fn get_partial_layout_data(&self) -> Option<&AtomicRefCell<PartialPersistentLayoutData>> {
unsafe {
self.get_jsmanaged().get_style_and_layout_data().map(|d| {
&**d.ptr
})
}
}
fn dump_indent(self, indent: u32) { fn dump_indent(self, indent: u32) {
let mut s = String::new(); let mut s = String::new();
for _ in 0..indent { for _ in 0..indent {
@ -871,7 +871,7 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
} }
} }
fn get_style_data(&self) -> Option<&RefCell<PartialStyleAndLayoutData>> { fn get_style_data(&self) -> Option<&AtomicRefCell<PersistentStyleData>> {
self.node.get_style_data() self.node.get_style_data()
} }
} }

View file

@ -52,11 +52,11 @@ use core::nonzero::NonZero;
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
use libc::c_void; use libc::c_void;
use restyle_damage::RestyleDamage; use restyle_damage::RestyleDamage;
use style::data::PrivateStyleData; use style::atomic_refcell::AtomicRefCell;
use style::refcell::RefCell; use style::data::PersistentStyleData;
pub struct PartialStyleAndLayoutData { pub struct PartialPersistentLayoutData {
pub style_data: PrivateStyleData, pub style_data: PersistentStyleData,
pub restyle_damage: RestyleDamage, pub restyle_damage: RestyleDamage,
} }
@ -64,7 +64,7 @@ pub struct PartialStyleAndLayoutData {
pub struct OpaqueStyleAndLayoutData { pub struct OpaqueStyleAndLayoutData {
#[ignore_heap_size_of = "TODO(#6910) Box value that should be counted but \ #[ignore_heap_size_of = "TODO(#6910) Box value that should be counted but \
the type lives in layout"] the type lives in layout"]
pub ptr: NonZero<*mut RefCell<PartialStyleAndLayoutData>> pub ptr: NonZero<*mut AtomicRefCell<PartialPersistentLayoutData>>
} }
#[allow(unsafe_code)] #[allow(unsafe_code)]

View file

@ -5,7 +5,6 @@
use HTMLCanvasData; use HTMLCanvasData;
use LayoutNodeType; use LayoutNodeType;
use OpaqueStyleAndLayoutData; use OpaqueStyleAndLayoutData;
use PartialStyleAndLayoutData;
use gfx_traits::{ByteIndex, LayerId, LayerType}; use gfx_traits::{ByteIndex, LayerId, LayerType};
use msg::constellation_msg::PipelineId; use msg::constellation_msg::PipelineId;
use range::Range; use range::Range;
@ -13,12 +12,13 @@ use restyle_damage::RestyleDamage;
use std::fmt::Debug; use std::fmt::Debug;
use std::sync::Arc; use std::sync::Arc;
use string_cache::{Atom, Namespace}; use string_cache::{Atom, Namespace};
use style::atomic_refcell::AtomicRefCell;
use style::computed_values::display; use style::computed_values::display;
use style::context::SharedStyleContext; use style::context::SharedStyleContext;
use style::data::PersistentStyleData;
use style::dom::{LayoutIterator, NodeInfo, PresentationalHintsSynthetizer, TNode}; use style::dom::{LayoutIterator, NodeInfo, PresentationalHintsSynthetizer, TNode};
use style::dom::OpaqueNode; use style::dom::OpaqueNode;
use style::properties::ServoComputedValues; use style::properties::ServoComputedValues;
use style::refcell::{Ref, RefCell};
use style::selector_impl::{PseudoElement, PseudoElementCascadeType, ServoSelectorImpl}; use style::selector_impl::{PseudoElement, PseudoElementCascadeType, ServoSelectorImpl};
use url::Url; use url::Url;
@ -76,7 +76,7 @@ pub trait LayoutNode: TNode {
/// Returns the type ID of this node. /// Returns the type ID of this node.
fn type_id(&self) -> LayoutNodeType; fn type_id(&self) -> LayoutNodeType;
fn get_style_data(&self) -> Option<&RefCell<PartialStyleAndLayoutData>>; fn get_style_data(&self) -> Option<&AtomicRefCell<PersistentStyleData>>;
fn init_style_and_layout_data(&self, data: OpaqueStyleAndLayoutData); fn init_style_and_layout_data(&self, data: OpaqueStyleAndLayoutData);
fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData>; fn get_style_and_layout_data(&self) -> Option<OpaqueStyleAndLayoutData>;
@ -183,7 +183,6 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized {
if self.get_style_data() if self.get_style_data()
.unwrap() .unwrap()
.borrow() .borrow()
.style_data
.per_pseudo .per_pseudo
.contains_key(&PseudoElement::Before) { .contains_key(&PseudoElement::Before) {
Some(self.with_pseudo(PseudoElementType::Before(None))) Some(self.with_pseudo(PseudoElementType::Before(None)))
@ -197,7 +196,6 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized {
if self.get_style_data() if self.get_style_data()
.unwrap() .unwrap()
.borrow() .borrow()
.style_data
.per_pseudo .per_pseudo
.contains_key(&PseudoElement::After) { .contains_key(&PseudoElement::After) {
Some(self.with_pseudo(PseudoElementType::After(None))) Some(self.with_pseudo(PseudoElementType::After(None)))
@ -240,12 +238,11 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized {
/// ///
/// Unlike the version on TNode, this handles pseudo-elements. /// Unlike the version on TNode, this handles pseudo-elements.
#[inline] #[inline]
fn style(&self, context: &SharedStyleContext) -> Ref<Arc<ServoComputedValues>> { fn style(&self, context: &SharedStyleContext) -> Arc<ServoComputedValues> {
match self.get_pseudo_element_type() { match self.get_pseudo_element_type() {
PseudoElementType::Normal => { PseudoElementType::Normal => {
Ref::map(self.get_style_data().unwrap().borrow(), |data| { self.get_style_data().unwrap().borrow()
data.style_data.style.as_ref().unwrap() .style.as_ref().unwrap().clone()
})
}, },
other => { other => {
// Precompute non-eagerly-cascaded pseudo-element styles if not // Precompute non-eagerly-cascaded pseudo-element styles if not
@ -258,14 +255,13 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized {
if !self.get_style_data() if !self.get_style_data()
.unwrap() .unwrap()
.borrow() .borrow()
.style_data
.per_pseudo.contains_key(&style_pseudo) { .per_pseudo.contains_key(&style_pseudo) {
let mut data = self.get_style_data().unwrap().borrow_mut(); let mut data = self.get_style_data().unwrap().borrow_mut();
let new_style = let new_style =
context.stylist context.stylist
.precomputed_values_for_pseudo(&style_pseudo, .precomputed_values_for_pseudo(&style_pseudo,
data.style_data.style.as_ref()); data.style.as_ref());
data.style_data.per_pseudo data.per_pseudo
.insert(style_pseudo.clone(), new_style.unwrap()); .insert(style_pseudo.clone(), new_style.unwrap());
} }
} }
@ -274,7 +270,6 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized {
if !self.get_style_data() if !self.get_style_data()
.unwrap() .unwrap()
.borrow() .borrow()
.style_data
.per_pseudo.contains_key(&style_pseudo) { .per_pseudo.contains_key(&style_pseudo) {
let mut data = self.get_style_data().unwrap().borrow_mut(); let mut data = self.get_style_data().unwrap().borrow_mut();
let new_style = let new_style =
@ -282,16 +277,16 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized {
.lazily_compute_pseudo_element_style( .lazily_compute_pseudo_element_style(
&self.as_element(), &self.as_element(),
&style_pseudo, &style_pseudo,
data.style_data.style.as_ref().unwrap()); data.style.as_ref().unwrap());
data.style_data.per_pseudo data.per_pseudo
.insert(style_pseudo.clone(), new_style.unwrap()); .insert(style_pseudo.clone(), new_style.unwrap());
} }
} }
} }
Ref::map(self.get_style_data().unwrap().borrow(), |data| { self.get_style_data().unwrap().borrow()
data.style_data.per_pseudo.get(&style_pseudo).unwrap() .per_pseudo.get(&style_pseudo)
}) .unwrap().clone()
} }
} }
} }
@ -304,24 +299,22 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized {
/// This should be used just for querying layout, or when we know the /// This should be used just for querying layout, or when we know the
/// element style is precomputed, not from general layout itself. /// element style is precomputed, not from general layout itself.
#[inline] #[inline]
fn resolved_style(&self) -> Ref<Arc<ServoComputedValues>> { fn resolved_style(&self) -> Arc<ServoComputedValues> {
Ref::map(self.get_style_data().unwrap().borrow(), |data| { let data = self.get_style_data().unwrap().borrow();
match self.get_pseudo_element_type() { match self.get_pseudo_element_type() {
PseudoElementType::Normal PseudoElementType::Normal
=> data.style_data.style.as_ref().unwrap(), => data.style.as_ref().unwrap().clone(),
other other
=> data.style_data.per_pseudo.get(&other.style_pseudo_element()).unwrap(), => data.per_pseudo.get(&other.style_pseudo_element()).unwrap().clone(),
} }
})
} }
#[inline] #[inline]
fn selected_style(&self, _context: &SharedStyleContext) -> Ref<Arc<ServoComputedValues>> { fn selected_style(&self, _context: &SharedStyleContext) -> Arc<ServoComputedValues> {
Ref::map(self.get_style_data().unwrap().borrow(), |data| { let data = self.get_style_data().unwrap().borrow();
data.style_data.per_pseudo data.per_pseudo
.get(&PseudoElement::Selection) .get(&PseudoElement::Selection)
.unwrap_or(data.style_data.style.as_ref().unwrap()) .unwrap_or(data.style.as_ref().unwrap()).clone()
})
} }
/// Removes the style from this node. /// Removes the style from this node.
@ -332,10 +325,10 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized {
match self.get_pseudo_element_type() { match self.get_pseudo_element_type() {
PseudoElementType::Normal => { PseudoElementType::Normal => {
data.style_data.style = None; data.style = None;
} }
other => { other => {
data.style_data.per_pseudo.remove(&other.style_pseudo_element()); data.per_pseudo.remove(&other.style_pseudo_element());
} }
}; };
} }
@ -390,7 +383,7 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized {
LayerId::new_of_type(LayerType::OverflowScroll, self.opaque().id() as usize) LayerId::new_of_type(LayerType::OverflowScroll, self.opaque().id() as usize)
} }
fn get_style_data(&self) -> Option<&RefCell<PartialStyleAndLayoutData>>; fn get_style_data(&self) -> Option<&AtomicRefCell<PersistentStyleData>>;
} }
// This trait is only public so that it can be implemented by the gecko wrapper. // This trait is only public so that it can be implemented by the gecko wrapper.

View file

@ -1728,6 +1728,32 @@ dependencies = [
"shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "owning_ref"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "parking_lot"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"owning_ref 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot_core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "parking_lot_core"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "phf" name = "phf"
version = "0.7.16" version = "0.7.16"
@ -2312,6 +2338,7 @@ dependencies = [
"num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1", "plugins 0.0.1",
"quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2937,6 +2964,9 @@ dependencies = [
"checksum osmesa-src 12.0.1 (git+https://github.com/servo/osmesa-src)" = "<none>" "checksum osmesa-src 12.0.1 (git+https://github.com/servo/osmesa-src)" = "<none>"
"checksum osmesa-sys 0.1.2 (git+https://github.com/daggerbot/osmesa-rs)" = "<none>" "checksum osmesa-sys 0.1.2 (git+https://github.com/daggerbot/osmesa-rs)" = "<none>"
"checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b" "checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b"
"checksum owning_ref 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88084505837507cbec6a9f39b5d3b985db3c84e9a741c80200b619001283293d"
"checksum parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3562f3de7bdff194212be82366abf5c6565aff8a433b71c53c63d0e7c9913878"
"checksum parking_lot_core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "06f24c980718110494e9cfb7db7438895c3f54505101bb6170329d5e43a53f64"
"checksum phf 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)" = "52c875926de24c01b5b69153eaa258b57920a39b44bbce8ef1f2052a6c5a6a1a" "checksum phf 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)" = "52c875926de24c01b5b69153eaa258b57920a39b44bbce8ef1f2052a6c5a6a1a"
"checksum phf_codegen 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)" = "0a8912c2cc0ea2e8ae70388ec0af9a445e7ab37b3c9cc61f059c2b34db8ed50b" "checksum phf_codegen 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)" = "0a8912c2cc0ea2e8ae70388ec0af9a445e7ab37b3c9cc61f059c2b34db8ed50b"
"checksum phf_generator 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)" = "04b5ea825e28cb6efd89d9133b129b2003b45a221aeda025509b125b00ecb7c4" "checksum phf_generator 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)" = "04b5ea825e28cb6efd89d9133b129b2003b45a221aeda025509b125b00ecb7c4"

View file

@ -39,6 +39,7 @@ num-integer = "0.1.32"
num-traits = "0.1.32" num-traits = "0.1.32"
num_cpus = "0.2.2" num_cpus = "0.2.2"
ordered-float = "0.2.2" ordered-float = "0.2.2"
parking_lot = "0.3.3"
quickersort = "2.0.0" quickersort = "2.0.0"
rand = "0.3" rand = "0.3"
rustc-serialize = "0.3" rustc-serialize = "0.3"

View file

@ -0,0 +1,41 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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 parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard};
/// Container type providing RefCell-like semantics for objects shared across
/// threads.
///
/// RwLock is traditionally considered to be the |Sync| analogue of RefCell.
/// However, for consumers that can guarantee that they will never mutably
/// borrow the contents concurrently with immutable borrows, an RwLock feels
/// like overkill.
///
/// The RwLock in the standard library is indeed heavyweight, since it heap-
/// allocates an OS-specific primitive and delegates operations to it. However,
/// parking_lot provides a pure-rust implementation of the standard
/// synchronization primitives, with uncontended borrows compiling down to a
/// single atomic operation. This is exactly how we would build an atomic
/// RefCell, so we newtype it with some API sugar.
pub struct AtomicRefCell<T>(RwLock<T>);
pub type AtomicRef<'a, T> = RwLockReadGuard<'a, T>;
pub type AtomicRefMut<'a, T> = RwLockWriteGuard<'a, T>;
impl<T> AtomicRefCell<T> {
pub fn new(value: T) -> Self {
AtomicRefCell(RwLock::new(value))
}
pub fn borrow(&self) -> AtomicRef<T> {
self.0.try_read().unwrap()
}
pub fn borrow_mut(&self) -> AtomicRefMut<T> {
self.0.try_write().unwrap()
}
}
impl<T: Default> Default for AtomicRefCell<T> {
fn default() -> Self {
Self::new(T::default())
}
}

View file

@ -11,7 +11,7 @@ use std::hash::BuildHasherDefault;
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::AtomicIsize; use std::sync::atomic::AtomicIsize;
pub struct PrivateStyleData { pub struct PersistentStyleData {
/// The results of CSS styling for this node. /// The results of CSS styling for this node.
pub style: Option<Arc<ComputedValues>>, pub style: Option<Arc<ComputedValues>>,
@ -23,9 +23,9 @@ pub struct PrivateStyleData {
pub parallel: DomParallelInfo, pub parallel: DomParallelInfo,
} }
impl PrivateStyleData { impl PersistentStyleData {
pub fn new() -> Self { pub fn new() -> Self {
PrivateStyleData { PersistentStyleData {
style: None, style: None,
per_pseudo: HashMap::with_hasher(Default::default()), per_pseudo: HashMap::with_hasher(Default::default()),
parallel: DomParallelInfo::new(), parallel: DomParallelInfo::new(),

View file

@ -6,11 +6,10 @@
#![allow(unsafe_code)] #![allow(unsafe_code)]
use context::SharedStyleContext; use atomic_refcell::{AtomicRef, AtomicRefMut};
use data::PrivateStyleData; use data::PersistentStyleData;
use element_state::ElementState; use element_state::ElementState;
use properties::{ComputedValues, PropertyDeclarationBlock}; use properties::{ComputedValues, PropertyDeclarationBlock};
use refcell::{Ref, RefMut};
use restyle_hints::{RESTYLE_DESCENDANTS, RESTYLE_LATER_SIBLINGS, RESTYLE_SELF, RestyleHint}; use restyle_hints::{RESTYLE_DESCENDANTS, RESTYLE_LATER_SIBLINGS, RESTYLE_SELF, RestyleHint};
use selector_impl::{ElementExt, PseudoElement}; use selector_impl::{ElementExt, PseudoElement};
use selector_matching::ApplicableDeclarationBlock; use selector_matching::ApplicableDeclarationBlock;
@ -139,17 +138,13 @@ pub trait TNode : Sized + Copy + Clone + NodeInfo {
unsafe fn set_can_be_fragmented(&self, value: bool); unsafe fn set_can_be_fragmented(&self, value: bool);
/// Borrows the PrivateStyleData without checks. /// Borrows the style data immutably. Fails on a conflicting borrow.
#[inline(always)] #[inline(always)]
unsafe fn borrow_data_unchecked(&self) -> Option<*const PrivateStyleData>; fn borrow_data(&self) -> Option<AtomicRef<PersistentStyleData>>;
/// Borrows the PrivateStyleData immutably. Fails on a conflicting borrow. /// Borrows the style data mutably. Fails on a conflicting borrow.
#[inline(always)] #[inline(always)]
fn borrow_data(&self) -> Option<Ref<PrivateStyleData>>; fn mutate_data(&self) -> Option<AtomicRefMut<PersistentStyleData>>;
/// Borrows the PrivateStyleData mutably. Fails on a conflicting borrow.
#[inline(always)]
fn mutate_data(&self) -> Option<RefMut<PrivateStyleData>>;
/// Get the description of how to account for recent style changes. /// Get the description of how to account for recent style changes.
fn restyle_damage(self) -> Self::ConcreteRestyleDamage; fn restyle_damage(self) -> Self::ConcreteRestyleDamage;
@ -167,13 +162,6 @@ pub trait TNode : Sized + Copy + Clone + NodeInfo {
fn next_sibling(&self) -> Option<Self>; fn next_sibling(&self) -> Option<Self>;
/// Returns the style results for the given node. If CSS selector matching
/// has not yet been performed, fails.
fn style(&self, _context: &SharedStyleContext) -> Ref<Arc<ComputedValues>> {
Ref::map(self.borrow_data().unwrap(), |data| data.style.as_ref().unwrap())
}
/// Removes the style from this node. /// Removes the style from this node.
fn unstyle(self) { fn unstyle(self) {
self.mutate_data().unwrap().style = None; self.mutate_data().unwrap().style = None;

View file

@ -5,7 +5,8 @@
#![allow(unsafe_code)] #![allow(unsafe_code)]
use data::PrivateStyleData; use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
use data::PersistentStyleData;
use dom::{LayoutIterator, NodeInfo, TDocument, TElement, TNode, TRestyleDamage, UnsafeNode}; use dom::{LayoutIterator, NodeInfo, TDocument, TElement, TNode, TRestyleDamage, UnsafeNode};
use dom::{OpaqueNode, PresentationalHintsSynthetizer}; use dom::{OpaqueNode, PresentationalHintsSynthetizer};
use element_state::ElementState; use element_state::ElementState;
@ -34,7 +35,6 @@ use libc::uintptr_t;
use parser::ParserContextExtraData; use parser::ParserContextExtraData;
use properties::{ComputedValues, parse_style_attribute}; use properties::{ComputedValues, parse_style_attribute};
use properties::PropertyDeclarationBlock; use properties::PropertyDeclarationBlock;
use refcell::{Ref, RefCell, RefMut};
use selector_impl::ElementExt; use selector_impl::ElementExt;
use selector_matching::ApplicableDeclarationBlock; use selector_matching::ApplicableDeclarationBlock;
use selectors::Element; use selectors::Element;
@ -48,11 +48,11 @@ use std::sync::atomic::{AtomicBool, AtomicPtr};
use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace}; use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace};
use url::Url; use url::Url;
pub struct NonOpaqueStyleData(RefCell<PrivateStyleData>); pub struct NonOpaqueStyleData(AtomicRefCell<PersistentStyleData>);
impl NonOpaqueStyleData { impl NonOpaqueStyleData {
pub fn new() -> Self { pub fn new() -> Self {
NonOpaqueStyleData(RefCell::new(PrivateStyleData::new())) NonOpaqueStyleData(AtomicRefCell::new(PersistentStyleData::new()))
} }
} }
@ -302,18 +302,12 @@ impl<'ln> TNode for GeckoNode<'ln> {
} }
#[inline(always)] #[inline(always)]
unsafe fn borrow_data_unchecked(&self) -> Option<*const PrivateStyleData> { fn borrow_data(&self) -> Option<AtomicRef<PersistentStyleData>> {
self.get_node_data().as_ref().map(|d| d.0.as_unsafe_cell().get()
as *const PrivateStyleData)
}
#[inline(always)]
fn borrow_data(&self) -> Option<Ref<PrivateStyleData>> {
self.get_node_data().as_ref().map(|d| d.0.borrow()) self.get_node_data().as_ref().map(|d| d.0.borrow())
} }
#[inline(always)] #[inline(always)]
fn mutate_data(&self) -> Option<RefMut<PrivateStyleData>> { fn mutate_data(&self) -> Option<AtomicRefMut<PersistentStyleData>> {
self.get_node_data().as_ref().map(|d| d.0.borrow_mut()) self.get_node_data().as_ref().map(|d| d.0.borrow_mut())
} }

View file

@ -61,6 +61,7 @@ extern crate num_integer;
extern crate num_traits; extern crate num_traits;
#[cfg(feature = "gecko")] extern crate num_cpus; #[cfg(feature = "gecko")] extern crate num_cpus;
extern crate ordered_float; extern crate ordered_float;
extern crate parking_lot;
extern crate quickersort; extern crate quickersort;
extern crate rand; extern crate rand;
extern crate rustc_serialize; extern crate rustc_serialize;
@ -80,6 +81,7 @@ extern crate util;
#[macro_use] pub mod string_cache; #[macro_use] pub mod string_cache;
pub mod animation; pub mod animation;
pub mod atomic_refcell;
pub mod attr; pub mod attr;
pub mod bezier; pub mod bezier;
pub mod cache; pub mod cache;

View file

@ -11,7 +11,7 @@ use arc_ptr_eq;
use cache::{LRUCache, SimpleHashCache}; use cache::{LRUCache, SimpleHashCache};
use cascade_info::CascadeInfo; use cascade_info::CascadeInfo;
use context::{SharedStyleContext, StyleContext}; use context::{SharedStyleContext, StyleContext};
use data::PrivateStyleData; use data::PersistentStyleData;
use dom::{NodeInfo, TElement, TNode, TRestyleDamage, UnsafeNode}; use dom::{NodeInfo, TElement, TNode, TRestyleDamage, UnsafeNode};
use properties::{ComputedValues, PropertyDeclarationBlock, cascade}; use properties::{ComputedValues, PropertyDeclarationBlock, cascade};
use properties::longhands::display::computed_value as display; use properties::longhands::display::computed_value as display;
@ -874,19 +874,9 @@ pub trait MatchMethods : TNode {
-> RestyleResult -> RestyleResult
where Ctx: StyleContext<'a> where Ctx: StyleContext<'a>
{ {
// Get our parent's style. This must be unsafe so that we don't touch the parent's // Get our parent's style.
// borrow flags. let parent_node_data = parent.as_ref().and_then(|x| x.borrow_data());
// let parent_style = parent_node_data.as_ref().map(|x| x.style.as_ref().unwrap());
// FIXME(pcwalton): Isolate this unsafety into the `wrapper` module to allow
// enforced safe, race-free access to the parent style.
let parent_style = match parent {
Some(parent_node) => {
let parent_style = (*parent_node.borrow_data_unchecked().unwrap()).style.as_ref().unwrap();
Some(parent_style)
}
None => None,
};
// In the case we're styling a text node, we don't need to compute the // In the case we're styling a text node, we don't need to compute the
// restyle damage, since it's a subset of the restyle damage of the // restyle damage, since it's a subset of the restyle damage of the
@ -945,7 +935,7 @@ pub trait MatchMethods : TNode {
fn compute_damage_and_cascade_pseudos<'a, Ctx>(&self, fn compute_damage_and_cascade_pseudos<'a, Ctx>(&self,
final_style: Arc<ComputedValues>, final_style: Arc<ComputedValues>,
data: &mut PrivateStyleData, data: &mut PersistentStyleData,
context: &Ctx, context: &Ctx,
applicable_declarations: &ApplicableDeclarations, applicable_declarations: &ApplicableDeclarations,
mut applicable_declarations_cache: &mut ApplicableDeclarationsCache) mut applicable_declarations_cache: &mut ApplicableDeclarationsCache)

View file

@ -161,9 +161,7 @@ fn bottom_up_dom<N, C>(root: OpaqueNode,
Some(parent) => parent, Some(parent) => parent,
}; };
let parent_data = unsafe { let parent_data = parent.borrow_data().unwrap();
&*parent.borrow_data_unchecked().unwrap()
};
if parent_data if parent_data
.parallel .parallel

30
ports/cef/Cargo.lock generated
View file

@ -1599,6 +1599,32 @@ dependencies = [
"shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "owning_ref"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "parking_lot"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"owning_ref 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot_core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "parking_lot_core"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "phf" name = "phf"
version = "0.7.16" version = "0.7.16"
@ -2195,6 +2221,7 @@ dependencies = [
"num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1", "plugins 0.0.1",
"quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2791,6 +2818,9 @@ dependencies = [
"checksum osmesa-src 12.0.1 (git+https://github.com/servo/osmesa-src)" = "<none>" "checksum osmesa-src 12.0.1 (git+https://github.com/servo/osmesa-src)" = "<none>"
"checksum osmesa-sys 0.1.2 (git+https://github.com/daggerbot/osmesa-rs)" = "<none>" "checksum osmesa-sys 0.1.2 (git+https://github.com/daggerbot/osmesa-rs)" = "<none>"
"checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b" "checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b"
"checksum owning_ref 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88084505837507cbec6a9f39b5d3b985db3c84e9a741c80200b619001283293d"
"checksum parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3562f3de7bdff194212be82366abf5c6565aff8a433b71c53c63d0e7c9913878"
"checksum parking_lot_core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "06f24c980718110494e9cfb7db7438895c3f54505101bb6170329d5e43a53f64"
"checksum phf 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)" = "52c875926de24c01b5b69153eaa258b57920a39b44bbce8ef1f2052a6c5a6a1a" "checksum phf 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)" = "52c875926de24c01b5b69153eaa258b57920a39b44bbce8ef1f2052a6c5a6a1a"
"checksum phf_codegen 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)" = "0a8912c2cc0ea2e8ae70388ec0af9a445e7ab37b3c9cc61f059c2b34db8ed50b" "checksum phf_codegen 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)" = "0a8912c2cc0ea2e8ae70388ec0af9a445e7ab37b3c9cc61f059c2b34db8ed50b"
"checksum phf_generator 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)" = "04b5ea825e28cb6efd89d9133b129b2003b45a221aeda025509b125b00ecb7c4" "checksum phf_generator 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)" = "04b5ea825e28cb6efd89d9133b129b2003b45a221aeda025509b125b00ecb7c4"

View file

@ -244,6 +244,32 @@ dependencies = [
"unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "owning_ref"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "parking_lot"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"owning_ref 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot_core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "parking_lot_core"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "phf_generator" name = "phf_generator"
version = "0.7.16" version = "0.7.16"
@ -353,6 +379,7 @@ dependencies = [
"num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
@ -524,6 +551,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "8359ea48994f253fa958b5b90b013728b06f54872e5a58bce39540fcdd0f2527" "checksum num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "8359ea48994f253fa958b5b90b013728b06f54872e5a58bce39540fcdd0f2527"
"checksum num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "cee7e88156f3f9e19bdd598f8d6c9db7bf4078f99f8381f43a55b09648d1a6e3" "checksum num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "cee7e88156f3f9e19bdd598f8d6c9db7bf4078f99f8381f43a55b09648d1a6e3"
"checksum ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cc511538298611a79d5a4ddfbb75315b866d942ed26a00bdc3590795c68b7279" "checksum ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cc511538298611a79d5a4ddfbb75315b866d942ed26a00bdc3590795c68b7279"
"checksum owning_ref 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88084505837507cbec6a9f39b5d3b985db3c84e9a741c80200b619001283293d"
"checksum parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3562f3de7bdff194212be82366abf5c6565aff8a433b71c53c63d0e7c9913878"
"checksum parking_lot_core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "06f24c980718110494e9cfb7db7438895c3f54505101bb6170329d5e43a53f64"
"checksum phf_generator 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)" = "04b5ea825e28cb6efd89d9133b129b2003b45a221aeda025509b125b00ecb7c4" "checksum phf_generator 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)" = "04b5ea825e28cb6efd89d9133b129b2003b45a221aeda025509b125b00ecb7c4"
"checksum phf_shared 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2c43b5dbe94d31f1f4ed45c50bb06d70e72fd53f15422b0a915b5c237e130dd6" "checksum phf_shared 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2c43b5dbe94d31f1f4ed45c50bb06d70e72fd53f15422b0a915b5c237e130dd6"
"checksum quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e952ea7699262481636004bc4ab8afaccf2bc13f91b79d1aee6617bd8fc39651" "checksum quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e952ea7699262481636004bc4ab8afaccf2bc13f91b79d1aee6617bd8fc39651"