Ignore the HTML parser's borrow flag in GC tracing

Adds some other dynamic checks in debug builds.
This commit is contained in:
Keegan McAllister 2014-10-23 18:10:00 -07:00
parent 6ec0939a22
commit 49234484d6
5 changed files with 59 additions and 5 deletions

View file

@ -6,6 +6,7 @@ use dom::bindings::trace::JSTraceable;
use js::jsapi::{JSTracer};
use servo_util::task_state;
use servo_util::task_state::{Script, InGC};
use std::cell::{Cell, UnsafeCell};
use std::kinds::marker;
@ -33,6 +34,23 @@ impl<T> DOMRefCell<T> {
&*self.value.get()
}
/// Borrow the contents for the purpose of GC tracing.
///
/// This succeeds even if the object is mutably borrowed,
/// so you have to be careful in trace code!
pub unsafe fn borrow_for_gc_trace<'a>(&'a self) -> &'a T {
debug_assert!(task_state::get().contains(Script | InGC));
&*self.value.get()
}
/// Is the cell mutably borrowed?
///
/// For safety checks in debug builds only.
#[cfg(not(ndebug))]
pub fn is_mutably_borrowed(&self) -> bool {
self.borrow.get() == WRITING
}
pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
debug_assert!(task_state::get().is_script());
match self.borrow.get() {

View file

@ -15,6 +15,8 @@ use dom::node::TrustedNodeAddress;
use dom::document::{Document, DocumentHelpers};
use parse::html::JSMessage;
use servo_util::task_state;
use std::default::Default;
use url::Url;
use js::jsapi::JSTracer;
@ -91,15 +93,23 @@ impl tree_builder::Tracer<TrustedNodeAddress> for Tracer {
impl JSTraceable for ServoHTMLParser {
fn trace(&self, trc: *mut JSTracer) {
self.reflector_.trace(trc);
let tracer = Tracer {
trc: trc,
};
let tracer = &tracer as &tree_builder::Tracer<TrustedNodeAddress>;
self.reflector_.trace(trc);
let tokenizer = self.tokenizer.borrow();
let tree_builder = tokenizer.sink();
tree_builder.trace_handles(tracer);
tree_builder.sink().trace(trc);
unsafe {
// Assertion: If the parser is mutably borrowed, we're in the
// parsing code paths.
debug_assert!(task_state::get().contains(task_state::InHTMLParser)
|| !self.tokenizer.is_mutably_borrowed());
let tokenizer = self.tokenizer.borrow_for_gc_trace();
let tree_builder = tokenizer.sink();
tree_builder.trace_handles(tracer);
tree_builder.sink().trace(trc);
}
}
}