Chromium Code Reviews| 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 |