OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 |
(...skipping 12 matching lines...) Expand all Loading... |
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 #include <stdlib.h> | 28 #include <stdlib.h> |
29 | 29 |
30 #include "src/v8.h" | 30 #include "src/v8.h" |
31 | 31 |
32 #include "src/api.h" | 32 #include "src/api.h" |
| 33 #include "src/base/platform/condition-variable.h" |
| 34 #include "src/base/platform/platform.h" |
33 #include "src/compilation-cache.h" | 35 #include "src/compilation-cache.h" |
34 #include "src/debug.h" | 36 #include "src/debug.h" |
35 #include "src/deoptimizer.h" | 37 #include "src/deoptimizer.h" |
36 #include "src/frames.h" | 38 #include "src/frames.h" |
37 #include "src/platform.h" | |
38 #include "src/platform/condition-variable.h" | |
39 #include "src/stub-cache.h" | 39 #include "src/stub-cache.h" |
40 #include "src/utils.h" | 40 #include "src/utils.h" |
41 #include "test/cctest/cctest.h" | 41 #include "test/cctest/cctest.h" |
42 | 42 |
43 | 43 |
44 using ::v8::internal::Mutex; | 44 using ::v8::base::Mutex; |
45 using ::v8::internal::LockGuard; | 45 using ::v8::base::LockGuard; |
46 using ::v8::internal::ConditionVariable; | 46 using ::v8::base::ConditionVariable; |
47 using ::v8::internal::Semaphore; | 47 using ::v8::base::OS; |
| 48 using ::v8::base::Semaphore; |
48 using ::v8::internal::EmbeddedVector; | 49 using ::v8::internal::EmbeddedVector; |
49 using ::v8::internal::Object; | 50 using ::v8::internal::Object; |
50 using ::v8::internal::OS; | |
51 using ::v8::internal::Handle; | 51 using ::v8::internal::Handle; |
52 using ::v8::internal::Heap; | 52 using ::v8::internal::Heap; |
53 using ::v8::internal::JSGlobalProxy; | 53 using ::v8::internal::JSGlobalProxy; |
54 using ::v8::internal::Code; | 54 using ::v8::internal::Code; |
55 using ::v8::internal::Debug; | 55 using ::v8::internal::Debug; |
56 using ::v8::internal::Debugger; | 56 using ::v8::internal::Debugger; |
57 using ::v8::internal::CommandMessage; | 57 using ::v8::internal::CommandMessage; |
58 using ::v8::internal::CommandMessageQueue; | 58 using ::v8::internal::CommandMessageQueue; |
59 using ::v8::internal::StackFrame; | 59 using ::v8::internal::StackFrame; |
60 using ::v8::internal::StepAction; | 60 using ::v8::internal::StepAction; |
(...skipping 4676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4737 | 4737 |
4738 // A set containing enough barriers and semaphores for any of the tests. | 4738 // A set containing enough barriers and semaphores for any of the tests. |
4739 class Barriers { | 4739 class Barriers { |
4740 public: | 4740 public: |
4741 Barriers() : semaphore_1(0), semaphore_2(0) {} | 4741 Barriers() : semaphore_1(0), semaphore_2(0) {} |
4742 ThreadBarrier<2> barrier_1; | 4742 ThreadBarrier<2> barrier_1; |
4743 ThreadBarrier<2> barrier_2; | 4743 ThreadBarrier<2> barrier_2; |
4744 ThreadBarrier<2> barrier_3; | 4744 ThreadBarrier<2> barrier_3; |
4745 ThreadBarrier<2> barrier_4; | 4745 ThreadBarrier<2> barrier_4; |
4746 ThreadBarrier<2> barrier_5; | 4746 ThreadBarrier<2> barrier_5; |
4747 v8::internal::Semaphore semaphore_1; | 4747 v8::base::Semaphore semaphore_1; |
4748 v8::internal::Semaphore semaphore_2; | 4748 v8::base::Semaphore semaphore_2; |
4749 }; | 4749 }; |
4750 | 4750 |
4751 | 4751 |
4752 // We match parts of the message to decide if it is a break message. | 4752 // We match parts of the message to decide if it is a break message. |
4753 bool IsBreakEventMessage(char *message) { | 4753 bool IsBreakEventMessage(char *message) { |
4754 const char* type_event = "\"type\":\"event\""; | 4754 const char* type_event = "\"type\":\"event\""; |
4755 const char* event_break = "\"event\":\"break\""; | 4755 const char* event_break = "\"event\":\"break\""; |
4756 // Does the message contain both type:event and event:break? | 4756 // Does the message contain both type:event and event:break? |
4757 return strstr(message, type_event) != NULL && | 4757 return strstr(message, type_event) != NULL && |
4758 strstr(message, event_break) != NULL; | 4758 strstr(message, event_break) != NULL; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4838 | 4838 |
4839 /* Test MessageQueues */ | 4839 /* Test MessageQueues */ |
4840 /* Tests the message queues that hold debugger commands and | 4840 /* Tests the message queues that hold debugger commands and |
4841 * response messages to the debugger. Fills queues and makes | 4841 * response messages to the debugger. Fills queues and makes |
4842 * them grow. | 4842 * them grow. |
4843 */ | 4843 */ |
4844 Barriers message_queue_barriers; | 4844 Barriers message_queue_barriers; |
4845 | 4845 |
4846 // This is the debugger thread, that executes no v8 calls except | 4846 // This is the debugger thread, that executes no v8 calls except |
4847 // placing JSON debugger commands in the queue. | 4847 // placing JSON debugger commands in the queue. |
4848 class MessageQueueDebuggerThread : public v8::internal::Thread { | 4848 class MessageQueueDebuggerThread : public v8::base::Thread { |
4849 public: | 4849 public: |
4850 MessageQueueDebuggerThread() | 4850 MessageQueueDebuggerThread() |
4851 : Thread("MessageQueueDebuggerThread") { } | 4851 : Thread("MessageQueueDebuggerThread") { } |
4852 void Run(); | 4852 void Run(); |
4853 }; | 4853 }; |
4854 | 4854 |
4855 | 4855 |
4856 static void MessageHandler(const v8::Debug::Message& message) { | 4856 static void MessageHandler(const v8::Debug::Message& message) { |
4857 v8::Handle<v8::String> json = message.GetJSON(); | 4857 v8::Handle<v8::String> json = message.GetJSON(); |
4858 v8::String::Utf8Value utf8(json); | 4858 v8::String::Utf8Value utf8(json); |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5095 | 5095 |
5096 /* Test ThreadedDebugging */ | 5096 /* Test ThreadedDebugging */ |
5097 /* This test interrupts a running infinite loop that is | 5097 /* This test interrupts a running infinite loop that is |
5098 * occupying the v8 thread by a break command from the | 5098 * occupying the v8 thread by a break command from the |
5099 * debugger thread. It then changes the value of a | 5099 * debugger thread. It then changes the value of a |
5100 * global object, to make the loop terminate. | 5100 * global object, to make the loop terminate. |
5101 */ | 5101 */ |
5102 | 5102 |
5103 Barriers threaded_debugging_barriers; | 5103 Barriers threaded_debugging_barriers; |
5104 | 5104 |
5105 class V8Thread : public v8::internal::Thread { | 5105 class V8Thread : public v8::base::Thread { |
5106 public: | 5106 public: |
5107 V8Thread() : Thread("V8Thread") { } | 5107 V8Thread() : Thread("V8Thread") { } |
5108 void Run(); | 5108 void Run(); |
5109 }; | 5109 }; |
5110 | 5110 |
5111 class DebuggerThread : public v8::internal::Thread { | 5111 class DebuggerThread : public v8::base::Thread { |
5112 public: | 5112 public: |
5113 DebuggerThread() : Thread("DebuggerThread") { } | 5113 DebuggerThread() : Thread("DebuggerThread") { } |
5114 void Run(); | 5114 void Run(); |
5115 }; | 5115 }; |
5116 | 5116 |
5117 | 5117 |
5118 static void ThreadedAtBarrier1( | 5118 static void ThreadedAtBarrier1( |
5119 const v8::FunctionCallbackInfo<v8::Value>& args) { | 5119 const v8::FunctionCallbackInfo<v8::Value>& args) { |
5120 threaded_debugging_barriers.barrier_1.Wait(); | 5120 threaded_debugging_barriers.barrier_1.Wait(); |
5121 } | 5121 } |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5207 } | 5207 } |
5208 | 5208 |
5209 | 5209 |
5210 /* Test RecursiveBreakpoints */ | 5210 /* Test RecursiveBreakpoints */ |
5211 /* In this test, the debugger evaluates a function with a breakpoint, after | 5211 /* In this test, the debugger evaluates a function with a breakpoint, after |
5212 * hitting a breakpoint in another function. We do this with both values | 5212 * hitting a breakpoint in another function. We do this with both values |
5213 * of the flag enabling recursive breakpoints, and verify that the second | 5213 * of the flag enabling recursive breakpoints, and verify that the second |
5214 * breakpoint is hit when enabled, and missed when disabled. | 5214 * breakpoint is hit when enabled, and missed when disabled. |
5215 */ | 5215 */ |
5216 | 5216 |
5217 class BreakpointsV8Thread : public v8::internal::Thread { | 5217 class BreakpointsV8Thread : public v8::base::Thread { |
5218 public: | 5218 public: |
5219 BreakpointsV8Thread() : Thread("BreakpointsV8Thread") { } | 5219 BreakpointsV8Thread() : Thread("BreakpointsV8Thread") { } |
5220 void Run(); | 5220 void Run(); |
5221 }; | 5221 }; |
5222 | 5222 |
5223 class BreakpointsDebuggerThread : public v8::internal::Thread { | 5223 class BreakpointsDebuggerThread : public v8::base::Thread { |
5224 public: | 5224 public: |
5225 explicit BreakpointsDebuggerThread(bool global_evaluate) | 5225 explicit BreakpointsDebuggerThread(bool global_evaluate) |
5226 : Thread("BreakpointsDebuggerThread"), | 5226 : Thread("BreakpointsDebuggerThread"), |
5227 global_evaluate_(global_evaluate) {} | 5227 global_evaluate_(global_evaluate) {} |
5228 void Run(); | 5228 void Run(); |
5229 | 5229 |
5230 private: | 5230 private: |
5231 bool global_evaluate_; | 5231 bool global_evaluate_; |
5232 }; | 5232 }; |
5233 | 5233 |
(...skipping 1288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6522 v8::Debug::ProcessDebugMessages(); | 6522 v8::Debug::ProcessDebugMessages(); |
6523 // At least two messages should come | 6523 // At least two messages should come |
6524 CHECK_GE(counting_message_handler_counter, 2); | 6524 CHECK_GE(counting_message_handler_counter, 2); |
6525 | 6525 |
6526 // Get rid of the debug message handler. | 6526 // Get rid of the debug message handler. |
6527 v8::Debug::SetMessageHandler(NULL); | 6527 v8::Debug::SetMessageHandler(NULL); |
6528 CheckDebuggerUnloaded(); | 6528 CheckDebuggerUnloaded(); |
6529 } | 6529 } |
6530 | 6530 |
6531 | 6531 |
6532 class SendCommandThread : public v8::internal::Thread { | 6532 class SendCommandThread : public v8::base::Thread { |
6533 public: | 6533 public: |
6534 explicit SendCommandThread(v8::Isolate* isolate) | 6534 explicit SendCommandThread(v8::Isolate* isolate) |
6535 : Thread("SendCommandThread"), | 6535 : Thread("SendCommandThread"), |
6536 semaphore_(0), | 6536 semaphore_(0), |
6537 isolate_(isolate) { } | 6537 isolate_(isolate) { } |
6538 | 6538 |
6539 static void ProcessDebugMessages(v8::Isolate* isolate, void* data) { | 6539 static void ProcessDebugMessages(v8::Isolate* isolate, void* data) { |
6540 v8::Debug::ProcessDebugMessages(); | 6540 v8::Debug::ProcessDebugMessages(); |
6541 reinterpret_cast<v8::internal::Semaphore*>(data)->Signal(); | 6541 reinterpret_cast<v8::base::Semaphore*>(data)->Signal(); |
6542 } | 6542 } |
6543 | 6543 |
6544 virtual void Run() { | 6544 virtual void Run() { |
6545 semaphore_.Wait(); | 6545 semaphore_.Wait(); |
6546 const int kBufferSize = 1000; | 6546 const int kBufferSize = 1000; |
6547 uint16_t buffer[kBufferSize]; | 6547 uint16_t buffer[kBufferSize]; |
6548 const char* scripts_command = | 6548 const char* scripts_command = |
6549 "{\"seq\":0," | 6549 "{\"seq\":0," |
6550 "\"type\":\"request\"," | 6550 "\"type\":\"request\"," |
6551 "\"command\":\"scripts\"}"; | 6551 "\"command\":\"scripts\"}"; |
(...skipping 10 matching lines...) Expand all Loading... |
6562 } | 6562 } |
6563 | 6563 |
6564 v8::V8::TerminateExecution(isolate_); | 6564 v8::V8::TerminateExecution(isolate_); |
6565 } | 6565 } |
6566 | 6566 |
6567 void StartSending() { | 6567 void StartSending() { |
6568 semaphore_.Signal(); | 6568 semaphore_.Signal(); |
6569 } | 6569 } |
6570 | 6570 |
6571 private: | 6571 private: |
6572 v8::internal::Semaphore semaphore_; | 6572 v8::base::Semaphore semaphore_; |
6573 v8::Isolate* isolate_; | 6573 v8::Isolate* isolate_; |
6574 }; | 6574 }; |
6575 | 6575 |
6576 | 6576 |
6577 static SendCommandThread* send_command_thread_ = NULL; | 6577 static SendCommandThread* send_command_thread_ = NULL; |
6578 | 6578 |
6579 static void StartSendingCommands( | 6579 static void StartSendingCommands( |
6580 const v8::FunctionCallbackInfo<v8::Value>& info) { | 6580 const v8::FunctionCallbackInfo<v8::Value>& info) { |
6581 send_command_thread_->StartSending(); | 6581 send_command_thread_->StartSending(); |
6582 } | 6582 } |
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7362 CompileRun("(function loop() {" | 7362 CompileRun("(function loop() {" |
7363 " for (var j = 0; j < 1000; j++) {" | 7363 " for (var j = 0; j < 1000; j++) {" |
7364 " for (var i = 0; i < 1000; i++) {" | 7364 " for (var i = 0; i < 1000; i++) {" |
7365 " if (i == 999) add_debug_break();" | 7365 " if (i == 999) add_debug_break();" |
7366 " }" | 7366 " }" |
7367 " }" | 7367 " }" |
7368 "})()"); | 7368 "})()"); |
7369 } | 7369 } |
7370 | 7370 |
7371 | 7371 |
7372 v8::internal::Semaphore terminate_requested_semaphore(0); | 7372 v8::base::Semaphore terminate_requested_semaphore(0); |
7373 v8::internal::Semaphore terminate_fired_semaphore(0); | 7373 v8::base::Semaphore terminate_fired_semaphore(0); |
7374 bool terminate_already_fired = false; | 7374 bool terminate_already_fired = false; |
7375 | 7375 |
7376 | 7376 |
7377 static void DebugBreakTriggerTerminate( | 7377 static void DebugBreakTriggerTerminate( |
7378 const v8::Debug::EventDetails& event_details) { | 7378 const v8::Debug::EventDetails& event_details) { |
7379 if (event_details.GetEvent() != v8::Break || terminate_already_fired) return; | 7379 if (event_details.GetEvent() != v8::Break || terminate_already_fired) return; |
7380 terminate_requested_semaphore.Signal(); | 7380 terminate_requested_semaphore.Signal(); |
7381 // Wait for at most 2 seconds for the terminate request. | 7381 // Wait for at most 2 seconds for the terminate request. |
7382 CHECK(terminate_fired_semaphore.WaitFor(i::TimeDelta::FromSeconds(2))); | 7382 CHECK(terminate_fired_semaphore.WaitFor(v8::base::TimeDelta::FromSeconds(2))); |
7383 terminate_already_fired = true; | 7383 terminate_already_fired = true; |
7384 v8::internal::Isolate* isolate = | 7384 v8::internal::Isolate* isolate = |
7385 v8::Utils::OpenHandle(*event_details.GetEventContext())->GetIsolate(); | 7385 v8::Utils::OpenHandle(*event_details.GetEventContext())->GetIsolate(); |
7386 CHECK(isolate->stack_guard()->CheckTerminateExecution()); | 7386 CHECK(isolate->stack_guard()->CheckTerminateExecution()); |
7387 } | 7387 } |
7388 | 7388 |
7389 | 7389 |
7390 class TerminationThread : public v8::internal::Thread { | 7390 class TerminationThread : public v8::base::Thread { |
7391 public: | 7391 public: |
7392 explicit TerminationThread(v8::Isolate* isolate) : Thread("terminator"), | 7392 explicit TerminationThread(v8::Isolate* isolate) : Thread("terminator"), |
7393 isolate_(isolate) { } | 7393 isolate_(isolate) { } |
7394 | 7394 |
7395 virtual void Run() { | 7395 virtual void Run() { |
7396 terminate_requested_semaphore.Wait(); | 7396 terminate_requested_semaphore.Wait(); |
7397 v8::V8::TerminateExecution(isolate_); | 7397 v8::V8::TerminateExecution(isolate_); |
7398 terminate_fired_semaphore.Signal(); | 7398 terminate_fired_semaphore.Signal(); |
7399 } | 7399 } |
7400 | 7400 |
7401 private: | 7401 private: |
7402 v8::Isolate* isolate_; | 7402 v8::Isolate* isolate_; |
7403 }; | 7403 }; |
7404 | 7404 |
7405 | 7405 |
7406 TEST(DebugBreakOffThreadTerminate) { | 7406 TEST(DebugBreakOffThreadTerminate) { |
7407 DebugLocalContext env; | 7407 DebugLocalContext env; |
7408 v8::Isolate* isolate = env->GetIsolate(); | 7408 v8::Isolate* isolate = env->GetIsolate(); |
7409 v8::HandleScope scope(isolate); | 7409 v8::HandleScope scope(isolate); |
7410 v8::Debug::SetDebugEventListener(DebugBreakTriggerTerminate); | 7410 v8::Debug::SetDebugEventListener(DebugBreakTriggerTerminate); |
7411 TerminationThread terminator(isolate); | 7411 TerminationThread terminator(isolate); |
7412 terminator.Start(); | 7412 terminator.Start(); |
7413 v8::Debug::DebugBreak(isolate); | 7413 v8::Debug::DebugBreak(isolate); |
7414 CompileRun("while (true);"); | 7414 CompileRun("while (true);"); |
7415 } | 7415 } |
OLD | NEW |