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

Use html5ever’s BytesParser. #9677

Closed
wants to merge 4 commits into from
Closed
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Use VecDeque for the parser’s pending input.

`vec.remove(0)` is O(n)
  • Loading branch information
SimonSapin committed Feb 17, 2016
commit c0a5aa15d84e8612f2312c2eb604f88e444c2fcf
@@ -70,7 +70,7 @@ cssparser = {version = "0.5.3", features = ["heap_size", "serde-serialization"]}
encoding = "0.2"
euclid = {version = "0.6.2", features = ["plugins"]}
fnv = "1.0"
heapsize = "0.3.0"
heapsize = "0.3.2"
heapsize_plugin = "0.1.2"
html5ever = {version = "0.5.1", features = ["heap_size", "unstable"]}
hyper = { version = "0.7", features = [ "serde-serialization" ] }
@@ -70,7 +70,7 @@ use serde::{Deserialize, Serialize};
use smallvec::SmallVec;
use std::boxed::FnBox;
use std::cell::{Cell, UnsafeCell};
use std::collections::{HashMap, HashSet};
use std::collections::{HashMap, HashSet, VecDeque};
use std::ffi::CString;
use std::hash::{BuildHasher, Hash};
use std::intrinsics::return_address;
@@ -204,6 +204,17 @@ impl<T: JSTraceable> JSTraceable for Vec<T> {
}
}

// XXXManishearth Check if the following three are optimized to no-ops
// if e.trace() is a no-op (e.g it is an no_jsmanaged_fields type)
impl<T: JSTraceable> JSTraceable for VecDeque<T> {
#[inline]
fn trace(&self, trc: *mut JSTracer) {
for e in &*self {
e.trace(trc);
}
}
}

// XXXManishearth Check if the following three are optimized to no-ops
// if e.trace() is a no-op (e.g it is an no_jsmanaged_fields type)
impl<T: JSTraceable + 'static> JSTraceable for SmallVec<[T; 1]> {
@@ -32,6 +32,7 @@ use parse::Parser;
use script_thread::{ScriptChan, ScriptThread};
use std::cell::Cell;
use std::cell::UnsafeCell;
use std::collections::VecDeque;
use std::default::Default;
use std::ptr;
use url::Url;
@@ -171,7 +172,7 @@ impl<'a> ParserRef<'a> {
}
}

