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

Side by Side Diff: Source/bindings/core/v8/ScriptStreamer.cpp

Issue 829313004: Retire unnecessary ScriptStreamer back reference from SourceStream. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 11 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "bindings/core/v8/ScriptStreamer.h" 6 #include "bindings/core/v8/ScriptStreamer.h"
7 7
8 #include "bindings/core/v8/ScriptStreamerThread.h" 8 #include "bindings/core/v8/ScriptStreamerThread.h"
9 #include "bindings/core/v8/V8ScriptRunner.h" 9 #include "bindings/core/v8/V8ScriptRunner.h"
10 #include "core/dom/Document.h" 10 #include "core/dom/Document.h"
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 }; 82 };
83 83
84 84
85 // SourceStream implements the streaming interface towards V8. The main 85 // SourceStream implements the streaming interface towards V8. The main
86 // functionality is preparing the data to give to V8 on main thread, and 86 // functionality is preparing the data to give to V8 on main thread, and
87 // actually giving the data (via GetMoreData which is called on a background 87 // actually giving the data (via GetMoreData which is called on a background
88 // thread). 88 // thread).
89 class SourceStream : public v8::ScriptCompiler::ExternalSourceStream { 89 class SourceStream : public v8::ScriptCompiler::ExternalSourceStream {
90 WTF_MAKE_NONCOPYABLE(SourceStream); 90 WTF_MAKE_NONCOPYABLE(SourceStream);
91 public: 91 public:
92 SourceStream(ScriptStreamer* streamer) 92 SourceStream()
93 : v8::ScriptCompiler::ExternalSourceStream() 93 : v8::ScriptCompiler::ExternalSourceStream()
94 , m_streamer(streamer)
95 , m_cancelled(false) 94 , m_cancelled(false)
96 , m_dataPosition(0) { } 95 , m_dataPosition(0) { }
97 96
98 virtual ~SourceStream() { } 97 virtual ~SourceStream() { }
99 98
100 // Called by V8 on a background thread. Should block until we can return 99 // Called by V8 on a background thread. Should block until we can return
101 // some data. 100 // some data.
102 virtual size_t GetMoreData(const uint8_t** src) override 101 virtual size_t GetMoreData(const uint8_t** src) override
103 { 102 {
104 ASSERT(!isMainThread()); 103 ASSERT(!isMainThread());
(...skipping 12 matching lines...) Expand all
117 } 116 }
118 return length; 117 return length;
119 } 118 }
120 119
121 void didFinishLoading() 120 void didFinishLoading()
122 { 121 {
123 ASSERT(isMainThread()); 122 ASSERT(isMainThread());
124 m_dataQueue.finish(); 123 m_dataQueue.finish();
125 } 124 }
126 125
127 void didReceiveData(size_t lengthOfBOM) 126 void didReceiveData(ScriptStreamer* streamer, size_t lengthOfBOM)
128 { 127 {
129 ASSERT(isMainThread()); 128 ASSERT(isMainThread());
130 prepareDataOnMainThread(lengthOfBOM); 129 prepareDataOnMainThread(streamer, lengthOfBOM);
131 } 130 }
132 131
133 void cancel() 132 void cancel()
134 { 133 {
135 ASSERT(isMainThread()); 134 ASSERT(isMainThread());
136 // The script is no longer needed by the upper layers. Stop streaming 135 // The script is no longer needed by the upper layers. Stop streaming
137 // it. The next time GetMoreData is called (or woken up), it will return 136 // it. The next time GetMoreData is called (or woken up), it will return
138 // 0, which will be interpreted as EOS by V8 and the parsing will 137 // 0, which will be interpreted as EOS by V8 and the parsing will
139 // fail. ScriptStreamer::streamingComplete will be called, and at that 138 // fail. ScriptStreamer::streamingComplete will be called, and at that
140 // point we will release the references to SourceStream. 139 // point we will release the references to SourceStream.
141 { 140 {
142 MutexLocker locker(m_mutex); 141 MutexLocker locker(m_mutex);
143 m_cancelled = true; 142 m_cancelled = true;
144 } 143 }
145 m_dataQueue.finish(); 144 m_dataQueue.finish();
146 } 145 }
147 146
148 private: 147 private:
149 void prepareDataOnMainThread(size_t lengthOfBOM) 148 void prepareDataOnMainThread(ScriptStreamer* streamer, size_t lengthOfBOM)
150 { 149 {
151 ASSERT(isMainThread()); 150 ASSERT(isMainThread());
152 // The Resource must still be alive; otherwise we should've cancelled 151 // The Resource must still be alive; otherwise we should've cancelled
153 // the streaming (if we have cancelled, the background thread is not 152 // the streaming (if we have cancelled, the background thread is not
154 // waiting). 153 // waiting).
155 ASSERT(m_streamer->resource()); 154 ASSERT(streamer->resource());
156 155
157 // BOM can only occur at the beginning of the data. 156 // BOM can only occur at the beginning of the data.
158 ASSERT(lengthOfBOM == 0 || m_dataPosition == 0); 157 ASSERT(lengthOfBOM == 0 || m_dataPosition == 0);
159 158
160 if (m_streamer->resource()->cachedMetadata(V8ScriptRunner::tagForCodeCac he(m_streamer->resource()))) { 159 if (streamer->resource()->cachedMetadata(V8ScriptRunner::tagForCodeCache (streamer->resource()))) {
161 // The resource has a code cache, so it's unnecessary to stream and 160 // The resource has a code cache, so it's unnecessary to stream and
162 // parse the code. Cancel the streaming and resume the non-streaming 161 // parse the code. Cancel the streaming and resume the non-streaming
163 // code path. 162 // code path.
164 m_streamer->suppressStreaming(); 163 streamer->suppressStreaming();
165 { 164 {
166 MutexLocker locker(m_mutex); 165 MutexLocker locker(m_mutex);
167 m_cancelled = true; 166 m_cancelled = true;
168 } 167 }
169 m_dataQueue.finish(); 168 m_dataQueue.finish();
170 return; 169 return;
171 } 170 }
172 171
173 if (!m_resourceBuffer) { 172 if (!m_resourceBuffer) {
174 // We don't have a buffer yet. Try to get it from the resource. 173 // We don't have a buffer yet. Try to get it from the resource.
175 SharedBuffer* buffer = m_streamer->resource()->resourceBuffer(); 174 SharedBuffer* buffer = streamer->resource()->resourceBuffer();
176 m_resourceBuffer = RefPtr<SharedBuffer>(buffer); 175 m_resourceBuffer = RefPtr<SharedBuffer>(buffer);
177 } 176 }
178 177
179 // Get as much data from the ResourceBuffer as we can. 178 // Get as much data from the ResourceBuffer as we can.
180 const char* data = 0; 179 const char* data = 0;
181 Vector<const char*> chunks; 180 Vector<const char*> chunks;
182 Vector<unsigned> chunkLengths; 181 Vector<unsigned> chunkLengths;
183 size_t dataLength = 0; 182 size_t dataLength = 0;
184 while (unsigned length = m_resourceBuffer->getSomeData(data, m_dataPosit ion)) { 183 while (unsigned length = m_resourceBuffer->getSomeData(data, m_dataPosit ion)) {
185 // FIXME: Here we can limit based on the total length, if it turns 184 // FIXME: Here we can limit based on the total length, if it turns
(...skipping 13 matching lines...) Expand all
199 for (size_t i = 0; i < chunks.size(); ++i) { 198 for (size_t i = 0; i < chunks.size(); ++i) {
200 memcpy(copiedData + offset, chunks[i] + lengthOfBOM, chunkLength s[i] - lengthOfBOM); 199 memcpy(copiedData + offset, chunks[i] + lengthOfBOM, chunkLength s[i] - lengthOfBOM);
201 offset += chunkLengths[i] - lengthOfBOM; 200 offset += chunkLengths[i] - lengthOfBOM;
202 // BOM is only in the first chunk 201 // BOM is only in the first chunk
203 lengthOfBOM = 0; 202 lengthOfBOM = 0;
204 } 203 }
205 m_dataQueue.produce(copiedData, dataLength); 204 m_dataQueue.produce(copiedData, dataLength);
206 } 205 }
207 } 206 }
208 207
209 ScriptStreamer* m_streamer;
210
211 // For coordinating between the main thread and background thread tasks. 208 // For coordinating between the main thread and background thread tasks.
212 // Guarded by m_mutex. 209 // Guarded by m_mutex.
213 bool m_cancelled; 210 bool m_cancelled;
214 Mutex m_mutex; 211 Mutex m_mutex;
215 212
216 unsigned m_dataPosition; // Only used by the main thread. 213 unsigned m_dataPosition; // Only used by the main thread.
217 RefPtr<SharedBuffer> m_resourceBuffer; // Only used by the main thread. 214 RefPtr<SharedBuffer> m_resourceBuffer; // Only used by the main thread.
218 SourceStreamDataQueue m_dataQueue; // Thread safe. 215 SourceStreamDataQueue m_dataQueue; // Thread safe.
219 }; 216 };
220 217
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 } 341 }
345 342
346 if (!m_scriptState->contextIsValid()) { 343 if (!m_scriptState->contextIsValid()) {
347 suppressStreaming(); 344 suppressStreaming();
348 blink::Platform::current()->histogramEnumeration(histogramName, 0, 2 ); 345 blink::Platform::current()->histogramEnumeration(histogramName, 0, 2 );
349 return; 346 return;
350 } 347 }
351 348
352 ASSERT(!m_stream); 349 ASSERT(!m_stream);
353 ASSERT(!m_source); 350 ASSERT(!m_source);
354 m_stream = new SourceStream(this); 351 m_stream = new SourceStream();
355 // m_source takes ownership of m_stream. 352 // m_source takes ownership of m_stream.
356 m_source = adoptPtr(new v8::ScriptCompiler::StreamedSource(m_stream, m_e ncoding)); 353 m_source = adoptPtr(new v8::ScriptCompiler::StreamedSource(m_stream, m_e ncoding));
357 354
358 ScriptState::Scope scope(m_scriptState.get()); 355 ScriptState::Scope scope(m_scriptState.get());
359 WTF::OwnPtr<v8::ScriptCompiler::ScriptStreamingTask> scriptStreamingTask (adoptPtr(v8::ScriptCompiler::StartStreamingScript(m_scriptState->isolate(), m_s ource.get(), m_compileOptions))); 356 WTF::OwnPtr<v8::ScriptCompiler::ScriptStreamingTask> scriptStreamingTask (adoptPtr(v8::ScriptCompiler::StartStreamingScript(m_scriptState->isolate(), m_s ource.get(), m_compileOptions)));
360 if (!scriptStreamingTask) { 357 if (!scriptStreamingTask) {
361 // V8 cannot stream the script. 358 // V8 cannot stream the script.
362 suppressStreaming(); 359 suppressStreaming();
363 m_stream = 0; 360 m_stream = 0;
364 m_source.clear(); 361 m_source.clear();
365 blink::Platform::current()->histogramEnumeration(histogramName, 0, 2 ); 362 blink::Platform::current()->histogramEnumeration(histogramName, 0, 2 );
366 return; 363 return;
367 } 364 }
368 365
369 // ScriptStreamer needs to stay alive as long as the background task is 366 // ScriptStreamer needs to stay alive as long as the background task is
370 // running. This is taken care of with a manual ref() & deref() pair; 367 // running. This is taken care of with a manual ref() & deref() pair;
371 // the corresponding deref() is in streamingComplete or in 368 // the corresponding deref() is in streamingComplete or in
372 // notifyFinished. 369 // notifyFinished.
373 ref(); 370 ref();
374 ScriptStreamingTask* task = new ScriptStreamingTask(scriptStreamingTask. release(), this); 371 ScriptStreamingTask* task = new ScriptStreamingTask(scriptStreamingTask. release(), this);
375 ScriptStreamerThread::shared()->postTask(task); 372 ScriptStreamerThread::shared()->postTask(task);
376 blink::Platform::current()->histogramEnumeration(histogramName, 1, 2); 373 blink::Platform::current()->histogramEnumeration(histogramName, 1, 2);
377 } 374 }
378 if (m_stream) 375 if (m_stream)
379 m_stream->didReceiveData(lengthOfBOM); 376 m_stream->didReceiveData(this, lengthOfBOM);
380 } 377 }
381 378
382 void ScriptStreamer::notifyFinished(Resource* resource) 379 void ScriptStreamer::notifyFinished(Resource* resource)
383 { 380 {
384 ASSERT(isMainThread()); 381 ASSERT(isMainThread());
385 ASSERT(m_resource == resource); 382 ASSERT(m_resource == resource);
386 // A special case: empty and small scripts. We didn't receive enough data to 383 // A special case: empty and small scripts. We didn't receive enough data to
387 // start the streaming before this notification. In that case, there won't 384 // start the streaming before this notification. In that case, there won't
388 // be a "parsing complete" notification either, and we should not wait for 385 // be a "parsing complete" notification either, and we should not wait for
389 // it. 386 // it.
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 543
547 // The Resource might go out of scope if the script is no longer 544 // The Resource might go out of scope if the script is no longer
548 // needed. This makes PendingScript notify the ScriptStreamer when it is 545 // needed. This makes PendingScript notify the ScriptStreamer when it is
549 // destroyed. 546 // destroyed.
550 script.setStreamer(adoptRef(new ScriptStreamer(resource, scriptType, setting s->v8ScriptStreamingMode(), scriptState, compileOption))); 547 script.setStreamer(adoptRef(new ScriptStreamer(resource, scriptType, setting s->v8ScriptStreamingMode(), scriptState, compileOption)));
551 548
552 return true; 549 return true;
553 } 550 }
554 551
555 } // namespace blink 552 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698