servo: Merge #15128 - Simplify how we handle script scheduling and delaying the load event (from nox:load-fixes); r=Ms2ger
authorAnthony Ramine <n.oxyde@gmail.com>
Fri, 20 Jan 2017 13:41:32 -0800
changeset 340621 e4e8cc664762509710d6fe292868747400c3547d
parent 340620 21f4a8184f20d3ff90a63a1c16f2e149997fe1a4
child 340622 1c1740c59404bace470b9045b225d8d6ed1b56e9
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMs2ger
servo: Merge #15128 - Simplify how we handle script scheduling and delaying the load event (from nox:load-fixes); r=Ms2ger Source-Repo: https://github.com/servo/servo Source-Revision: 830fe189adfa93a09af5e4018a110a718a8a95cd
servo/components/script/dom/document.rs
servo/components/script/dom/servoparser/mod.rs
--- a/servo/components/script/dom/document.rs
+++ b/servo/components/script/dom/document.rs
@@ -224,17 +224,17 @@ pub struct Document {
     pending_parsing_blocking_script: DOMRefCell<Option<PendingScript>>,
     /// Number of stylesheets that block executing the next parser-inserted script
     script_blocking_stylesheets_count: Cell<u32>,
     /// https://html.spec.whatwg.org/multipage/#list-of-scripts-that-will-execute-when-the-document-has-finished-parsing
     deferred_scripts: PendingInOrderScriptVec,
     /// https://html.spec.whatwg.org/multipage/#list-of-scripts-that-will-execute-in-order-as-soon-as-possible
     asap_in_order_scripts_list: PendingInOrderScriptVec,
     /// https://html.spec.whatwg.org/multipage/#set-of-scripts-that-will-execute-as-soon-as-possible
-    asap_scripts_set: DOMRefCell<VecDeque<PendingScript>>,
+    asap_scripts_set: DOMRefCell<Vec<JS<HTMLScriptElement>>>,
     /// https://html.spec.whatwg.org/multipage/#concept-n-noscript
     /// True if scripting is enabled for all scripts in this document
     scripting_enabled: Cell<bool>,
     /// https://html.spec.whatwg.org/multipage/#animation-frame-callback-identifier
     /// Current identifier of animation frame callback
     animation_frame_ident: Cell<u32>,
     /// https://html.spec.whatwg.org/multipage/#list-of-animation-frame-callbacks
     /// List of animation frame callbacks
@@ -1542,39 +1542,25 @@ impl Document {
     pub fn finish_load(&self, load: LoadType) {
         debug!("Document got finish_load: {:?}", load);
         // The parser might need the loader, so restrict the lifetime of the borrow.
         {
             let mut loader = self.loader.borrow_mut();
             loader.finish_load(&load);
         }
 
-        if let LoadType::Script(_) = load {
-            self.process_deferred_scripts();
-            self.process_asap_scripts();
-        }
-
-        if let Some(parser) = self.get_current_parser() {
-            let ready_to_be_executed = match self.pending_parsing_blocking_script.borrow_mut().as_mut() {
-                Some(pending) => {
-                    if self.script_blocking_stylesheets_count.get() > 0 {
-                        return;
-                    }
-                    if let Some(pair) = pending.take_result() {
-                        Some(pair)
-                    } else {
-                        return;
-                    }
-                },
-                None => None,
-            };
-            if let Some((element, result)) = ready_to_be_executed {
-                *self.pending_parsing_blocking_script.borrow_mut() = None;
-                parser.resume_with_pending_parsing_blocking_script(&element, result);
-            }
+        match load {
+            LoadType::Stylesheet(_) => {
+                self.process_deferred_scripts();
+                self.process_pending_parsing_blocking_script();
+            },
+            LoadType::PageSource(_) => {
+                self.process_deferred_scripts();
+            },
+            _ => {},
         }
 
         if !self.loader.borrow().is_blocked() && !self.loader.borrow().events_inhibited() {
             self.loader.borrow_mut().inhibit_events();
             // Schedule a task to fire a "load" event.
             debug!("Document loads are complete.");
             let handler = box DocumentProgressHandler::new(Trusted::new(self));
             self.window.dom_manipulation_task_source().queue(handler, self.window.upcast()).unwrap();
@@ -1589,69 +1575,81 @@ impl Document {
     }
 
     pub fn has_pending_parsing_blocking_script(&self) -> bool {
         self.pending_parsing_blocking_script.borrow().is_some()
     }
 
     /// https://html.spec.whatwg.org/multipage/#prepare-a-script step 22.d.
     pub fn pending_parsing_blocking_script_loaded(&self, element: &HTMLScriptElement, result: ScriptResult) {
-        let mut blocking_script = self.pending_parsing_blocking_script.borrow_mut();
-        let entry = blocking_script.as_mut().unwrap();
-        assert!(&*entry.element == element);
-        entry.loaded(result);
+        {
+            let mut blocking_script = self.pending_parsing_blocking_script.borrow_mut();
+            let entry = blocking_script.as_mut().unwrap();
+            assert!(&*entry.element == element);
+            entry.loaded(result);
+        }
+        self.process_pending_parsing_blocking_script();
+    }
+
+    fn process_pending_parsing_blocking_script(&self) {
+        if self.script_blocking_stylesheets_count.get() > 0 {
+            return;
+        }
+        let pair = self.pending_parsing_blocking_script
+            .borrow_mut()
+            .as_mut()
+            .and_then(PendingScript::take_result);
+        if let Some((element, result)) = pair {
+            *self.pending_parsing_blocking_script.borrow_mut() = None;
+            self.get_current_parser().unwrap().resume_with_pending_parsing_blocking_script(&element, result);
+        }
     }
 
     pub fn add_asap_script(&self, script: &HTMLScriptElement) {
-        self.asap_scripts_set.borrow_mut().push_back(PendingScript::new(script));
+        self.asap_scripts_set.borrow_mut().push(JS::from_ref(script));
     }
 
     /// https://html.spec.whatwg.org/multipage/#the-end step 3.
     /// https://html.spec.whatwg.org/multipage/#prepare-a-script step 22.d.
     pub fn asap_script_loaded(&self, element: &HTMLScriptElement, result: ScriptResult) {
-        let mut scripts = self.asap_scripts_set.borrow_mut();
-        let idx = scripts.iter().position(|entry| &*entry.element == element).unwrap();
-        scripts.swap(0, idx);
-        scripts[0].loaded(result);
+        {
+            let mut scripts = self.asap_scripts_set.borrow_mut();
+            let idx = scripts.iter().position(|entry| &**entry == element).unwrap();
+            scripts.swap_remove(idx);
+        }
+        element.execute(result);
     }
 
     pub fn push_asap_in_order_script(&self, script: &HTMLScriptElement) {
         self.asap_in_order_scripts_list.push(script);
     }
 
     /// https://html.spec.whatwg.org/multipage/#the-end step 3.
     /// https://html.spec.whatwg.org/multipage/#prepare-a-script step 22.c.
     pub fn asap_in_order_script_loaded(&self,
                                        element: &HTMLScriptElement,
                                        result: ScriptResult) {
         self.asap_in_order_scripts_list.loaded(element, result);
-    }
-
-    fn process_asap_scripts(&self) {
-        let pair = self.asap_scripts_set.borrow_mut().front_mut().and_then(PendingScript::take_result);
-        if let Some((element, result)) = pair {
-            self.asap_scripts_set.borrow_mut().pop_front();
-            element.execute(result);
-        }
         while let Some((element, result)) = self.asap_in_order_scripts_list.take_next_ready_to_be_executed() {
             element.execute(result);
         }
     }
 
     pub fn add_deferred_script(&self, script: &HTMLScriptElement) {
         self.deferred_scripts.push(script);
     }
 
     /// https://html.spec.whatwg.org/multipage/#prepare-a-script step 22.d.
     pub fn deferred_script_loaded(&self, element: &HTMLScriptElement, result: ScriptResult) {
         self.deferred_scripts.loaded(element, result);
+        self.process_deferred_scripts();
     }
 
     /// https://html.spec.whatwg.org/multipage/#the-end step 3.
-    pub fn process_deferred_scripts(&self) {
+    fn process_deferred_scripts(&self) {
         if self.ready_state.get() != DocumentReadyState::Interactive {
             return;
         }
         // Part of substep 1.
         loop {
             if self.script_blocking_stylesheets_count.get() > 0 {
                 return;
             }
--- a/servo/components/script/dom/servoparser/mod.rs
+++ b/servo/components/script/dom/servoparser/mod.rs
@@ -354,19 +354,18 @@ impl ServoParser {
         if self.pipeline.is_some() {
             // Initial reflow.
             self.document.disarm_reflow_timeout();
             self.document.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
             let window = self.document.window();
             window.reflow(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery, ReflowReason::FirstLoad);
         }
 
-        // Steps 3-12 are in other castles, namely process_deferred_scripts and finish_load.
+        // Steps 3-12 are in another castle, namely finish_load.
         let url = self.tokenizer.borrow().url().clone();
-        self.document.process_deferred_scripts();
         self.document.finish_load(LoadType::PageSource(url));
     }
 }
 
 pub struct FragmentParsingResult {
     inner: NodeSiblingIterator,
 }