pub fn pending_input(&self) -> &DOMRefCell<Vec<String>> {
pub fn pending_input(&self) -> &DOMRefCell<VecDeque<String>> {
match *self {
ParserRef::HTML(parser) => parser.pending_input(),
ParserRef::XML(parser) => parser.pending_input(),
@@ -263,13 +264,13 @@ impl AsyncResponseListener for ParserContext {
self.is_synthesized_document = true;
let page = format!("<html><body><img src='{}' /></body></html>",
self.url.serialize());
parser.pending_input().borrow_mut().push(page);
parser.pending_input().borrow_mut().push_back(page);
parser.parse_sync();
},
Some(ContentType(Mime(TopLevel::Text, SubLevel::Plain, _))) => {
// https://html.spec.whatwg.org/multipage/#read-text
let page = format!("<pre>\n");
parser.pending_input().borrow_mut().push(page);
parser.pending_input().borrow_mut().push_back(page);
parser.parse_sync();
parser.set_plaintext_state();
},
@@ -285,7 +286,7 @@ impl AsyncResponseListener for ParserContext {
let page = format!("<html><body><p>Unknown content type ({}/{}).</p></body></html>",
toplevel.as_str(), sublevel.as_str());
self.is_synthesized_document = true;
parser.pending_input().borrow_mut().push(page);
parser.pending_input().borrow_mut().push_back(page);
parser.parse_sync();
},
None => {
@@ -335,7 +336,7 @@ pub struct ServoHTMLParser {
#[ignore_heap_size_of = "Defined in html5ever"]
tokenizer: DOMRefCell<Tokenizer>,
/// Input chunks received but not yet passed to the parser.
pending_input: DOMRefCell<Vec<String>>,
pending_input: DOMRefCell<VecDeque<String>>,
/// The document associated with this parser.
document: JS<Document>,
/// True if this parser should avoid passing any further data to the tokenizer.
@@ -350,7 +351,7 @@ pub struct ServoHTMLParser {
impl<'a> Parser for &'a ServoHTMLParser {
fn parse_chunk(self, input: String) {
self.document.set_current_parser(Some(ParserRef::HTML(self)));
self.pending_input.borrow_mut().push(input);
self.pending_input.borrow_mut().push_back(input);
if !self.is_suspended() {
self.parse_sync();
}
@@ -390,7 +391,7 @@ impl ServoHTMLParser {
let parser = ServoHTMLParser {
reflector_: Reflector::new(),
tokenizer: DOMRefCell::new(tok),
pending_input: DOMRefCell::new(vec!()),
pending_input: DOMRefCell::new(VecDeque::new()),
document: JS::from_ref(document),
suspended: Cell::new(false),
last_chunk_received: Cell::new(false),
@@ -427,7 +428,7 @@ impl ServoHTMLParser {
let parser = ServoHTMLParser {
reflector_: Reflector::new(),
tokenizer: DOMRefCell::new(tok),
pending_input: DOMRefCell::new(vec!()),
pending_input: DOMRefCell::new(VecDeque::new()),
document: JS::from_ref(document),
suspended: Cell::new(false),
last_chunk_received: Cell::new(true),
@@ -451,7 +452,7 @@ impl ServoHTMLParser {
self.tokenizer.borrow_mut().end()
}

pub fn pending_input(&self) -> &DOMRefCell<Vec<String>> {
pub fn pending_input(&self) -> &DOMRefCell<VecDeque<String>> {
&self.pending_input
}

@@ -465,8 +466,7 @@ impl ServoHTMLParser {
loop {
self.document.reflow_if_reflow_timer_expired();
let mut pending_input = self.pending_input.borrow_mut();
if !pending_input.is_empty() {
let chunk = pending_input.remove(0);
if let Some(chunk) = pending_input.pop_front() {
self.tokenizer.borrow_mut().feed(chunk.into());
} else {
self.tokenizer.borrow_mut().run();
@@ -17,6 +17,7 @@ use msg::constellation_msg::PipelineId;
use parse::Parser;
use script_thread::ScriptThread;
use std::cell::Cell;
use std::collections::VecDeque;
use url::Url;
use xml5ever::tokenizer;
use xml5ever::tree_builder::{self, XmlTreeBuilder};
@@ -37,7 +38,7 @@ pub struct ServoXMLParser {
#[ignore_heap_size_of = "Defined in xml5ever"]
tokenizer: DOMRefCell<Tokenizer>,
/// Input chunks received but not yet passed to the parser.
pending_input: DOMRefCell<Vec<String>>,
pending_input: DOMRefCell<VecDeque<String>>,
/// The document associated with this parser.
document: JS<Document>,
/// True if this parser should avoid passing any further data to the tokenizer.
@@ -52,7 +53,7 @@ pub struct ServoXMLParser {
impl<'a> Parser for &'a ServoXMLParser {
fn parse_chunk(self, input: String) {
self.document.set_current_parser(Some(ParserRef::XML(self)));
self.pending_input.borrow_mut().push(input);
self.pending_input.borrow_mut().push_back(input);
if !self.is_suspended() {
self.parse_sync();
}
@@ -89,7 +90,7 @@ impl ServoXMLParser {
let parser = ServoXMLParser {
reflector_: Reflector::new(),
tokenizer: DOMRefCell::new(tok),
pending_input: DOMRefCell::new(vec!()),
pending_input: DOMRefCell::new(VecDeque::new()),
document: JS::from_ref(document),
suspended: Cell::new(false),
last_chunk_received: Cell::new(false),
@@ -125,8 +126,7 @@ impl ServoXMLParser {
loop {
self.document.reflow_if_reflow_timer_expired();
let mut pending_input = self.pending_input.borrow_mut();
if !pending_input.is_empty() {
let chunk = pending_input.remove(0);
if let Some(chunk) = pending_input.pop_front() {
self.tokenizer.borrow_mut().feed(chunk.into());
}

@@ -145,7 +145,7 @@ impl ServoXMLParser {
}
}

pub fn pending_input(&self) -> &DOMRefCell<Vec<String>> {
pub fn pending_input(&self) -> &DOMRefCell<VecDeque<String>> {
&self.pending_input
}

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.