Revert of Teach ScriptRunner how to yield and post on loading task queue...

Revert of Teach ScriptRunner how to yield and post on loading task queue (patchset #10 id:260001 of https://codereview.chromium.org/866273005/)

Reason for revert:
Looks like this was causing oilpan leaks

Original issue's description:
> Teach ScriptRunner how to yield
> 
> Previously ScriptRunner could execute an arbitrary number of scripts
> leading to janks.  Now ScriptRunner polls shouldYieldForHighPriorityWork
> before running each script.
> 
> In addition the task to execute the scripts is now posted on the
> loading task queue.
> 
> BUG=456777
> 
> Committed: https://src.chromium.org/viewvc/blink?view=rev&revision=190648

TBR=skyostil@chromium.org,marja@chromium.org,sigbjornf@opera.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=456777

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

git-svn-id: svn://svn.chromium.org/blink/trunk@190661 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 650accf4
......@@ -3750,7 +3750,6 @@
'dom/DocumentTest.cpp',
'dom/MainThreadTaskRunnerTest.cpp',
'dom/RangeTest.cpp',
'dom/ScriptRunnerTest.cpp',
'dom/TreeScopeTest.cpp',
'editing/CompositionUnderlineRangeFilterTest.cpp',
'editing/FrameSelectionTest.cpp',
......
......@@ -36,7 +36,7 @@ class ScriptLoaderClient;
class ScriptSourceCode;
class ScriptLoader : public NoBaseWillBeGarbageCollectedFinalized<ScriptLoader>, private ScriptResourceClient {
class ScriptLoader final : public NoBaseWillBeGarbageCollectedFinalized<ScriptLoader>, private ScriptResourceClient {
public:
static PassOwnPtrWillBeRawPtr<ScriptLoader> create(Element* element, bool createdByParser, bool isEvaluated)
{
......@@ -54,7 +54,7 @@ public:
String scriptCharset() const { return m_characterEncoding; }
String scriptContent() const;
void executeScript(const ScriptSourceCode&, double* compilationFinishTime = 0);
virtual void execute();
void execute();
// XML parser calls these
void dispatchLoadEvent();
......@@ -78,15 +78,14 @@ public:
void handleSourceAttribute(const String& sourceUrl);
void handleAsyncAttribute();
virtual bool isReady() const { return m_pendingScript.isReady(); }
bool isReady() const { return m_pendingScript.isReady(); }
// Clears the connection to the PendingScript (and Element and Resource).
void detach();
protected:
private:
ScriptLoader(Element*, bool createdByParser, bool isEvaluated);
private:
bool ignoresLoadRequest() const;
bool isScriptForEventSupported() const;
......
......@@ -30,14 +30,12 @@
#include "core/dom/Element.h"
#include "core/dom/ScriptLoader.h"
#include "platform/heap/Handle.h"
#include "platform/scheduler/Scheduler.h"
#include "wtf/Functional.h"
namespace blink {
ScriptRunner::ScriptRunner(Document* document)
: m_document(document)
, m_executeScriptsTaskFactory(WTF::bind(&ScriptRunner::executeScripts, this))
, m_timer(this, &ScriptRunner::timerFired)
{
ASSERT(document);
}
......@@ -79,13 +77,13 @@ void ScriptRunner::queueScriptForExecution(ScriptLoader* scriptLoader, Execution
void ScriptRunner::suspend()
{
m_executeScriptsTaskFactory.cancel();
m_timer.stop();
}
void ScriptRunner::resume()
{
if (hasPendingScripts())
postTaskIfOneIsNotAlreadyInFlight();
m_timer.startOneShot(0, FROM_HERE);
}
void ScriptRunner::notifyScriptReady(ScriptLoader* scriptLoader, ExecutionType executionType)
......@@ -105,7 +103,7 @@ void ScriptRunner::notifyScriptReady(ScriptLoader* scriptLoader, ExecutionType e
RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(!m_scriptsToExecuteInOrder.isEmpty());
break;
}
postTaskIfOneIsNotAlreadyInFlight();
m_timer.startOneShot(0, FROM_HERE);
}
void ScriptRunner::notifyScriptLoadError(ScriptLoader* scriptLoader, ExecutionType executionType)
......@@ -163,54 +161,28 @@ void ScriptRunner::movePendingAsyncScript(ScriptRunner* newRunner, ScriptLoader*
}
}
void ScriptRunner::executeScripts()
void ScriptRunner::timerFired(Timer<ScriptRunner>* timer)
{
ASSERT_UNUSED(timer, timer == &m_timer);
RefPtrWillBeRawPtr<Document> protect(m_document.get());
// New scripts are always appended to m_scriptsToExecuteSoon and m_scriptsToExecuteInOrder (never prepended)
// so as long as we keep track of the current totals, we can ensure the order of execution if new scripts
// are added while executing the current ones.
// NOTE a yield followed by a notifyScriptReady(... ASYNC_EXECUTION) will result in that script executing
// before any pre-existing ScriptsToExecuteInOrder.
size_t numScriptsToExecuteSoon = m_scriptsToExecuteSoon.size();
size_t numScriptsToExecuteInOrder = m_scriptsToExecuteInOrder.size();
for (size_t i = 0; i < numScriptsToExecuteSoon; i++) {
ASSERT(!m_scriptsToExecuteSoon.isEmpty());
m_scriptsToExecuteSoon.takeFirst()->execute();
m_document->decrementLoadEventDelayCount();
if (yieldForHighPriorityWork())
return;
}
WillBeHeapVector<RawPtrWillBeMember<ScriptLoader> > scriptLoaders;
scriptLoaders.swap(m_scriptsToExecuteSoon);
for (size_t i = 0; i < numScriptsToExecuteInOrder; i++) {
ASSERT(!m_scriptsToExecuteInOrder.isEmpty());
if (!m_scriptsToExecuteInOrder.first()->isReady())
break;
m_scriptsToExecuteInOrder.takeFirst()->execute();
size_t numInOrderScriptsToExecute = 0;
for (; numInOrderScriptsToExecute < m_scriptsToExecuteInOrder.size() && m_scriptsToExecuteInOrder[numInOrderScriptsToExecute]->isReady(); ++numInOrderScriptsToExecute)
scriptLoaders.append(m_scriptsToExecuteInOrder[numInOrderScriptsToExecute]);
if (numInOrderScriptsToExecute)
m_scriptsToExecuteInOrder.remove(0, numInOrderScriptsToExecute);
size_t size = scriptLoaders.size();
for (size_t i = 0; i < size; ++i) {
scriptLoaders[i]->execute();
m_document->decrementLoadEventDelayCount();
if (yieldForHighPriorityWork())
return;
}
}
bool ScriptRunner::yieldForHighPriorityWork()
{
if (!Scheduler::shared()->shouldYieldForHighPriorityWork())
return false;
postTaskIfOneIsNotAlreadyInFlight();
return true;
}
void ScriptRunner::postTaskIfOneIsNotAlreadyInFlight()
{
if (m_executeScriptsTaskFactory.isPending())
return;
// FIXME: Rename task() so that it's obvious it cancels any pending task.
Scheduler::shared()->postLoadingTask(FROM_HERE, m_executeScriptsTaskFactory.task());
}
void ScriptRunner::trace(Visitor* visitor)
{
#if ENABLE(OILPAN)
......
......@@ -27,12 +27,12 @@
#define ScriptRunner_h
#include "core/fetch/ResourcePtr.h"
#include "platform/Timer.h"
#include "platform/heap/Handle.h"
#include "platform/scheduler/CancellableTaskFactory.h"
#include "wtf/Deque.h"
#include "wtf/HashMap.h"
#include "wtf/Noncopyable.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/Vector.h"
namespace blink {
......@@ -63,22 +63,18 @@ public:
private:
explicit ScriptRunner(Document*);
void executeScripts();
void timerFired(Timer<ScriptRunner>*);
void addPendingAsyncScript(ScriptLoader*);
void movePendingAsyncScript(ScriptRunner*, ScriptLoader*);
bool yieldForHighPriorityWork();
void postTaskIfOneIsNotAlreadyInFlight();
RawPtrWillBeMember<Document> m_document;
WillBeHeapDeque<RawPtrWillBeMember<ScriptLoader>> m_scriptsToExecuteInOrder;
WillBeHeapVector<RawPtrWillBeMember<ScriptLoader> > m_scriptsToExecuteInOrder;
// http://www.whatwg.org/specs/web-apps/current-work/#set-of-scripts-that-will-execute-as-soon-as-possible
WillBeHeapDeque<RawPtrWillBeMember<ScriptLoader>> m_scriptsToExecuteSoon;
WillBeHeapVector<RawPtrWillBeMember<ScriptLoader> > m_scriptsToExecuteSoon;
WillBeHeapHashSet<RawPtrWillBeMember<ScriptLoader> > m_pendingAsyncScripts;
CancellableTaskFactory m_executeScriptsTaskFactory;
Timer<ScriptRunner> m_timer;
};
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment