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

Side by Side Diff: test/cctest/test-thread-termination.cc

Issue 12729023: first step to remove unsafe handles (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: issue with debug build Created 7 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « test/cctest/test-symbols.cc ('k') | test/cctest/test-threads.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 // TODO(dcarney): remove
29 #define V8_ALLOW_ACCESS_TO_PERSISTENT_IMPLICIT
30 #define V8_ALLOW_ACCESS_TO_PERSISTENT_ARROW
31
28 #include "v8.h" 32 #include "v8.h"
29 #include "platform.h" 33 #include "platform.h"
30 #include "cctest.h" 34 #include "cctest.h"
31 35
32 36
33 v8::internal::Semaphore* semaphore = NULL; 37 v8::internal::Semaphore* semaphore = NULL;
34 38
35 39
36 v8::Handle<v8::Value> Signal(const v8::Arguments& args) { 40 v8::Handle<v8::Value> Signal(const v8::Arguments& args) {
37 semaphore->Signal(); 41 semaphore->Signal();
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 return global; 121 return global;
118 } 122 }
119 123
120 124
121 // Test that a single thread of JavaScript execution can terminate 125 // Test that a single thread of JavaScript execution can terminate
122 // itself. 126 // itself.
123 TEST(TerminateOnlyV8ThreadFromThreadItself) { 127 TEST(TerminateOnlyV8ThreadFromThreadItself) {
124 v8::HandleScope scope(v8::Isolate::GetCurrent()); 128 v8::HandleScope scope(v8::Isolate::GetCurrent());
125 v8::Handle<v8::ObjectTemplate> global = 129 v8::Handle<v8::ObjectTemplate> global =
126 CreateGlobalTemplate(TerminateCurrentThread, DoLoop); 130 CreateGlobalTemplate(TerminateCurrentThread, DoLoop);
127 v8::Persistent<v8::Context> context = v8::Context::New(NULL, global); 131 v8::Handle<v8::Context> context =
132 v8::Context::New(v8::Isolate::GetCurrent(), NULL, global);
128 v8::Context::Scope context_scope(context); 133 v8::Context::Scope context_scope(context);
129 CHECK(!v8::V8::IsExecutionTerminating()); 134 CHECK(!v8::V8::IsExecutionTerminating());
130 // Run a loop that will be infinite if thread termination does not work. 135 // Run a loop that will be infinite if thread termination does not work.
131 v8::Handle<v8::String> source = 136 v8::Handle<v8::String> source =
132 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); 137 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }");
133 v8::Script::Compile(source)->Run(); 138 v8::Script::Compile(source)->Run();
134 // Test that we can run the code again after thread termination. 139 // Test that we can run the code again after thread termination.
135 CHECK(!v8::V8::IsExecutionTerminating()); 140 CHECK(!v8::V8::IsExecutionTerminating());
136 v8::Script::Compile(source)->Run(); 141 v8::Script::Compile(source)->Run();
137 context.Dispose(context->GetIsolate());
138 } 142 }
139 143
140 144
141 // Test that a single thread of JavaScript execution can terminate 145 // Test that a single thread of JavaScript execution can terminate
142 // itself in a loop that performs no calls. 146 // itself in a loop that performs no calls.
143 TEST(TerminateOnlyV8ThreadFromThreadItselfNoLoop) { 147 TEST(TerminateOnlyV8ThreadFromThreadItselfNoLoop) {
144 v8::HandleScope scope(v8::Isolate::GetCurrent()); 148 v8::HandleScope scope(v8::Isolate::GetCurrent());
145 v8::Handle<v8::ObjectTemplate> global = 149 v8::Handle<v8::ObjectTemplate> global =
146 CreateGlobalTemplate(TerminateCurrentThread, DoLoopNoCall); 150 CreateGlobalTemplate(TerminateCurrentThread, DoLoopNoCall);
147 v8::Persistent<v8::Context> context = v8::Context::New(NULL, global); 151 v8::Handle<v8::Context> context =
152 v8::Context::New(v8::Isolate::GetCurrent(), NULL, global);
148 v8::Context::Scope context_scope(context); 153 v8::Context::Scope context_scope(context);
149 CHECK(!v8::V8::IsExecutionTerminating()); 154 CHECK(!v8::V8::IsExecutionTerminating());
150 // Run a loop that will be infinite if thread termination does not work. 155 // Run a loop that will be infinite if thread termination does not work.
151 v8::Handle<v8::String> source = 156 v8::Handle<v8::String> source =
152 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); 157 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }");
153 v8::Script::Compile(source)->Run(); 158 v8::Script::Compile(source)->Run();
154 CHECK(!v8::V8::IsExecutionTerminating()); 159 CHECK(!v8::V8::IsExecutionTerminating());
155 // Test that we can run the code again after thread termination. 160 // Test that we can run the code again after thread termination.
156 v8::Script::Compile(source)->Run(); 161 v8::Script::Compile(source)->Run();
157 context.Dispose(context->GetIsolate());
158 } 162 }
159 163
160 164
161 class TerminatorThread : public v8::internal::Thread { 165 class TerminatorThread : public v8::internal::Thread {
162 public: 166 public:
163 explicit TerminatorThread(i::Isolate* isolate) 167 explicit TerminatorThread(i::Isolate* isolate)
164 : Thread("TerminatorThread"), 168 : Thread("TerminatorThread"),
165 isolate_(reinterpret_cast<v8::Isolate*>(isolate)) { } 169 isolate_(reinterpret_cast<v8::Isolate*>(isolate)) { }
166 void Run() { 170 void Run() {
167 semaphore->Wait(); 171 semaphore->Wait();
168 CHECK(!v8::V8::IsExecutionTerminating(isolate_)); 172 CHECK(!v8::V8::IsExecutionTerminating(isolate_));
169 v8::V8::TerminateExecution(isolate_); 173 v8::V8::TerminateExecution(isolate_);
170 } 174 }
171 175
172 private: 176 private:
173 v8::Isolate* isolate_; 177 v8::Isolate* isolate_;
174 }; 178 };
175 179
176 180
177 // Test that a single thread of JavaScript execution can be terminated 181 // Test that a single thread of JavaScript execution can be terminated
178 // from the side by another thread. 182 // from the side by another thread.
179 TEST(TerminateOnlyV8ThreadFromOtherThread) { 183 TEST(TerminateOnlyV8ThreadFromOtherThread) {
180 semaphore = v8::internal::OS::CreateSemaphore(0); 184 semaphore = v8::internal::OS::CreateSemaphore(0);
181 TerminatorThread thread(i::Isolate::Current()); 185 TerminatorThread thread(i::Isolate::Current());
182 thread.Start(); 186 thread.Start();
183 187
184 v8::HandleScope scope(v8::Isolate::GetCurrent()); 188 v8::HandleScope scope(v8::Isolate::GetCurrent());
185 v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate(Signal, DoLoop); 189 v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate(Signal, DoLoop);
186 v8::Persistent<v8::Context> context = v8::Context::New(NULL, global); 190 v8::Handle<v8::Context> context =
191 v8::Context::New(v8::Isolate::GetCurrent(), NULL, global);
187 v8::Context::Scope context_scope(context); 192 v8::Context::Scope context_scope(context);
188 CHECK(!v8::V8::IsExecutionTerminating()); 193 CHECK(!v8::V8::IsExecutionTerminating());
189 // Run a loop that will be infinite if thread termination does not work. 194 // Run a loop that will be infinite if thread termination does not work.
190 v8::Handle<v8::String> source = 195 v8::Handle<v8::String> source =
191 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); 196 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }");
192 v8::Script::Compile(source)->Run(); 197 v8::Script::Compile(source)->Run();
193 198
194 thread.Join(); 199 thread.Join();
195 delete semaphore; 200 delete semaphore;
196 semaphore = NULL; 201 semaphore = NULL;
197 context.Dispose(context->GetIsolate());
198 } 202 }
199 203
200 204
201 class LoopingThread : public v8::internal::Thread { 205 class LoopingThread : public v8::internal::Thread {
202 public: 206 public:
203 LoopingThread() : Thread("LoopingThread") { } 207 LoopingThread() : Thread("LoopingThread") { }
204 void Run() { 208 void Run() {
205 v8::Locker locker(CcTest::default_isolate()); 209 v8::Locker locker(CcTest::default_isolate());
206 v8::HandleScope scope(CcTest::default_isolate()); 210 v8::HandleScope scope(CcTest::default_isolate());
207 v8_thread_id_ = v8::V8::GetCurrentThreadId(); 211 v8_thread_id_ = v8::V8::GetCurrentThreadId();
208 v8::Handle<v8::ObjectTemplate> global = 212 v8::Handle<v8::ObjectTemplate> global =
209 CreateGlobalTemplate(Signal, DoLoop); 213 CreateGlobalTemplate(Signal, DoLoop);
210 v8::Persistent<v8::Context> context = v8::Context::New(NULL, global); 214 v8::Handle<v8::Context> context =
215 v8::Context::New(v8::Isolate::GetCurrent(), NULL, global);
211 v8::Context::Scope context_scope(context); 216 v8::Context::Scope context_scope(context);
212 CHECK(!v8::V8::IsExecutionTerminating()); 217 CHECK(!v8::V8::IsExecutionTerminating());
213 // Run a loop that will be infinite if thread termination does not work. 218 // Run a loop that will be infinite if thread termination does not work.
214 v8::Handle<v8::String> source = 219 v8::Handle<v8::String> source =
215 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); 220 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }");
216 v8::Script::Compile(source)->Run(); 221 v8::Script::Compile(source)->Run();
217 context.Dispose(context->GetIsolate());
218 } 222 }
219 223
220 int GetV8ThreadId() { return v8_thread_id_; } 224 int GetV8ThreadId() { return v8_thread_id_; }
221 225
222 private: 226 private:
223 int v8_thread_id_; 227 int v8_thread_id_;
224 }; 228 };
225 229
226 230
227 // Test that multiple threads using default isolate can be terminated 231 // Test that multiple threads using default isolate can be terminated
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 // triggered by the creation of error objects in connection with ICs. 311 // triggered by the creation of error objects in connection with ICs.
308 TEST(TerminateLoadICException) { 312 TEST(TerminateLoadICException) {
309 v8::HandleScope scope(v8::Isolate::GetCurrent()); 313 v8::HandleScope scope(v8::Isolate::GetCurrent());
310 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); 314 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
311 global->Set(v8::String::New("terminate_or_return_object"), 315 global->Set(v8::String::New("terminate_or_return_object"),
312 v8::FunctionTemplate::New(TerminateOrReturnObject)); 316 v8::FunctionTemplate::New(TerminateOrReturnObject));
313 global->Set(v8::String::New("fail"), v8::FunctionTemplate::New(Fail)); 317 global->Set(v8::String::New("fail"), v8::FunctionTemplate::New(Fail));
314 global->Set(v8::String::New("loop"), 318 global->Set(v8::String::New("loop"),
315 v8::FunctionTemplate::New(LoopGetProperty)); 319 v8::FunctionTemplate::New(LoopGetProperty));
316 320
317 v8::Persistent<v8::Context> context = v8::Context::New(NULL, global); 321 v8::Handle<v8::Context> context =
322 v8::Context::New(v8::Isolate::GetCurrent(), NULL, global);
318 v8::Context::Scope context_scope(context); 323 v8::Context::Scope context_scope(context);
319 CHECK(!v8::V8::IsExecutionTerminating()); 324 CHECK(!v8::V8::IsExecutionTerminating());
320 // Run a loop that will be infinite if thread termination does not work. 325 // Run a loop that will be infinite if thread termination does not work.
321 v8::Handle<v8::String> source = 326 v8::Handle<v8::String> source =
322 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); 327 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }");
323 call_count = 0; 328 call_count = 0;
324 v8::Script::Compile(source)->Run(); 329 v8::Script::Compile(source)->Run();
325 // Test that we can run the code again after thread termination. 330 // Test that we can run the code again after thread termination.
326 CHECK(!v8::V8::IsExecutionTerminating()); 331 CHECK(!v8::V8::IsExecutionTerminating());
327 call_count = 0; 332 call_count = 0;
328 v8::Script::Compile(source)->Run(); 333 v8::Script::Compile(source)->Run();
329 context.Dispose(context->GetIsolate());
330 } 334 }
331 335
332 v8::Handle<v8::Value> ReenterAfterTermination(const v8::Arguments& args) { 336 v8::Handle<v8::Value> ReenterAfterTermination(const v8::Arguments& args) {
333 v8::TryCatch try_catch; 337 v8::TryCatch try_catch;
334 CHECK(!v8::V8::IsExecutionTerminating()); 338 CHECK(!v8::V8::IsExecutionTerminating());
335 v8::Script::Compile(v8::String::New("function f() {" 339 v8::Script::Compile(v8::String::New("function f() {"
336 " var term = true;" 340 " var term = true;"
337 " try {" 341 " try {"
338 " while(true) {" 342 " while(true) {"
339 " if (term) terminate();" 343 " if (term) terminate();"
(...skipping 13 matching lines...) Expand all
353 v8::Script::Compile(v8::String::New("function f() { fail(); } f()"))->Run(); 357 v8::Script::Compile(v8::String::New("function f() { fail(); } f()"))->Run();
354 return v8::Undefined(); 358 return v8::Undefined();
355 } 359 }
356 360
357 // Test that reentry into V8 while the termination exception is still pending 361 // Test that reentry into V8 while the termination exception is still pending
358 // (has not yet unwound the 0-level JS frame) does not crash. 362 // (has not yet unwound the 0-level JS frame) does not crash.
359 TEST(TerminateAndReenterFromThreadItself) { 363 TEST(TerminateAndReenterFromThreadItself) {
360 v8::HandleScope scope(v8::Isolate::GetCurrent()); 364 v8::HandleScope scope(v8::Isolate::GetCurrent());
361 v8::Handle<v8::ObjectTemplate> global = 365 v8::Handle<v8::ObjectTemplate> global =
362 CreateGlobalTemplate(TerminateCurrentThread, ReenterAfterTermination); 366 CreateGlobalTemplate(TerminateCurrentThread, ReenterAfterTermination);
363 v8::Persistent<v8::Context> context = v8::Context::New(NULL, global); 367 v8::Handle<v8::Context> context =
368 v8::Context::New(v8::Isolate::GetCurrent(), NULL, global);
364 v8::Context::Scope context_scope(context); 369 v8::Context::Scope context_scope(context);
365 CHECK(!v8::V8::IsExecutionTerminating()); 370 CHECK(!v8::V8::IsExecutionTerminating());
366 v8::Handle<v8::String> source = 371 v8::Handle<v8::String> source =
367 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); 372 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }");
368 v8::Script::Compile(source)->Run(); 373 v8::Script::Compile(source)->Run();
369 CHECK(!v8::V8::IsExecutionTerminating()); 374 CHECK(!v8::V8::IsExecutionTerminating());
370 // Check we can run JS again after termination. 375 // Check we can run JS again after termination.
371 CHECK(v8::Script::Compile(v8::String::New("function f() { return true; }" 376 CHECK(v8::Script::Compile(v8::String::New("function f() { return true; }"
372 "f()"))->Run()->IsTrue()); 377 "f()"))->Run()->IsTrue());
373 context.Dispose(context->GetIsolate());
374 } 378 }
375 379
376 v8::Handle<v8::Value> DoLoopCancelTerminate(const v8::Arguments& args) { 380 v8::Handle<v8::Value> DoLoopCancelTerminate(const v8::Arguments& args) {
377 v8::TryCatch try_catch; 381 v8::TryCatch try_catch;
378 CHECK(!v8::V8::IsExecutionTerminating()); 382 CHECK(!v8::V8::IsExecutionTerminating());
379 v8::Script::Compile(v8::String::New("var term = true;" 383 v8::Script::Compile(v8::String::New("var term = true;"
380 "while(true) {" 384 "while(true) {"
381 " if (term) terminate();" 385 " if (term) terminate();"
382 " term = false;" 386 " term = false;"
383 "}" 387 "}"
384 "fail();"))->Run(); 388 "fail();"))->Run();
385 CHECK(try_catch.HasCaught()); 389 CHECK(try_catch.HasCaught());
386 CHECK(try_catch.Exception()->IsNull()); 390 CHECK(try_catch.Exception()->IsNull());
387 CHECK(try_catch.Message().IsEmpty()); 391 CHECK(try_catch.Message().IsEmpty());
388 CHECK(!try_catch.CanContinue()); 392 CHECK(!try_catch.CanContinue());
389 CHECK(v8::V8::IsExecutionTerminating()); 393 CHECK(v8::V8::IsExecutionTerminating());
390 CHECK(try_catch.HasTerminated()); 394 CHECK(try_catch.HasTerminated());
391 v8::V8::CancelTerminateExecution(v8::Isolate::GetCurrent()); 395 v8::V8::CancelTerminateExecution(v8::Isolate::GetCurrent());
392 CHECK(!v8::V8::IsExecutionTerminating()); 396 CHECK(!v8::V8::IsExecutionTerminating());
393 return v8::Undefined(); 397 return v8::Undefined();
394 } 398 }
395 399
396 // Test that a single thread of JavaScript execution can terminate 400 // Test that a single thread of JavaScript execution can terminate
397 // itself and then resume execution. 401 // itself and then resume execution.
398 TEST(TerminateCancelTerminateFromThreadItself) { 402 TEST(TerminateCancelTerminateFromThreadItself) {
399 v8::HandleScope scope; 403 v8::HandleScope scope;
400 v8::Handle<v8::ObjectTemplate> global = 404 v8::Handle<v8::ObjectTemplate> global =
401 CreateGlobalTemplate(TerminateCurrentThread, DoLoopCancelTerminate); 405 CreateGlobalTemplate(TerminateCurrentThread, DoLoopCancelTerminate);
402 v8::Persistent<v8::Context> context = v8::Context::New(NULL, global); 406 v8::Handle<v8::Context> context =
407 v8::Context::New(v8::Isolate::GetCurrent(), NULL, global);
403 v8::Context::Scope context_scope(context); 408 v8::Context::Scope context_scope(context);
404 CHECK(!v8::V8::IsExecutionTerminating()); 409 CHECK(!v8::V8::IsExecutionTerminating());
405 v8::Handle<v8::String> source = 410 v8::Handle<v8::String> source =
406 v8::String::New("try { doloop(); } catch(e) { fail(); } 'completed';"); 411 v8::String::New("try { doloop(); } catch(e) { fail(); } 'completed';");
407 // Check that execution completed with correct return value. 412 // Check that execution completed with correct return value.
408 CHECK(v8::Script::Compile(source)->Run()->Equals(v8_str("completed"))); 413 CHECK(v8::Script::Compile(source)->Run()->Equals(v8_str("completed")));
409 context.Dispose(context->GetIsolate());
410 } 414 }
411 415
OLDNEW
« no previous file with comments | « test/cctest/test-symbols.cc ('k') | test/cctest/test-threads.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698