diff options
Diffstat (limited to 'src/3rdparty/v8/test/cctest/test-thread-termination.cc')
-rw-r--r-- | src/3rdparty/v8/test/cctest/test-thread-termination.cc | 374 |
1 files changed, 0 insertions, 374 deletions
diff --git a/src/3rdparty/v8/test/cctest/test-thread-termination.cc b/src/3rdparty/v8/test/cctest/test-thread-termination.cc deleted file mode 100644 index b249c7a..0000000 --- a/src/3rdparty/v8/test/cctest/test-thread-termination.cc +++ /dev/null @@ -1,374 +0,0 @@ -// Copyright 2009 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "v8.h" -#include "platform.h" -#include "cctest.h" - - -v8::internal::Semaphore* semaphore = NULL; - - -v8::Handle<v8::Value> Signal(const v8::Arguments& args) { - semaphore->Signal(); - return v8::Undefined(); -} - - -v8::Handle<v8::Value> TerminateCurrentThread(const v8::Arguments& args) { - CHECK(!v8::V8::IsExecutionTerminating()); - v8::V8::TerminateExecution(); - return v8::Undefined(); -} - - -v8::Handle<v8::Value> Fail(const v8::Arguments& args) { - CHECK(false); - return v8::Undefined(); -} - - -v8::Handle<v8::Value> Loop(const v8::Arguments& args) { - CHECK(!v8::V8::IsExecutionTerminating()); - v8::Handle<v8::String> source = - v8::String::New("try { doloop(); fail(); } catch(e) { fail(); }"); - v8::Handle<v8::Value> result = v8::Script::Compile(source)->Run(); - CHECK(result.IsEmpty()); - CHECK(v8::V8::IsExecutionTerminating()); - return v8::Undefined(); -} - - -v8::Handle<v8::Value> DoLoop(const v8::Arguments& args) { - v8::TryCatch try_catch; - CHECK(!v8::V8::IsExecutionTerminating()); - v8::Script::Compile(v8::String::New("function f() {" - " var term = true;" - " try {" - " while(true) {" - " if (term) terminate();" - " term = false;" - " }" - " fail();" - " } catch(e) {" - " fail();" - " }" - "}" - "f()"))->Run(); - CHECK(try_catch.HasCaught()); - CHECK(try_catch.Exception()->IsNull()); - CHECK(try_catch.Message().IsEmpty()); - CHECK(!try_catch.CanContinue()); - CHECK(v8::V8::IsExecutionTerminating()); - return v8::Undefined(); -} - - -v8::Handle<v8::Value> DoLoopNoCall(const v8::Arguments& args) { - v8::TryCatch try_catch; - CHECK(!v8::V8::IsExecutionTerminating()); - v8::Script::Compile(v8::String::New("var term = true;" - "while(true) {" - " if (term) terminate();" - " term = false;" - "}"))->Run(); - CHECK(try_catch.HasCaught()); - CHECK(try_catch.Exception()->IsNull()); - CHECK(try_catch.Message().IsEmpty()); - CHECK(!try_catch.CanContinue()); - CHECK(v8::V8::IsExecutionTerminating()); - return v8::Undefined(); -} - - -v8::Handle<v8::ObjectTemplate> CreateGlobalTemplate( - v8::InvocationCallback terminate, - v8::InvocationCallback doloop) { - v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); - global->Set(v8::String::New("terminate"), - v8::FunctionTemplate::New(terminate)); - global->Set(v8::String::New("fail"), v8::FunctionTemplate::New(Fail)); - global->Set(v8::String::New("loop"), v8::FunctionTemplate::New(Loop)); - global->Set(v8::String::New("doloop"), v8::FunctionTemplate::New(doloop)); - return global; -} - - -// Test that a single thread of JavaScript execution can terminate -// itself. -TEST(TerminateOnlyV8ThreadFromThreadItself) { - v8::HandleScope scope; - v8::Handle<v8::ObjectTemplate> global = - CreateGlobalTemplate(TerminateCurrentThread, DoLoop); - v8::Persistent<v8::Context> context = v8::Context::New(NULL, global); - v8::Context::Scope context_scope(context); - CHECK(!v8::V8::IsExecutionTerminating()); - // Run a loop that will be infinite if thread termination does not work. - v8::Handle<v8::String> source = - v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); - v8::Script::Compile(source)->Run(); - // Test that we can run the code again after thread termination. - CHECK(!v8::V8::IsExecutionTerminating()); - v8::Script::Compile(source)->Run(); - context.Dispose(context->GetIsolate()); -} - - -// Test that a single thread of JavaScript execution can terminate -// itself in a loop that performs no calls. -TEST(TerminateOnlyV8ThreadFromThreadItselfNoLoop) { - v8::HandleScope scope; - v8::Handle<v8::ObjectTemplate> global = - CreateGlobalTemplate(TerminateCurrentThread, DoLoopNoCall); - v8::Persistent<v8::Context> context = v8::Context::New(NULL, global); - v8::Context::Scope context_scope(context); - CHECK(!v8::V8::IsExecutionTerminating()); - // Run a loop that will be infinite if thread termination does not work. - v8::Handle<v8::String> source = - v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); - v8::Script::Compile(source)->Run(); - CHECK(!v8::V8::IsExecutionTerminating()); - // Test that we can run the code again after thread termination. - v8::Script::Compile(source)->Run(); - context.Dispose(context->GetIsolate()); -} - - -class TerminatorThread : public v8::internal::Thread { - public: - explicit TerminatorThread(i::Isolate* isolate) - : Thread("TerminatorThread"), - isolate_(reinterpret_cast<v8::Isolate*>(isolate)) { } - void Run() { - semaphore->Wait(); - CHECK(!v8::V8::IsExecutionTerminating(isolate_)); - v8::V8::TerminateExecution(isolate_); - } - - private: - v8::Isolate* isolate_; -}; - - -// Test that a single thread of JavaScript execution can be terminated -// from the side by another thread. -TEST(TerminateOnlyV8ThreadFromOtherThread) { - semaphore = v8::internal::OS::CreateSemaphore(0); - TerminatorThread thread(i::Isolate::Current()); - thread.Start(); - - v8::HandleScope scope; - v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate(Signal, DoLoop); - v8::Persistent<v8::Context> context = v8::Context::New(NULL, global); - v8::Context::Scope context_scope(context); - CHECK(!v8::V8::IsExecutionTerminating()); - // Run a loop that will be infinite if thread termination does not work. - v8::Handle<v8::String> source = - v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); - v8::Script::Compile(source)->Run(); - - thread.Join(); - delete semaphore; - semaphore = NULL; - context.Dispose(context->GetIsolate()); -} - - -class LoopingThread : public v8::internal::Thread { - public: - LoopingThread() : Thread("LoopingThread") { } - void Run() { - v8::Locker locker(CcTest::default_isolate()); - v8::HandleScope scope; - v8_thread_id_ = v8::V8::GetCurrentThreadId(); - v8::Handle<v8::ObjectTemplate> global = - CreateGlobalTemplate(Signal, DoLoop); - v8::Persistent<v8::Context> context = v8::Context::New(NULL, global); - v8::Context::Scope context_scope(context); - CHECK(!v8::V8::IsExecutionTerminating()); - // Run a loop that will be infinite if thread termination does not work. - v8::Handle<v8::String> source = - v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); - v8::Script::Compile(source)->Run(); - context.Dispose(context->GetIsolate()); - } - - int GetV8ThreadId() { return v8_thread_id_; } - - private: - int v8_thread_id_; -}; - - -// Test that multiple threads using default isolate can be terminated -// from another thread when using Lockers and preemption. -TEST(TerminateMultipleV8ThreadsDefaultIsolate) { - { - v8::Locker locker(CcTest::default_isolate()); - v8::V8::Initialize(); - v8::Locker::StartPreemption(1); - semaphore = v8::internal::OS::CreateSemaphore(0); - } - const int kThreads = 2; - i::List<LoopingThread*> threads(kThreads); - for (int i = 0; i < kThreads; i++) { - threads.Add(new LoopingThread()); - } - for (int i = 0; i < kThreads; i++) { - threads[i]->Start(); - } - // Wait until all threads have signaled the semaphore. - for (int i = 0; i < kThreads; i++) { - semaphore->Wait(); - } - { - v8::Locker locker(CcTest::default_isolate()); - for (int i = 0; i < kThreads; i++) { - v8::V8::TerminateExecution(threads[i]->GetV8ThreadId()); - } - } - for (int i = 0; i < kThreads; i++) { - threads[i]->Join(); - delete threads[i]; - } - { - v8::Locker locker(CcTest::default_isolate()); - v8::Locker::StopPreemption(); - } - - delete semaphore; - semaphore = NULL; -} - - -int call_count = 0; - - -v8::Handle<v8::Value> TerminateOrReturnObject(const v8::Arguments& args) { - if (++call_count == 10) { - CHECK(!v8::V8::IsExecutionTerminating()); - v8::V8::TerminateExecution(); - return v8::Undefined(); - } - v8::Local<v8::Object> result = v8::Object::New(); - result->Set(v8::String::New("x"), v8::Integer::New(42)); - return result; -} - - -v8::Handle<v8::Value> LoopGetProperty(const v8::Arguments& args) { - v8::TryCatch try_catch; - CHECK(!v8::V8::IsExecutionTerminating()); - v8::Script::Compile(v8::String::New("function f() {" - " try {" - " while(true) {" - " terminate_or_return_object().x;" - " }" - " fail();" - " } catch(e) {" - " fail();" - " }" - "}" - "f()"))->Run(); - CHECK(try_catch.HasCaught()); - CHECK(try_catch.Exception()->IsNull()); - CHECK(try_catch.Message().IsEmpty()); - CHECK(!try_catch.CanContinue()); - CHECK(v8::V8::IsExecutionTerminating()); - return v8::Undefined(); -} - - -// Test that we correctly handle termination exceptions if they are -// triggered by the creation of error objects in connection with ICs. -TEST(TerminateLoadICException) { - v8::HandleScope scope; - v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); - global->Set(v8::String::New("terminate_or_return_object"), - v8::FunctionTemplate::New(TerminateOrReturnObject)); - global->Set(v8::String::New("fail"), v8::FunctionTemplate::New(Fail)); - global->Set(v8::String::New("loop"), - v8::FunctionTemplate::New(LoopGetProperty)); - - v8::Persistent<v8::Context> context = v8::Context::New(NULL, global); - v8::Context::Scope context_scope(context); - CHECK(!v8::V8::IsExecutionTerminating()); - // Run a loop that will be infinite if thread termination does not work. - v8::Handle<v8::String> source = - v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); - call_count = 0; - v8::Script::Compile(source)->Run(); - // Test that we can run the code again after thread termination. - CHECK(!v8::V8::IsExecutionTerminating()); - call_count = 0; - v8::Script::Compile(source)->Run(); - context.Dispose(context->GetIsolate()); -} - -v8::Handle<v8::Value> ReenterAfterTermination(const v8::Arguments& args) { - v8::TryCatch try_catch; - CHECK(!v8::V8::IsExecutionTerminating()); - v8::Script::Compile(v8::String::New("function f() {" - " var term = true;" - " try {" - " while(true) {" - " if (term) terminate();" - " term = false;" - " }" - " fail();" - " } catch(e) {" - " fail();" - " }" - "}" - "f()"))->Run(); - CHECK(try_catch.HasCaught()); - CHECK(try_catch.Exception()->IsNull()); - CHECK(try_catch.Message().IsEmpty()); - CHECK(!try_catch.CanContinue()); - CHECK(v8::V8::IsExecutionTerminating()); - v8::Script::Compile(v8::String::New("function f() { fail(); } f()"))->Run(); - return v8::Undefined(); -} - -// Test that reentry into V8 while the termination exception is still pending -// (has not yet unwound the 0-level JS frame) does not crash. -TEST(TerminateAndReenterFromThreadItself) { - v8::HandleScope scope; - v8::Handle<v8::ObjectTemplate> global = - CreateGlobalTemplate(TerminateCurrentThread, ReenterAfterTermination); - v8::Persistent<v8::Context> context = v8::Context::New(NULL, global); - v8::Context::Scope context_scope(context); - CHECK(!v8::V8::IsExecutionTerminating()); - v8::Handle<v8::String> source = - v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); - v8::Script::Compile(source)->Run(); - CHECK(!v8::V8::IsExecutionTerminating()); - // Check we can run JS again after termination. - CHECK(v8::Script::Compile(v8::String::New("function f() { return true; }" - "f()"))->Run()->IsTrue()); - context.Dispose(context->GetIsolate()); -} |