mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Make OpaqueLayoutAndStyleData just a bit less opaque
It now stores a NonNull<dyn Any>.
This commit is contained in:
parent
e47e884cc7
commit
4c61baee30
11 changed files with 83 additions and 65 deletions
|
@ -8,8 +8,7 @@ use script_layout_interface::StyleData;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct StyleAndLayoutData {
|
pub struct StyleAndLayoutData {
|
||||||
/// Data accessed by script_layout_interface. This must be first to allow
|
/// The style data associated with a node.
|
||||||
/// casting between StyleAndLayoutData and StyleData.
|
|
||||||
pub style_data: StyleData,
|
pub style_data: StyleData,
|
||||||
/// The layout data associated with a node.
|
/// The layout data associated with a node.
|
||||||
pub layout_data: AtomicRefCell<LayoutData>,
|
pub layout_data: AtomicRefCell<LayoutData>,
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
use crate::construct::ConstructionResult;
|
use crate::construct::ConstructionResult;
|
||||||
use crate::context::LayoutContext;
|
use crate::context::LayoutContext;
|
||||||
|
use crate::data::StyleAndLayoutData;
|
||||||
use crate::display_list::items::{DisplayList, OpaqueNode, ScrollOffsetMap};
|
use crate::display_list::items::{DisplayList, OpaqueNode, ScrollOffsetMap};
|
||||||
use crate::display_list::IndexableText;
|
use crate::display_list::IndexableText;
|
||||||
use crate::flow::{Flow, GetBaseFlow};
|
use crate::flow::{Flow, GetBaseFlow};
|
||||||
|
@ -26,7 +27,6 @@ use script_layout_interface::rpc::{OffsetParentResponse, ResolvedStyleResponse,
|
||||||
use script_layout_interface::wrapper_traits::{
|
use script_layout_interface::wrapper_traits::{
|
||||||
LayoutNode, ThreadSafeLayoutElement, ThreadSafeLayoutNode,
|
LayoutNode, ThreadSafeLayoutElement, ThreadSafeLayoutNode,
|
||||||
};
|
};
|
||||||
use script_layout_interface::StyleData;
|
|
||||||
use script_layout_interface::{LayoutElementType, LayoutNodeType};
|
use script_layout_interface::{LayoutElementType, LayoutNodeType};
|
||||||
use script_traits::LayoutMsg as ConstellationMsg;
|
use script_traits::LayoutMsg as ConstellationMsg;
|
||||||
use script_traits::UntrustedNodeAddress;
|
use script_traits::UntrustedNodeAddress;
|
||||||
|
@ -1037,8 +1037,13 @@ fn inner_text_collection_steps<'dom>(
|
||||||
};
|
};
|
||||||
|
|
||||||
let element_data = unsafe {
|
let element_data = unsafe {
|
||||||
node.get_style_and_layout_data()
|
&node.get_style_and_layout_data().as_ref().map(|opaque| {
|
||||||
.map(|d| &(*(d.ptr.as_ptr() as *mut StyleData)).element_data)
|
&opaque
|
||||||
|
.downcast_ref::<StyleAndLayoutData>()
|
||||||
|
.unwrap()
|
||||||
|
.style_data
|
||||||
|
.element_data
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
if element_data.is_none() {
|
if element_data.is_none() {
|
||||||
|
|
|
@ -73,7 +73,7 @@ where
|
||||||
// flow construction:
|
// flow construction:
|
||||||
// (1) They child doesn't yet have layout data (preorder traversal initializes it).
|
// (1) They child doesn't yet have layout data (preorder traversal initializes it).
|
||||||
// (2) The parent element has restyle damage (so the text flow also needs fixup).
|
// (2) The parent element has restyle damage (so the text flow also needs fixup).
|
||||||
node.get_raw_data().is_none() || !parent_data.damage.is_empty()
|
(unsafe { node.get_raw_data().is_none() }) || !parent_data.damage.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shared_context(&self) -> &SharedStyleContext {
|
fn shared_context(&self) -> &SharedStyleContext {
|
||||||
|
|
|
@ -52,11 +52,11 @@ where
|
||||||
T: GetLayoutData<'dom>,
|
T: GetLayoutData<'dom>,
|
||||||
{
|
{
|
||||||
fn borrow_layout_data(&self) -> Option<AtomicRef<LayoutData>> {
|
fn borrow_layout_data(&self) -> Option<AtomicRef<LayoutData>> {
|
||||||
self.get_raw_data().map(|d| d.layout_data.borrow())
|
unsafe { self.get_raw_data().map(|d| d.layout_data.borrow()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mutate_layout_data(&self) -> Option<AtomicRefMut<LayoutData>> {
|
fn mutate_layout_data(&self) -> Option<AtomicRefMut<LayoutData>> {
|
||||||
self.get_raw_data().map(|d| d.layout_data.borrow_mut())
|
unsafe { self.get_raw_data().map(|d| d.layout_data.borrow_mut()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flow_debug_id(self) -> usize {
|
fn flow_debug_id(self) -> usize {
|
||||||
|
@ -66,18 +66,16 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GetRawData {
|
pub trait GetRawData {
|
||||||
fn get_raw_data(&self) -> Option<&StyleAndLayoutData>;
|
unsafe fn get_raw_data(&self) -> Option<&StyleAndLayoutData>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom, T> GetRawData for T
|
impl<'dom, T> GetRawData for T
|
||||||
where
|
where
|
||||||
T: GetLayoutData<'dom>,
|
T: GetLayoutData<'dom>,
|
||||||
{
|
{
|
||||||
fn get_raw_data(&self) -> Option<&StyleAndLayoutData> {
|
unsafe fn get_raw_data(&self) -> Option<&StyleAndLayoutData> {
|
||||||
self.get_style_and_layout_data().map(|opaque| {
|
self.get_style_and_layout_data()
|
||||||
let container = opaque.ptr.as_ptr() as *mut StyleAndLayoutData;
|
.map(|opaque| opaque.downcast_ref().unwrap())
|
||||||
unsafe { &*container }
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +144,7 @@ where
|
||||||
debug_assert!(node.is_element());
|
debug_assert!(node.is_element());
|
||||||
}
|
}
|
||||||
|
|
||||||
let damage = {
|
let damage = unsafe {
|
||||||
let data = node.get_raw_data().unwrap();
|
let data = node.get_raw_data().unwrap();
|
||||||
|
|
||||||
if !data
|
if !data
|
||||||
|
|
|
@ -446,10 +446,13 @@ where
|
||||||
self.opaque()
|
self.opaque()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
fn layout_data_mut(&self) -> AtomicRefMut<LayoutDataForElement> {
|
fn layout_data_mut(&self) -> AtomicRefMut<LayoutDataForElement> {
|
||||||
self.get_raw_data()
|
unsafe {
|
||||||
.map(|d| d.layout_data.borrow_mut())
|
self.get_raw_data()
|
||||||
.unwrap()
|
.map(|d| d.layout_data.borrow_mut())
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn element_box_slot(&self) -> BoxSlot<'dom> {
|
fn element_box_slot(&self) -> BoxSlot<'dom> {
|
||||||
|
|
|
@ -63,7 +63,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn text_node_needs_traversal(node: E::ConcreteNode, parent_data: &ElementData) -> bool {
|
fn text_node_needs_traversal(node: E::ConcreteNode, parent_data: &ElementData) -> bool {
|
||||||
node.get_raw_data().is_none() || !parent_data.damage.is_empty()
|
(unsafe { node.get_raw_data().is_none() }) || !parent_data.damage.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shared_context(&self) -> &SharedStyleContext {
|
fn shared_context(&self) -> &SharedStyleContext {
|
||||||
|
|
|
@ -8,17 +8,15 @@ use crate::data::StyleAndLayoutData;
|
||||||
use script_layout_interface::wrapper_traits::GetLayoutData;
|
use script_layout_interface::wrapper_traits::GetLayoutData;
|
||||||
|
|
||||||
pub trait GetRawData {
|
pub trait GetRawData {
|
||||||
fn get_raw_data(&self) -> Option<&StyleAndLayoutData>;
|
unsafe fn get_raw_data(&self) -> Option<&StyleAndLayoutData>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom, T> GetRawData for T
|
impl<'dom, T> GetRawData for T
|
||||||
where
|
where
|
||||||
T: GetLayoutData<'dom>,
|
T: GetLayoutData<'dom>,
|
||||||
{
|
{
|
||||||
fn get_raw_data(&self) -> Option<&StyleAndLayoutData> {
|
unsafe fn get_raw_data(&self) -> Option<&StyleAndLayoutData> {
|
||||||
self.get_style_and_layout_data().map(|opaque| {
|
self.get_style_and_layout_data()
|
||||||
let container = opaque.ptr.as_ptr() as *mut StyleAndLayoutData;
|
.map(|opaque| opaque.downcast_ref().unwrap())
|
||||||
unsafe { &*container }
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,6 @@ use std::borrow::Cow;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::ptr::NonNull;
|
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::Arc as StdArc;
|
use std::sync::Arc as StdArc;
|
||||||
use style::applicable_declarations::ApplicableDeclarationBlock;
|
use style::applicable_declarations::ApplicableDeclarationBlock;
|
||||||
|
@ -93,9 +92,7 @@ use style::stylist::CascadeData;
|
||||||
use style::CaseSensitivityExt;
|
use style::CaseSensitivityExt;
|
||||||
|
|
||||||
pub unsafe fn drop_style_and_layout_data(data: OpaqueStyleAndLayoutData) {
|
pub unsafe fn drop_style_and_layout_data(data: OpaqueStyleAndLayoutData) {
|
||||||
let ptr = data.ptr.as_ptr() as *mut StyleData;
|
drop(Box::from_raw(data.as_ptr()));
|
||||||
let non_opaque: *mut StyleAndLayoutData = ptr as *mut _;
|
|
||||||
let _ = Box::from_raw(non_opaque);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
@ -276,10 +273,7 @@ impl<'ln> LayoutNode<'ln> for ServoLayoutNode<'ln> {
|
||||||
|
|
||||||
unsafe fn initialize_data(&self) {
|
unsafe fn initialize_data(&self) {
|
||||||
if self.get_raw_data().is_none() {
|
if self.get_raw_data().is_none() {
|
||||||
let ptr: *mut StyleAndLayoutData = Box::into_raw(Box::new(StyleAndLayoutData::new()));
|
let opaque = OpaqueStyleAndLayoutData::new(StyleAndLayoutData::new());
|
||||||
let opaque = OpaqueStyleAndLayoutData {
|
|
||||||
ptr: NonNull::new_unchecked(ptr as *mut StyleData),
|
|
||||||
};
|
|
||||||
self.init_style_and_layout_data(opaque);
|
self.init_style_and_layout_data(opaque);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -558,10 +552,7 @@ impl<'le> TElement for ServoLayoutElement<'le> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_data(&self) -> Option<&AtomicRefCell<ElementData>> {
|
fn get_data(&self) -> Option<&AtomicRefCell<ElementData>> {
|
||||||
unsafe {
|
self.get_style_data().map(|data| &data.element_data)
|
||||||
self.get_style_and_layout_data()
|
|
||||||
.map(|d| &(*(d.ptr.as_ptr() as *mut StyleData)).element_data)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn skip_item_display_fixup(&self) -> bool {
|
fn skip_item_display_fixup(&self) -> bool {
|
||||||
|
@ -697,10 +688,12 @@ impl<'le> ServoLayoutElement<'le> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_style_data(&self) -> Option<&StyleData> {
|
fn get_style_data(&self) -> Option<&StyleData> {
|
||||||
unsafe {
|
self.get_style_and_layout_data().map(|opaque| {
|
||||||
self.get_style_and_layout_data()
|
&opaque
|
||||||
.map(|d| &*(d.ptr.as_ptr() as *mut StyleData))
|
.downcast_ref::<StyleAndLayoutData>()
|
||||||
}
|
.unwrap()
|
||||||
|
.style_data
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn unset_snapshot_flags(&self) {
|
pub unsafe fn unset_snapshot_flags(&self) {
|
||||||
|
|
|
@ -70,7 +70,6 @@ use std::borrow::Cow;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::ptr::NonNull;
|
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::Arc as StdArc;
|
use std::sync::Arc as StdArc;
|
||||||
use style::applicable_declarations::ApplicableDeclarationBlock;
|
use style::applicable_declarations::ApplicableDeclarationBlock;
|
||||||
|
@ -93,9 +92,7 @@ use style::stylist::CascadeData;
|
||||||
use style::CaseSensitivityExt;
|
use style::CaseSensitivityExt;
|
||||||
|
|
||||||
pub unsafe fn drop_style_and_layout_data(data: OpaqueStyleAndLayoutData) {
|
pub unsafe fn drop_style_and_layout_data(data: OpaqueStyleAndLayoutData) {
|
||||||
let ptr = data.ptr.as_ptr() as *mut StyleData;
|
drop(Box::from_raw(data.as_ptr()));
|
||||||
let non_opaque: *mut StyleAndLayoutData = ptr as *mut _;
|
|
||||||
let _ = Box::from_raw(non_opaque);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
@ -283,10 +280,7 @@ impl<'ln> LayoutNode<'ln> for ServoLayoutNode<'ln> {
|
||||||
|
|
||||||
unsafe fn initialize_data(&self) {
|
unsafe fn initialize_data(&self) {
|
||||||
if self.get_raw_data().is_none() {
|
if self.get_raw_data().is_none() {
|
||||||
let ptr: *mut StyleAndLayoutData = Box::into_raw(Box::new(StyleAndLayoutData::new()));
|
let opaque = OpaqueStyleAndLayoutData::new(StyleAndLayoutData::new());
|
||||||
let opaque = OpaqueStyleAndLayoutData {
|
|
||||||
ptr: NonNull::new_unchecked(ptr as *mut StyleData),
|
|
||||||
};
|
|
||||||
self.init_style_and_layout_data(opaque);
|
self.init_style_and_layout_data(opaque);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -565,10 +559,7 @@ impl<'le> TElement for ServoLayoutElement<'le> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_data(&self) -> Option<&AtomicRefCell<ElementData>> {
|
fn get_data(&self) -> Option<&AtomicRefCell<ElementData>> {
|
||||||
unsafe {
|
self.get_style_data().map(|data| &data.element_data)
|
||||||
self.get_style_and_layout_data()
|
|
||||||
.map(|d| &(*(d.ptr.as_ptr() as *mut StyleData)).element_data)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn skip_item_display_fixup(&self) -> bool {
|
fn skip_item_display_fixup(&self) -> bool {
|
||||||
|
@ -704,10 +695,12 @@ impl<'le> ServoLayoutElement<'le> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_style_data(&self) -> Option<&StyleData> {
|
fn get_style_data(&self) -> Option<&StyleData> {
|
||||||
unsafe {
|
self.get_style_and_layout_data().map(|opaque| {
|
||||||
self.get_style_and_layout_data()
|
&opaque
|
||||||
.map(|d| &*(d.ptr.as_ptr() as *mut StyleData))
|
.downcast_ref::<StyleAndLayoutData>()
|
||||||
}
|
.unwrap()
|
||||||
|
.style_data
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn unset_snapshot_flags(&self) {
|
pub unsafe fn unset_snapshot_flags(&self) {
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
//! to depend on script.
|
//! to depend on script.
|
||||||
|
|
||||||
#![deny(unsafe_code)]
|
#![deny(unsafe_code)]
|
||||||
|
#![feature(box_into_raw_non_null)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate html5ever;
|
extern crate html5ever;
|
||||||
|
@ -24,6 +25,7 @@ use libc::c_void;
|
||||||
use net_traits::image_cache::PendingImageId;
|
use net_traits::image_cache::PendingImageId;
|
||||||
use script_traits::UntrustedNodeAddress;
|
use script_traits::UntrustedNodeAddress;
|
||||||
use servo_url::{ImmutableOrigin, ServoUrl};
|
use servo_url::{ImmutableOrigin, ServoUrl};
|
||||||
|
use std::any::Any;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use std::sync::atomic::AtomicIsize;
|
use std::sync::atomic::AtomicIsize;
|
||||||
use style::data::ElementData;
|
use style::data::ElementData;
|
||||||
|
@ -54,7 +56,34 @@ pub struct OpaqueStyleAndLayoutData {
|
||||||
// NB: We really store a `StyleAndLayoutData` here, so be careful!
|
// NB: We really store a `StyleAndLayoutData` here, so be careful!
|
||||||
#[ignore_malloc_size_of = "TODO(#6910) Box value that should be counted but \
|
#[ignore_malloc_size_of = "TODO(#6910) Box value that should be counted but \
|
||||||
the type lives in layout"]
|
the type lives in layout"]
|
||||||
pub ptr: NonNull<StyleData>,
|
ptr: NonNull<dyn Any + Send + Sync>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OpaqueStyleAndLayoutData {
|
||||||
|
#[inline]
|
||||||
|
pub fn new<T>(value: T) -> Self
|
||||||
|
where
|
||||||
|
T: Any + Send + Sync,
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
ptr: Box::into_raw_non_null(Box::new(value) as Box<dyn Any + Send + Sync>),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn as_ptr(&self) -> *mut (dyn Any + Send + Sync) {
|
||||||
|
self.ptr.as_ptr()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extremely cursed.
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
#[inline]
|
||||||
|
pub unsafe fn downcast_ref<'extended, T>(&self) -> Option<&'extended T>
|
||||||
|
where
|
||||||
|
T: Any + Send + Sync,
|
||||||
|
{
|
||||||
|
(*self.ptr.as_ptr()).downcast_ref()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
|
|
|
@ -30,10 +30,10 @@ macro_rules! sizeof_checker (
|
||||||
|
|
||||||
// Update the sizes here
|
// Update the sizes here
|
||||||
sizeof_checker!(size_event_target, EventTarget, 56);
|
sizeof_checker!(size_event_target, EventTarget, 56);
|
||||||
sizeof_checker!(size_node, Node, 176);
|
sizeof_checker!(size_node, Node, 184);
|
||||||
sizeof_checker!(size_element, Element, 352);
|
sizeof_checker!(size_element, Element, 360);
|
||||||
sizeof_checker!(size_htmlelement, HTMLElement, 368);
|
sizeof_checker!(size_htmlelement, HTMLElement, 376);
|
||||||
sizeof_checker!(size_div, HTMLDivElement, 368);
|
sizeof_checker!(size_div, HTMLDivElement, 376);
|
||||||
sizeof_checker!(size_span, HTMLSpanElement, 368);
|
sizeof_checker!(size_span, HTMLSpanElement, 376);
|
||||||
sizeof_checker!(size_text, Text, 208);
|
sizeof_checker!(size_text, Text, 216);
|
||||||
sizeof_checker!(size_characterdata, CharacterData, 208);
|
sizeof_checker!(size_characterdata, CharacterData, 216);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue