Pending scripts can cause disposed documents to leak.

The script runner of a document may still be holding pending scripts
when the document is disposed (e.g. due to navigation). The script
runner, and thus the pending scripts, is cleared in the destructor of
the document. However, the pending scripts keep a reference to the
script element they belong to. The script element in turn, keeps a
guard ref to the document, so the document will never be deleted.
Clearing the script runner in dispose clears the pending scripts and
breaks the reference cycle so that document can be deleted.

BUG=534844
R=sigbjornf@opera.com

Review URL: https://codereview.chromium.org/1368623003

Cr-Commit-Position: refs/heads/master@{#350664}
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/pending-script-leak-expected.txt b/third_party/WebKit/LayoutTests/http/tests/loading/pending-script-leak-expected.txt
new file mode 100644
index 0000000..d51532b1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/loading/pending-script-leak-expected.txt
@@ -0,0 +1,12 @@
+main frame - didStartProvisionalLoadForFrame
+main frame - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+main frame - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+
+There should be no leaks when run with --enable-leak-detection
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/pending-script-leak.html b/third_party/WebKit/LayoutTests/http/tests/loading/pending-script-leak.html
new file mode 100644
index 0000000..081c645
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/loading/pending-script-leak.html
@@ -0,0 +1,17 @@
+<html>
+<body>
+<script>
+var iframe = document.createElement("iframe");
+document.body.appendChild(iframe);
+
+var s = iframe.contentWindow.document.createElement("script");
+s.src = "http://127.0.0.1:8000/resources/slow-script.pl?delay=10000";
+s.async = false;
+iframe.contentWindow.document.body.appendChild(s);
+
+if (window.testRunner)
+    testRunner.dumpAsText();
+</script>
+<p>There should be no leaks when run with --enable-leak-detection
+</body>
+</html>
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index dff02f7..0327bab 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -572,6 +572,7 @@
     m_userActionElements.documentDidRemoveLastRef();
     m_associatedFormControls.clear();
 
+    m_scriptRunner.clear();
     detachParser();
 
     m_registrationContext.clear();