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

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

Issue 576853003: Oilpan: have ScriptStreamingTest correctly trace its PendingScript. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 3 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 5
6 #include "config.h" 6 #include "config.h"
7 #include "bindings/core/v8/ScriptStreamer.h" 7 #include "bindings/core/v8/ScriptStreamer.h"
8 8
9 #include "bindings/core/v8/ScriptStreamerThread.h" 9 #include "bindings/core/v8/ScriptStreamerThread.h"
10 #include "bindings/core/v8/V8Binding.h" 10 #include "bindings/core/v8/V8Binding.h"
11 #include "bindings/core/v8/V8ScriptRunner.h" 11 #include "bindings/core/v8/V8ScriptRunner.h"
12 #include "core/dom/PendingScript.h" 12 #include "core/dom/PendingScript.h"
13 #include "core/frame/Settings.h" 13 #include "core/frame/Settings.h"
14 #include "platform/Task.h" 14 #include "platform/Task.h"
15 #include "platform/heap/Handle.h"
15 #include "public/platform/Platform.h" 16 #include "public/platform/Platform.h"
16 17
17 #include <gtest/gtest.h> 18 #include <gtest/gtest.h>
18 #include <v8.h> 19 #include <v8.h>
19 20
20 namespace blink { 21 namespace blink {
21 22
22 namespace { 23 namespace {
23 24
25 // For the benefit of Oilpan, put the part object PendingScript inside
26 // a wrapper that's on the Oilpan heap and hold a reference to that wrapper
27 // from ScriptStreamingTest.
28 class PendingScriptWrapper : public NoBaseWillBeGarbageCollectedFinalized<Pendin gScriptWrapper> {
29 public:
30 static PassOwnPtrWillBeRawPtr<PendingScriptWrapper> create()
31 {
32 return adoptPtrWillBeNoop(new PendingScriptWrapper());
33 }
34
35 static PassOwnPtrWillBeRawPtr<PendingScriptWrapper> create(Element* element, ScriptResource* resource)
36 {
37 return adoptPtrWillBeNoop(new PendingScriptWrapper(element, resource));
38 }
39
40 PendingScript& get() { return m_pendingScript; }
41
42 void trace(Visitor* visitor)
43 {
44 visitor->trace(m_pendingScript);
45 }
46
47 private:
48 PendingScriptWrapper()
49 {
50 }
51
52 PendingScriptWrapper(Element* element, ScriptResource* resource)
53 : m_pendingScript(PendingScript(element, resource))
54 {
55 }
56
57 PendingScript m_pendingScript;
58 };
59
24 class ScriptStreamingTest : public testing::Test { 60 class ScriptStreamingTest : public testing::Test {
25 public: 61 public:
26 ScriptStreamingTest() 62 ScriptStreamingTest()
27 : m_scope(v8::Isolate::GetCurrent()) 63 : m_scope(v8::Isolate::GetCurrent())
28 , m_settings(Settings::create()) 64 , m_settings(Settings::create())
29 , m_resourceRequest("http://www.streaming-test.com/") 65 , m_resourceRequest("http://www.streaming-test.com/")
30 , m_resource(new ScriptResource(m_resourceRequest, "text/utf-8")) 66 , m_resource(new ScriptResource(m_resourceRequest, "text/utf-8"))
31 , m_pendingScript(0, m_resource) // Takes ownership of m_resource. 67 , m_pendingScript(PendingScriptWrapper::create(0, m_resource)) // Takes ownership of m_resource.
32 { 68 {
33 m_settings->setV8ScriptStreamingEnabled(true); 69 m_settings->setV8ScriptStreamingEnabled(true);
34 m_resource->setLoading(true); 70 m_resource->setLoading(true);
35 } 71 }
36 72
37 ScriptState* scriptState() const { return m_scope.scriptState(); } 73 ScriptState* scriptState() const { return m_scope.scriptState(); }
38 v8::Isolate* isolate() const { return m_scope.isolate(); } 74 v8::Isolate* isolate() const { return m_scope.isolate(); }
39 75
40 void trace(Visitor* visitor) 76 PendingScript& pendingScript() const { return m_pendingScript->get(); }
41 {
42 visitor->trace(m_pendingScript);
43 }
44 77
45 protected: 78 protected:
46 void appendData(const char* data) 79 void appendData(const char* data)
47 { 80 {
48 m_resource->appendData(data, strlen(data)); 81 m_resource->appendData(data, strlen(data));
49 // Yield control to the background thread, so that V8 gets a change to 82 // Yield control to the background thread, so that V8 gets a change to
50 // process the data before the main thread adds more. Note that we 83 // process the data before the main thread adds more. Note that we
51 // cannot fully control in what kind of chunks the data is passed to V8 84 // cannot fully control in what kind of chunks the data is passed to V8
52 // (if the V8 is not requesting more data between two appendData calls, 85 // (if the V8 is not requesting more data between two appendData calls,
53 // V8 will get both chunks together). 86 // V8 will get both chunks together).
(...skipping 24 matching lines...) Expand all
78 } 111 }
79 } 112 }
80 113
81 V8TestingScope m_scope; 114 V8TestingScope m_scope;
82 OwnPtr<Settings> m_settings; 115 OwnPtr<Settings> m_settings;
83 // The Resource and PendingScript where we stream from. These don't really 116 // The Resource and PendingScript where we stream from. These don't really
84 // fetch any data outside the test; the test controls the data by calling 117 // fetch any data outside the test; the test controls the data by calling
85 // ScriptResource::appendData. 118 // ScriptResource::appendData.
86 ResourceRequest m_resourceRequest; 119 ResourceRequest m_resourceRequest;
87 ScriptResource* m_resource; 120 ScriptResource* m_resource;
88 PendingScript m_pendingScript; 121 OwnPtrWillBePersistent<PendingScriptWrapper> m_pendingScript;
89 }; 122 };
90 123
91 class TestScriptResourceClient : public ScriptResourceClient { 124 class TestScriptResourceClient : public ScriptResourceClient {
92 public: 125 public:
93 TestScriptResourceClient() 126 TestScriptResourceClient()
94 : m_finished(false) { } 127 : m_finished(false) { }
95 128
96 virtual void notifyFinished(Resource*) OVERRIDE { m_finished = true; } 129 virtual void notifyFinished(Resource*) OVERRIDE { m_finished = true; }
97 130
98 bool finished() const { return m_finished; } 131 bool finished() const { return m_finished; }
99 132
100 private: 133 private:
101 bool m_finished; 134 bool m_finished;
102 }; 135 };
103 136
104 TEST_F(ScriptStreamingTest, CompilingStreamedScript) 137 TEST_F(ScriptStreamingTest, CompilingStreamedScript)
105 { 138 {
106 // Test that we can successfully compile a streamed script. 139 // Test that we can successfully compile a streamed script.
107 bool started = ScriptStreamer::startStreaming(m_pendingScript, m_settings.ge t(), m_scope.scriptState()); 140 bool started = ScriptStreamer::startStreaming(pendingScript(), m_settings.ge t(), m_scope.scriptState());
108 TestScriptResourceClient client; 141 TestScriptResourceClient client;
109 m_pendingScript.watchForLoad(&client); 142 pendingScript().watchForLoad(&client);
110 EXPECT_TRUE(started); 143 EXPECT_TRUE(started);
111 144
112 appendData("function foo() {"); 145 appendData("function foo() {");
113 appendPadding(); 146 appendPadding();
114 appendData("return 5; }"); 147 appendData("return 5; }");
115 appendPadding(); 148 appendPadding();
116 appendData("foo();"); 149 appendData("foo();");
117 EXPECT_FALSE(client.finished()); 150 EXPECT_FALSE(client.finished());
118 finish(); 151 finish();
119 152
120 // Process tasks on the main thread until the streaming background thread 153 // Process tasks on the main thread until the streaming background thread
121 // has completed its tasks. 154 // has completed its tasks.
122 processTasksUntilStreamingComplete(); 155 processTasksUntilStreamingComplete();
123 EXPECT_TRUE(client.finished()); 156 EXPECT_TRUE(client.finished());
124 bool errorOccurred = false; 157 bool errorOccurred = false;
125 ScriptSourceCode sourceCode = m_pendingScript.getSource(KURL(), errorOccurre d); 158 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d);
126 EXPECT_FALSE(errorOccurred); 159 EXPECT_FALSE(errorOccurred);
127 EXPECT_TRUE(sourceCode.streamer()); 160 EXPECT_TRUE(sourceCode.streamer());
128 v8::TryCatch tryCatch; 161 v8::TryCatch tryCatch;
129 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(sourceCode, is olate()); 162 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(sourceCode, is olate());
130 EXPECT_FALSE(script.IsEmpty()); 163 EXPECT_FALSE(script.IsEmpty());
131 EXPECT_FALSE(tryCatch.HasCaught()); 164 EXPECT_FALSE(tryCatch.HasCaught());
132 } 165 }
133 166
134 TEST_F(ScriptStreamingTest, CompilingStreamedScriptWithParseError) 167 TEST_F(ScriptStreamingTest, CompilingStreamedScriptWithParseError)
135 { 168 {
136 // Test that scripts with parse errors are handled properly. In those cases, 169 // Test that scripts with parse errors are handled properly. In those cases,
137 // the V8 side typically finished before loading finishes: make sure we 170 // the V8 side typically finished before loading finishes: make sure we
138 // handle it gracefully. 171 // handle it gracefully.
139 bool started = ScriptStreamer::startStreaming(m_pendingScript, m_settings.ge t(), m_scope.scriptState()); 172 bool started = ScriptStreamer::startStreaming(pendingScript(), m_settings.ge t(), m_scope.scriptState());
140 TestScriptResourceClient client; 173 TestScriptResourceClient client;
141 m_pendingScript.watchForLoad(&client); 174 pendingScript().watchForLoad(&client);
142 EXPECT_TRUE(started); 175 EXPECT_TRUE(started);
143 appendData("function foo() {"); 176 appendData("function foo() {");
144 appendData("this is the part which will be a parse error"); 177 appendData("this is the part which will be a parse error");
145 // V8 won't realize the parse error until it actually starts parsing the 178 // V8 won't realize the parse error until it actually starts parsing the
146 // script, and this happens only when its buffer is filled. 179 // script, and this happens only when its buffer is filled.
147 appendPadding(); 180 appendPadding();
148 181
149 EXPECT_FALSE(client.finished()); 182 EXPECT_FALSE(client.finished());
150 183
151 // Force the V8 side to finish before the loading. 184 // Force the V8 side to finish before the loading.
152 processTasksUntilStreamingComplete(); 185 processTasksUntilStreamingComplete();
153 EXPECT_FALSE(client.finished()); 186 EXPECT_FALSE(client.finished());
154 187
155 finish(); 188 finish();
156 EXPECT_TRUE(client.finished()); 189 EXPECT_TRUE(client.finished());
157 190
158 bool errorOccurred = false; 191 bool errorOccurred = false;
159 ScriptSourceCode sourceCode = m_pendingScript.getSource(KURL(), errorOccurre d); 192 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d);
160 EXPECT_FALSE(errorOccurred); 193 EXPECT_FALSE(errorOccurred);
161 EXPECT_TRUE(sourceCode.streamer()); 194 EXPECT_TRUE(sourceCode.streamer());
162 v8::TryCatch tryCatch; 195 v8::TryCatch tryCatch;
163 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(sourceCode, is olate()); 196 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(sourceCode, is olate());
164 EXPECT_TRUE(script.IsEmpty()); 197 EXPECT_TRUE(script.IsEmpty());
165 EXPECT_TRUE(tryCatch.HasCaught()); 198 EXPECT_TRUE(tryCatch.HasCaught());
166 } 199 }
167 200
168 TEST_F(ScriptStreamingTest, CancellingStreaming) 201 TEST_F(ScriptStreamingTest, CancellingStreaming)
169 { 202 {
170 // Test that the upper layers (PendingScript and up) can be ramped down 203 // Test that the upper layers (PendingScript and up) can be ramped down
171 // while streaming is ongoing, and ScriptStreamer handles it gracefully. 204 // while streaming is ongoing, and ScriptStreamer handles it gracefully.
172 bool started = ScriptStreamer::startStreaming(m_pendingScript, m_settings.ge t(), m_scope.scriptState()); 205 bool started = ScriptStreamer::startStreaming(pendingScript(), m_settings.ge t(), m_scope.scriptState());
173 TestScriptResourceClient client; 206 TestScriptResourceClient client;
174 m_pendingScript.watchForLoad(&client); 207 pendingScript().watchForLoad(&client);
175 EXPECT_TRUE(started); 208 EXPECT_TRUE(started);
176 appendData("function foo() {"); 209 appendData("function foo() {");
177 210
178 // In general, we cannot control what the background thread is doing 211 // In general, we cannot control what the background thread is doing
179 // (whether it's parsing or waiting for more data). In this test, we have 212 // (whether it's parsing or waiting for more data). In this test, we have
180 // given it so little data that it's surely waiting for more. 213 // given it so little data that it's surely waiting for more.
181 214
182 // Simulate cancelling the network load (e.g., because the user navigated 215 // Simulate cancelling the network load (e.g., because the user navigated
183 // away). 216 // away).
184 EXPECT_FALSE(client.finished()); 217 EXPECT_FALSE(client.finished());
185 m_pendingScript.stopWatchingForLoad(&client); 218 pendingScript().stopWatchingForLoad(&client);
186 m_pendingScript = PendingScript(); // This will destroy m_resource. 219 m_pendingScript = PendingScriptWrapper::create(); // This will destroy m_res ource.
187 m_resource = 0; 220 m_resource = 0;
188 221
189 // The V8 side will complete too. This should not crash. We don't receive 222 // The V8 side will complete too. This should not crash. We don't receive
190 // any results from the streaming and the client doesn't get notified. 223 // any results from the streaming and the client doesn't get notified.
191 processTasksUntilStreamingComplete(); 224 processTasksUntilStreamingComplete();
192 EXPECT_FALSE(client.finished()); 225 EXPECT_FALSE(client.finished());
193 } 226 }
194 227
195 TEST_F(ScriptStreamingTest, SuppressingStreaming) 228 TEST_F(ScriptStreamingTest, SuppressingStreaming)
196 { 229 {
197 // If we notice during streaming that there is a code cache, streaming 230 // If we notice during streaming that there is a code cache, streaming
198 // is suppressed (V8 doesn't parse while the script is loading), and the 231 // is suppressed (V8 doesn't parse while the script is loading), and the
199 // upper layer (ScriptResourceClient) should get a notification when the 232 // upper layer (ScriptResourceClient) should get a notification when the
200 // script is loaded. 233 // script is loaded.
201 bool started = ScriptStreamer::startStreaming(m_pendingScript, m_settings.ge t(), m_scope.scriptState()); 234 bool started = ScriptStreamer::startStreaming(pendingScript(), m_settings.ge t(), m_scope.scriptState());
202 TestScriptResourceClient client; 235 TestScriptResourceClient client;
203 m_pendingScript.watchForLoad(&client); 236 pendingScript().watchForLoad(&client);
204 EXPECT_TRUE(started); 237 EXPECT_TRUE(started);
205 appendData("function foo() {"); 238 appendData("function foo() {");
206 appendPadding(); 239 appendPadding();
207 240
208 m_resource->setCachedMetadata(V8ScriptRunner::tagForCodeCache(), "X", 1, Res ource::CacheLocally); 241 m_resource->setCachedMetadata(V8ScriptRunner::tagForCodeCache(), "X", 1, Res ource::CacheLocally);
209 242
210 appendPadding(); 243 appendPadding();
211 finish(); 244 finish();
212 processTasksUntilStreamingComplete(); 245 processTasksUntilStreamingComplete();
213 EXPECT_TRUE(client.finished()); 246 EXPECT_TRUE(client.finished());
214 247
215 bool errorOccurred = false; 248 bool errorOccurred = false;
216 ScriptSourceCode sourceCode = m_pendingScript.getSource(KURL(), errorOccurre d); 249 ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurre d);
217 EXPECT_FALSE(errorOccurred); 250 EXPECT_FALSE(errorOccurred);
218 // ScriptSourceCode doesn't refer to the streamer, since we have suppressed 251 // ScriptSourceCode doesn't refer to the streamer, since we have suppressed
219 // the streaming and resumed the non-streaming code path for script 252 // the streaming and resumed the non-streaming code path for script
220 // compilation. 253 // compilation.
221 EXPECT_FALSE(sourceCode.streamer()); 254 EXPECT_FALSE(sourceCode.streamer());
222 } 255 }
223 256
224 } // namespace 257 } // namespace
225 258
226 } // namespace blink 259 } // 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