Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(321)

Unified Diff: third_party/WebKit/Source/core/dom/PendingScript.cpp

Issue 2695713015: WIP: Reland CompiledScript, prototype compiling in a separate task.
Patch Set: allow compile to fail, disallow restreaming (hack) Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/dom/PendingScript.cpp
diff --git a/third_party/WebKit/Source/core/dom/PendingScript.cpp b/third_party/WebKit/Source/core/dom/PendingScript.cpp
index 7ea074252620e6ed402a035c3bbe8bfceba0d48e..36891d53430be82b931e1f33a7faf12fa213a820 100644
--- a/third_party/WebKit/Source/core/dom/PendingScript.cpp
+++ b/third_party/WebKit/Source/core/dom/PendingScript.cpp
@@ -25,10 +25,15 @@
#include "core/dom/PendingScript.h"
+#include "bindings/core/v8/ScriptController.h"
#include "bindings/core/v8/ScriptSourceCode.h"
#include "core/dom/Element.h"
+#include "core/dom/ScriptLoader.h"
+#include "core/dom/TaskRunnerHelper.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/SubresourceIntegrity.h"
#include "platform/SharedBuffer.h"
+#include "platform/instrumentation/tracing/TraceEvent.h"
#include "wtf/CurrentTime.h"
namespace blink {
@@ -52,6 +57,7 @@ PendingScript::PendingScript(Element* element,
const TextPosition& startingPosition,
bool isForTesting)
: m_watchingForLoad(false),
+ m_readyState(resource ? kWaitingForResource : kReady),
m_element(element),
m_startingPosition(startingPosition),
m_integrityFailure(false),
@@ -99,7 +105,7 @@ void PendingScript::watchForLoad(PendingScriptClient* client) {
m_watchingForLoad = true;
m_client = client;
if (isReady())
- m_client->pendingScriptFinished(this);
+ client->pendingScriptFinished(this);
}
void PendingScript::stopWatchingForLoad() {
@@ -121,6 +127,51 @@ Element* PendingScript::element() const {
void PendingScript::streamingFinished() {
checkState();
DCHECK(resource());
+ fetchFinished();
+}
+
+void PendingScript::fetchFinished() {
+ advanceReadyState(kWaitingForCompile);
+
+ TRACE_EVENT_WITH_FLOW0("blink", "PendingScript compile", this,
+ TRACE_EVENT_FLAG_FLOW_OUT);
+ LocalFrame* frame = m_element ? m_element->document().frame() : nullptr;
+ if (!frame) {
+ // TODO(jbroman): A way of telling the client that it failed, without making
+ // the client try again, would be great.
+ compileFinished();
+ return;
+ }
+
+ ScriptState::Scope scope(ScriptState::forMainWorld(frame));
+ bool errorOccurred;
+ ScriptSourceCode sourceCode = getSource(KURL(), errorOccurred);
+
+ if (errorOccurred) {
+ // TODO(jbroman): A way of telling the client that it failed, without making
+ // the client try again, would be great.
+ compileFinished();
+ return;
+ }
+
+ const bool isExternalScript = true;
+ AccessControlStatus accessControlStatus =
+ ScriptLoader::accessControlStatusForScript(
+ isExternalScript, resource(),
+ m_element->document().getSecurityOrigin());
+ m_compiledScript =
+ frame->script().compileScriptInMainWorld(sourceCode, accessControlStatus);
+ // TODO(jbroman): Can this fail? Yes, it can.
+ // CHECK(m_compiledScript) << "no compiled script? :'(";
+ TaskRunnerHelper::get(TaskType::Networking, frame)
+ ->postTask(FROM_HERE, WTF::bind(&PendingScript::compileFinished,
+ wrapPersistent(this)));
+}
+
+void PendingScript::compileFinished() {
+ TRACE_EVENT_WITH_FLOW0("blink", "PendingScript compile", this,
+ TRACE_EVENT_FLAG_FLOW_IN);
+ advanceReadyState(kReady);
if (m_client)
m_client->pendingScriptFinished(this);
}
@@ -202,10 +253,12 @@ void PendingScript::notifyFinished(Resource* resource) {
// If script streaming is in use, the client will be notified in
// streamingFinished.
- if (m_streamer)
+ if (m_streamer) {
+ advanceReadyState(kWaitingForStreaming);
m_streamer->notifyFinished(resource);
- else if (m_client)
- m_client->pendingScriptFinished(this);
+ } else {
+ fetchFinished();
+ }
}
void PendingScript::notifyAppendData(ScriptResource* resource) {
@@ -217,6 +270,7 @@ DEFINE_TRACE(PendingScript) {
visitor->trace(m_element);
visitor->trace(m_streamer);
visitor->trace(m_client);
+ visitor->trace(m_compiledScript);
ResourceOwner<ScriptResource>::trace(visitor);
MemoryCoordinatorClient::trace(visitor);
}
@@ -228,8 +282,12 @@ ScriptSourceCode PendingScript::getSource(const KURL& documentURL,
errorOccurred = this->errorOccurred();
if (resource()) {
DCHECK(resource()->isLoaded());
- if (m_streamer && !m_streamer->streamingSuppressed())
+ // Avoid consuming the streamed source code more than once.
+ // TODO(jbroman): Update this if we don't always do the precompile step.
+ if (m_streamer && !m_streamer->streamingSuppressed() &&
+ m_readyState < ReadyState::kReady) {
return ScriptSourceCode(m_streamer, resource());
+ }
return ScriptSourceCode(resource());
}
@@ -240,17 +298,15 @@ ScriptSourceCode PendingScript::getSource(const KURL& documentURL,
void PendingScript::setStreamer(ScriptStreamer* streamer) {
DCHECK(!m_streamer);
DCHECK(!m_watchingForLoad);
+ DCHECK(!streamer->isFinished());
+ DCHECK_LT(m_readyState, kWaitingForStreaming);
m_streamer = streamer;
checkState();
}
bool PendingScript::isReady() const {
checkState();
- if (resource()) {
- return resource()->isLoaded() && (!m_streamer || m_streamer->isFinished());
- }
-
- return true;
+ return m_readyState == kReady;
}
bool PendingScript::errorOccurred() const {
« no previous file with comments | « third_party/WebKit/Source/core/dom/PendingScript.h ('k') | third_party/WebKit/Source/core/dom/ScriptLoader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698