| 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..a769cc4677cc7ced8db1d0c562ccb83a5e720c90 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,41 @@ void ScriptStreamer::notifyAppendData(ScriptResource* resource)
|
| blink::Platform::current()->histogramEnumeration(histogramName, 0, 2);
|
| return;
|
| }
|
| - ASSERT(m_task);
|
| +
|
| + if (!m_scriptState->contextIsValid()) {
|
| + suppressStreaming();
|
| + blink::Platform::current()->histogramEnumeration(histogramName, 0, 2);
|
| + return;
|
| + }
|
| +
|
| + 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());
|
| + 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 +379,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 +415,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 +519,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 +528,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
|
|
|