mirror of
https://github.com/servo/servo.git
synced 2025-09-20 11:50:09 +01:00
Use an AtomicRefCell instead of a RwLock for caching intrinsic sizes (#34384)
It panics if the value is mutably borrowed concurrently, but this allows it to perform better. Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
63793ccbb7
commit
d034385f76
1 changed files with 9 additions and 13 deletions
|
@ -2,9 +2,8 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use std::sync::RwLock;
|
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
|
use atomic_refcell::AtomicRefCell;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
|
@ -41,7 +40,8 @@ pub(crate) struct NonReplacedFormattingContext {
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
pub style: Arc<ComputedValues>,
|
pub style: Arc<ComputedValues>,
|
||||||
/// If it was requested during construction
|
/// If it was requested during construction
|
||||||
pub content_sizes_result: RwLock<Option<(SizeConstraint, InlineContentSizesResult)>>,
|
#[serde(skip_serializing)]
|
||||||
|
pub content_sizes_result: AtomicRefCell<Option<(SizeConstraint, InlineContentSizesResult)>>,
|
||||||
pub contents: NonReplacedFormattingContextContents,
|
pub contents: NonReplacedFormattingContextContents,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ impl IndependentFormattingContext {
|
||||||
Self::NonReplaced(NonReplacedFormattingContext {
|
Self::NonReplaced(NonReplacedFormattingContext {
|
||||||
style: Arc::clone(&node_and_style_info.style),
|
style: Arc::clone(&node_and_style_info.style),
|
||||||
base_fragment_info,
|
base_fragment_info,
|
||||||
content_sizes_result: RwLock::default(),
|
content_sizes_result: AtomicRefCell::default(),
|
||||||
contents,
|
contents,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -298,24 +298,20 @@ impl NonReplacedFormattingContext {
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext,
|
||||||
constraint_space: &ConstraintSpace,
|
constraint_space: &ConstraintSpace,
|
||||||
) -> InlineContentSizesResult {
|
) -> InlineContentSizesResult {
|
||||||
if let Ok(Some((previous_cb_block_size, result))) =
|
let mut cache = self.content_sizes_result.borrow_mut();
|
||||||
self.content_sizes_result.read().as_deref()
|
if let Some((previous_cb_block_size, result)) = *cache {
|
||||||
{
|
|
||||||
if !result.depends_on_block_constraints ||
|
if !result.depends_on_block_constraints ||
|
||||||
*previous_cb_block_size == constraint_space.block_size
|
previous_cb_block_size == constraint_space.block_size
|
||||||
{
|
{
|
||||||
return *result;
|
return result;
|
||||||
}
|
}
|
||||||
// TODO: Should we keep multiple caches for various block sizes?
|
// TODO: Should we keep multiple caches for various block sizes?
|
||||||
}
|
}
|
||||||
|
|
||||||
let writer = self.content_sizes_result.write();
|
|
||||||
let result = self
|
let result = self
|
||||||
.contents
|
.contents
|
||||||
.inline_content_sizes(layout_context, constraint_space);
|
.inline_content_sizes(layout_context, constraint_space);
|
||||||
if let Ok(mut cache) = writer {
|
|
||||||
*cache = Some((constraint_space.block_size, result));
|
*cache = Some((constraint_space.block_size, result));
|
||||||
}
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue