Index: Source/bindings/core/v8/ScriptStreamer.cpp |
diff --git a/Source/bindings/core/v8/ScriptStreamer.cpp b/Source/bindings/core/v8/ScriptStreamer.cpp |
index c1cea1802f0d321dda9bca29f9196c6d450b2495..2fe8855d1326233c010e0e5ae16a601956db8abc 100644 |
--- a/Source/bindings/core/v8/ScriptStreamer.cpp |
+++ b/Source/bindings/core/v8/ScriptStreamer.cpp |
@@ -253,7 +253,8 @@ void ScriptStreamer::cancel() |
// its operations and streamingComplete will be called soon. |
m_detached = true; |
m_resource = 0; |
- m_stream->cancel(); |
+ if (m_stream) |
+ m_stream->cancel(); |
} |
void ScriptStreamer::suppressStreaming() |
@@ -265,6 +266,17 @@ void ScriptStreamer::suppressStreaming() |
m_streamingSuppressed = true; |
} |
+unsigned ScriptStreamer::cachedDataType() const |
+{ |
+ if (m_compileOptions == v8::ScriptCompiler::kProduceParserCache) { |
+ return V8ScriptRunner::tagForParserCache(); |
+ } |
+ if (m_compileOptions == v8::ScriptCompiler::kProduceCodeCache) { |
+ return V8ScriptRunner::tagForCodeCache(); |
+ } |
+ return 0; |
+} |
+ |
void ScriptStreamer::notifyAppendData(ScriptResource* resource) |
{ |
ASSERT(isMainThread()); |
@@ -283,6 +295,31 @@ void ScriptStreamer::notifyAppendData(ScriptResource* resource) |
} |
m_haveEnoughDataForStreaming = true; |
const char* histogramName = startedStreamingHistogramName(m_scriptType); |
+ |
+ // Encoding should be detected only when we have some data. It's |
+ // possible that resource->encoding() returns a different encoding |
+ // before the loading has started and after we got some data. |
+ WTF::TextEncoding textEncoding(resource->encoding()); |
+ const char* encodingName = textEncoding.name(); |
+ |
+ // Here's a list of encodings we can use for streaming. These are |
+ // the canonical names. |
+ v8::ScriptCompiler::StreamedSource::Encoding encoding; |
+ if (strcmp(encodingName, "windows-1252") == 0 |
+ || strcmp(encodingName, "ISO-8859-1") == 0 |
+ || strcmp(encodingName, "US-ASCII") == 0) { |
+ encoding = v8::ScriptCompiler::StreamedSource::ONE_BYTE; |
+ } else if (strcmp(encodingName, "UTF-8") == 0) { |
+ encoding = v8::ScriptCompiler::StreamedSource::UTF8; |
+ } else { |
+ // We don't stream other encodings; especially we don't stream two |
+ // byte scripts to avoid the handling of byte order marks. Most |
+ // scripts are Latin1 or UTF-8 anyway, so this should be enough for |
+ // most real world purposes. |
+ suppressStreaming(); |
+ blink::Platform::current()->histogramEnumeration(histogramName, 0, 2); |
+ return; |
+ } |
if (ScriptStreamerThread::shared()->isRunningTask()) { |
// At the moment we only have one thread for running the tasks. A |
// new task shouldn't be queued before the running task completes, |
@@ -292,17 +329,35 @@ void ScriptStreamer::notifyAppendData(ScriptResource* resource) |
blink::Platform::current()->histogramEnumeration(histogramName, 0, 2); |
return; |
} |
- ASSERT(m_task); |
+ |
+ ASSERT(!m_stream); |
+ ASSERT(!m_source); |
+ m_stream = new SourceStream(this); |
+ // m_source takes ownership of m_stream. |
+ m_source = adoptPtr(new v8::ScriptCompiler::StreamedSource(m_stream, encoding)); |
+ |
+ ScriptState::Scope scope(m_scriptState.get()); |
haraken
2014/11/04 10:36:38
I guess you need to check:
if (!m_scriptState->
marja
2014/11/04 10:41:39
Ok; this is already checked in startStreamingInter
|
+ WTF::OwnPtr<v8::ScriptCompiler::ScriptStreamingTask> scriptStreamingTask(adoptPtr(v8::ScriptCompiler::StartStreamingScript(m_scriptState->isolate(), m_source.get(), m_compileOptions))); |
+ if (!scriptStreamingTask) { |
+ // V8 cannot stream the script. |
+ suppressStreaming(); |
+ m_stream = 0; |
+ m_source.clear(); |
+ blink::Platform::current()->histogramEnumeration(histogramName, 0, 2); |
+ return; |
+ } |
+ |
// ScriptStreamer needs to stay alive as long as the background task is |
// running. This is taken care of with a manual ref() & deref() pair; |
// the corresponding deref() is in streamingComplete or in |
// notifyFinished. |
ref(); |
- ScriptStreamingTask* task = new ScriptStreamingTask(m_task.release(), this); |
+ ScriptStreamingTask* task = new ScriptStreamingTask(scriptStreamingTask.release(), this); |
ScriptStreamerThread::shared()->postTask(task); |
blink::Platform::current()->histogramEnumeration(histogramName, 1, 2); |
} |
- m_stream->didReceiveData(); |
+ if (m_stream) |
+ m_stream->didReceiveData(); |
} |
void ScriptStreamer::notifyFinished(Resource* resource) |
@@ -318,7 +373,8 @@ void ScriptStreamer::notifyFinished(Resource* resource) |
blink::Platform::current()->histogramEnumeration(histogramName, 0, 2); |
suppressStreaming(); |
} |
- m_stream->didFinishLoading(); |
+ if (m_stream) |
+ m_stream->didFinishLoading(); |
m_loadingFinished = true; |
if (shouldBlockMainThread()) { |
@@ -353,16 +409,17 @@ void ScriptStreamer::notifyFinished(Resource* resource) |
} |
} |
-ScriptStreamer::ScriptStreamer(ScriptResource* resource, v8::ScriptCompiler::StreamedSource::Encoding encoding, PendingScript::Type scriptType, ScriptStreamingMode mode) |
+ScriptStreamer::ScriptStreamer(ScriptResource* resource, PendingScript::Type scriptType, ScriptStreamingMode mode, ScriptState* scriptState, v8::ScriptCompiler::CompileOptions compileOptions) |
: m_resource(resource) |
, m_detached(false) |
- , m_stream(new SourceStream(this)) |
- , m_source(m_stream, encoding) // m_source takes ownership of m_stream. |
+ , m_stream(0) |
, m_client(0) |
, m_loadingFinished(false) |
, m_parsingFinished(false) |
, m_haveEnoughDataForStreaming(false) |
, m_streamingSuppressed(false) |
+ , m_compileOptions(compileOptions) |
+ , m_scriptState(scriptState) |
, m_scriptType(scriptType) |
, m_scriptStreamingMode(mode) |
, m_mainThreadWaitingForParserThread(false) |
@@ -456,34 +513,8 @@ bool ScriptStreamer::startStreamingInternal(PendingScript& script, Settings* set |
// to arrive. In general, the web servers don't seem to send the |
// Content-Length HTTP header for scripts. |
- WTF::TextEncoding textEncoding(resource->encoding()); |
- const char* encodingName = textEncoding.name(); |
- |
- // Here's a list of encodings we can use for streaming. These are |
- // the canonical names. |
- v8::ScriptCompiler::StreamedSource::Encoding encoding; |
- if (strcmp(encodingName, "windows-1252") == 0 |
- || strcmp(encodingName, "ISO-8859-1") == 0 |
- || strcmp(encodingName, "US-ASCII") == 0) { |
- encoding = v8::ScriptCompiler::StreamedSource::ONE_BYTE; |
- } else if (strcmp(encodingName, "UTF-8") == 0) { |
- encoding = v8::ScriptCompiler::StreamedSource::UTF8; |
- } else { |
- // We don't stream other encodings; especially we don't stream two byte |
- // scripts to avoid the handling of byte order marks. Most scripts are |
- // Latin1 or UTF-8 anyway, so this should be enough for most real world |
- // purposes. |
- return false; |
- } |
- |
if (!scriptState->contextIsValid()) |
return false; |
- ScriptState::Scope scope(scriptState); |
- |
- // The Resource might go out of scope if the script is no longer needed. We |
- // will soon call PendingScript::setStreamer, which makes the PendingScript |
- // notify the ScriptStreamer when it is destroyed. |
- RefPtr<ScriptStreamer> streamer = adoptRef(new ScriptStreamer(resource, encoding, scriptType, settings->v8ScriptStreamingMode())); |
// Decide what kind of cached data we should produce while streaming. By |
// default, we generate the parser cache for streamed scripts, to emulate |
@@ -491,14 +522,13 @@ bool ScriptStreamer::startStreamingInternal(PendingScript& script, Settings* set |
v8::ScriptCompiler::CompileOptions compileOption = v8::ScriptCompiler::kProduceParserCache; |
if (settings->v8CacheOptions() == V8CacheOptionsCode) |
compileOption = v8::ScriptCompiler::kProduceCodeCache; |
- v8::ScriptCompiler::ScriptStreamingTask* scriptStreamingTask = v8::ScriptCompiler::StartStreamingScript(scriptState->isolate(), &(streamer->m_source), compileOption); |
- if (scriptStreamingTask) { |
- streamer->m_task = adoptPtr(scriptStreamingTask); |
- script.setStreamer(streamer.release()); |
- return true; |
- } |
- // Otherwise, V8 cannot stream the script. |
- return false; |
+ |
+ // The Resource might go out of scope if the script is no longer |
+ // needed. This makes PendingScript notify the ScriptStreamer when it is |
+ // destroyed. |
+ script.setStreamer(adoptRef(new ScriptStreamer(resource, scriptType, settings->v8ScriptStreamingMode(), scriptState, compileOption))); |
+ |
+ return true; |
} |
} // namespace blink |