Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a safe, mostly-sound rooting rooting strategy. #2101

Merged
merged 16 commits into from May 3, 2014
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Store per-ScriptTask RootCollection in TLS and use that in favour of …

…per-frame collections.
  • Loading branch information
jdm committed May 3, 2014
commit aaf0a6119414072b34e3ef2109827eaf2f2a3156
@@ -6,9 +6,11 @@ use dom::bindings::utils::{Reflector, Reflectable, cx_for_dom_object};
use dom::window::Window;
use js::jsapi::{JSObject, JSContext, JS_AddObjectRoot, JS_RemoveObjectRoot};
use layout_interface::TrustedNodeAddress;
use script_task::StackRoots;

use std::cast;
use std::cell::RefCell;
use std::local_data;

/// A type that represents a JS-owned value that is rooted for the lifetime of this value.
/// Importantly, it requires explicit rooting in order to interact with the inner value.
@@ -52,8 +54,13 @@ impl<T: Reflectable> Temporary<T> {
}

/// Root this unrooted value.
pub fn root<'a, 'b>(self, collection: &'a RootCollection) -> Root<'a, 'b, T> {
collection.new_root(&self.inner)
pub fn root<'a, 'b>(self, _collection: &'a RootCollection) -> Root<'a, 'b, T> {
local_data::get(StackRoots, |opt| {
let collection = opt.unwrap();
unsafe {
(**collection).new_root(&self.inner)
}
})
}

unsafe fn inner(&self) -> JS<T> {
@@ -55,6 +55,7 @@ use servo_util::namespace::Null;
use std::cast;
use std::cell::{RefCell, Ref, RefMut};
use std::comm::{channel, Sender, Receiver, Empty, Disconnected, Data};
use std::local_data;
use std::mem::replace;
use std::ptr;
use std::rc::Rc;
@@ -63,6 +64,8 @@ use url::Url;

use serialize::{Encoder, Encodable};

local_data_key!(pub StackRoots: *RootCollection)

/// Messages used to control the script task.
pub enum ScriptMsg {
/// Loads a new URL on the specified pipeline.
@@ -510,6 +513,21 @@ pub struct JSPageInfo {
pub js_context: Untraceable<Rc<Cx>>,
}

struct StackRootTLS;

impl StackRootTLS {
fn new(roots: &RootCollection) -> StackRootTLS {
local_data::set(StackRoots, roots as *RootCollection);
StackRootTLS
}
}

impl Drop for StackRootTLS {
fn drop(&mut self) {
let _ = local_data::pop(StackRoots);
}
}

/// Information for an entire page. Pages are top-level browsing contexts and can contain multiple
/// frames.
///
@@ -653,6 +671,9 @@ impl ScriptTask {

/// Handle incoming control messages.
fn handle_msgs(&self) -> bool {
let roots = RootCollection::new();
let _stack_roots_tls = StackRootTLS::new(&roots);

// Handle pending resize events.
// Gather them first to avoid a double mut borrow on self.
let mut resizes = vec!();
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.