aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/context.rs
diff options
context:
space:
mode:
authorBobby Holley <bobbyholley@gmail.com>2016-12-16 11:50:11 -0800
committerBobby Holley <bobbyholley@gmail.com>2016-12-21 11:10:39 -0800
commitc5f01fe3b89c2a381fb891e9728fa2951b87a747 (patch)
treecca5add7c82e7f24255f4706696c02f2ed5bce3f /components/layout/context.rs
parent8f7f62f8104bf576c38f7cfa1fedfaf2c51c0049 (diff)
downloadservo-c5f01fe3b89c2a381fb891e9728fa2951b87a747.tar.gz
servo-c5f01fe3b89c2a381fb891e9728fa2951b87a747.zip
Introduce and use Scoped TLS.
It turns out that it's problematic to embed ThreadLocalStyleContext within LayoutContext, because parameterizing the former on TElement (which we do in the next patch) infects all the traversal stuff with the trait parameters, which we don't really want. In general, it probably makes sense to use separate scoped TLS types for the separate DOM and Flow tree passes, so we can add a different ScopedTLS type for the Flow pass if we ever need it. We also reorder the |scope| and |shared| parameters in parallel.rs, because it aligns more with the order in style/parallel.rs. I did this when I was adding a TLS parameter to all these functions, which I realized we don't need for now.
Diffstat (limited to 'components/layout/context.rs')
-rw-r--r--components/layout/context.rs71
1 files changed, 34 insertions, 37 deletions
diff --git a/components/layout/context.rs b/components/layout/context.rs
index 9497d736b47..cc20fa4ef0c 100644
--- a/components/layout/context.rs
+++ b/components/layout/context.rs
@@ -19,7 +19,6 @@ use net_traits::image_cache_thread::{ImageOrMetadataAvailable, UsePlaceholder};
use parking_lot::RwLock;
use servo_config::opts;
use servo_url::ServoUrl;
-use std::borrow::Borrow;
use std::cell::{RefCell, RefMut};
use std::collections::HashMap;
use std::hash::BuildHasherDefault;
@@ -27,59 +26,64 @@ use std::rc::Rc;
use std::sync::{Arc, Mutex};
use style::context::{SharedStyleContext, ThreadLocalStyleContext};
-pub struct ThreadLocalLayoutContext {
+/// TLS data scoped to the traversal.
+pub struct ScopedThreadLocalLayoutContext {
pub style_context: ThreadLocalStyleContext,
+}
+
+impl ScopedThreadLocalLayoutContext {
+ pub fn new(shared: &SharedLayoutContext) -> Self {
+ ScopedThreadLocalLayoutContext {
+ style_context: ThreadLocalStyleContext::new(&shared.style_context),
+ }
+ }
+}
+
+/// TLS data that persists across traversals.
+pub struct PersistentThreadLocalLayoutContext {
+ // FontContext uses Rc all over the place and so isn't Send, which means we
+ // can't use ScopedTLS for it. There's also no reason to scope it to the
+ // traversal, and performance is probably better if we don't.
pub font_context: RefCell<FontContext>,
}
-impl ThreadLocalLayoutContext {
+impl PersistentThreadLocalLayoutContext {
pub fn new(shared: &SharedLayoutContext) -> Rc<Self> {
let font_cache_thread = shared.font_cache_thread.lock().unwrap().clone();
- let local_style_data = shared.style_context.local_context_creation_data.lock().unwrap();
-
- Rc::new(ThreadLocalLayoutContext {
- style_context: ThreadLocalStyleContext::new(&local_style_data),
+ Rc::new(PersistentThreadLocalLayoutContext {
font_context: RefCell::new(FontContext::new(font_cache_thread)),
})
}
}
-impl Borrow<ThreadLocalStyleContext> for ThreadLocalLayoutContext {
- fn borrow(&self) -> &ThreadLocalStyleContext {
- &self.style_context
- }
-}
-
-impl HeapSizeOf for ThreadLocalLayoutContext {
- // FIXME(njn): measure other fields eventually.
+impl HeapSizeOf for PersistentThreadLocalLayoutContext {
fn heap_size_of_children(&self) -> usize {
self.font_context.heap_size_of_children()
}
}
-thread_local!(static LOCAL_CONTEXT_KEY: RefCell<Option<Rc<ThreadLocalLayoutContext>>> = RefCell::new(None));
+thread_local!(static LOCAL_CONTEXT_KEY: RefCell<Option<Rc<PersistentThreadLocalLayoutContext>>> = RefCell::new(None));
-pub fn heap_size_of_local_context() -> usize {
- LOCAL_CONTEXT_KEY.with(|r| {
- r.borrow().clone().map_or(0, |context| context.heap_size_of_children())
- })
-}
-
-// Keep this implementation in sync with the one in ports/geckolib/traversal.rs.
-pub fn create_or_get_local_context(shared: &SharedLayoutContext)
- -> Rc<ThreadLocalLayoutContext> {
+fn create_or_get_persistent_context(shared: &SharedLayoutContext)
+ -> Rc<PersistentThreadLocalLayoutContext> {
LOCAL_CONTEXT_KEY.with(|r| {
let mut r = r.borrow_mut();
if let Some(context) = r.clone() {
context
} else {
- let context = ThreadLocalLayoutContext::new(shared);
+ let context = PersistentThreadLocalLayoutContext::new(shared);
*r = Some(context.clone());
context
}
})
}
+pub fn heap_size_of_persistent_local_context() -> usize {
+ LOCAL_CONTEXT_KEY.with(|r| {
+ r.borrow().clone().map_or(0, |context| context.heap_size_of_children())
+ })
+}
+
/// Layout information shared among all workers. This must be thread-safe.
pub struct SharedLayoutContext {
/// Bits shared by the layout and style system.
@@ -100,24 +104,17 @@ pub struct SharedLayoutContext {
BuildHasherDefault<FnvHasher>>>>,
}
-impl Borrow<SharedStyleContext> for SharedLayoutContext {
- fn borrow(&self) -> &SharedStyleContext {
- &self.style_context
- }
-}
-
pub struct LayoutContext<'a> {
pub shared: &'a SharedLayoutContext,
- pub thread_local: &'a ThreadLocalLayoutContext,
+ pub persistent: Rc<PersistentThreadLocalLayoutContext>,
}
impl<'a> LayoutContext<'a> {
- pub fn new(shared: &'a SharedLayoutContext,
- thread_local: &'a ThreadLocalLayoutContext) -> Self
+ pub fn new(shared: &'a SharedLayoutContext) -> Self
{
LayoutContext {
shared: shared,
- thread_local: thread_local,
+ persistent: create_or_get_persistent_context(shared),
}
}
}
@@ -138,7 +135,7 @@ impl<'a> LayoutContext<'a> {
#[inline(always)]
pub fn font_context(&self) -> RefMut<FontContext> {
- self.thread_local.font_context.borrow_mut()
+ self.persistent.font_context.borrow_mut()
}
}