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 20 matching lines...) Expand all Loading... |
31 | 31 |
32 #define V8_DISABLE_DEPRECATIONS 1 | 32 #define V8_DISABLE_DEPRECATIONS 1 |
33 #include "v8.h" | 33 #include "v8.h" |
34 | 34 |
35 #include "api.h" | 35 #include "api.h" |
36 #include "cctest.h" | 36 #include "cctest.h" |
37 #include "compilation-cache.h" | 37 #include "compilation-cache.h" |
38 #include "debug.h" | 38 #include "debug.h" |
39 #include "deoptimizer.h" | 39 #include "deoptimizer.h" |
40 #include "platform.h" | 40 #include "platform.h" |
| 41 #include "platform/condition-variable.h" |
41 #include "stub-cache.h" | 42 #include "stub-cache.h" |
42 #include "utils.h" | 43 #include "utils.h" |
43 #undef V8_DISABLE_DEPRECATIONS | 44 #undef V8_DISABLE_DEPRECATIONS |
44 | 45 |
45 | 46 |
| 47 using ::v8::internal::Mutex; |
| 48 using ::v8::internal::LockGuard; |
| 49 using ::v8::internal::ConditionVariable; |
| 50 using ::v8::internal::Semaphore; |
46 using ::v8::internal::EmbeddedVector; | 51 using ::v8::internal::EmbeddedVector; |
47 using ::v8::internal::Object; | 52 using ::v8::internal::Object; |
48 using ::v8::internal::OS; | 53 using ::v8::internal::OS; |
49 using ::v8::internal::Handle; | 54 using ::v8::internal::Handle; |
50 using ::v8::internal::Heap; | 55 using ::v8::internal::Heap; |
51 using ::v8::internal::JSGlobalProxy; | 56 using ::v8::internal::JSGlobalProxy; |
52 using ::v8::internal::Code; | 57 using ::v8::internal::Code; |
53 using ::v8::internal::Debug; | 58 using ::v8::internal::Debug; |
54 using ::v8::internal::Debugger; | 59 using ::v8::internal::Debugger; |
55 using ::v8::internal::CommandMessage; | 60 using ::v8::internal::CommandMessage; |
(...skipping 4604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4660 "obj_mirror.property('a').value().value() == 1")->BooleanValue()); | 4665 "obj_mirror.property('a').value().value() == 1")->BooleanValue()); |
4661 CHECK(CompileRun( | 4666 CHECK(CompileRun( |
4662 "obj_mirror.property('b').value().value() == 2")->BooleanValue()); | 4667 "obj_mirror.property('b').value().value() == 2")->BooleanValue()); |
4663 } | 4668 } |
4664 | 4669 |
4665 | 4670 |
4666 // Multithreaded tests of JSON debugger protocol | 4671 // Multithreaded tests of JSON debugger protocol |
4667 | 4672 |
4668 // Support classes | 4673 // Support classes |
4669 | 4674 |
4670 // Provides synchronization between k threads, where k is an input to the | 4675 // Provides synchronization between N threads, where N is a template parameter. |
4671 // constructor. The Wait() call blocks a thread until it is called for the | 4676 // The Wait() call blocks a thread until it is called for the Nth time, then all |
4672 // k'th time, then all calls return. Each ThreadBarrier object can only | 4677 // calls return. Each ThreadBarrier object can only be used once. |
4673 // be used once. | 4678 template <int N> |
4674 class ThreadBarrier { | 4679 class ThreadBarrier V8_FINAL { |
4675 public: | 4680 public: |
4676 explicit ThreadBarrier(int num_threads); | 4681 ThreadBarrier() : num_blocked_(0) {} |
4677 ~ThreadBarrier(); | 4682 |
4678 void Wait(); | 4683 ~ThreadBarrier() { |
| 4684 LockGuard<Mutex> lock_guard(&mutex_); |
| 4685 if (num_blocked_ != 0) { |
| 4686 CHECK_EQ(N, num_blocked_); |
| 4687 } |
| 4688 } |
| 4689 |
| 4690 void Wait() { |
| 4691 LockGuard<Mutex> lock_guard(&mutex_); |
| 4692 CHECK_LT(num_blocked_, N); |
| 4693 num_blocked_++; |
| 4694 if (N == num_blocked_) { |
| 4695 // Signal and unblock all waiting threads. |
| 4696 cv_.NotifyAll(); |
| 4697 printf("BARRIER\n\n"); |
| 4698 fflush(stdout); |
| 4699 } else { // Wait for the semaphore. |
| 4700 while (num_blocked_ < N) { |
| 4701 cv_.Wait(&mutex_); |
| 4702 } |
| 4703 } |
| 4704 CHECK_EQ(N, num_blocked_); |
| 4705 } |
| 4706 |
4679 private: | 4707 private: |
4680 int num_threads_; | 4708 ConditionVariable cv_; |
| 4709 Mutex mutex_; |
4681 int num_blocked_; | 4710 int num_blocked_; |
4682 v8::internal::Mutex lock_; | 4711 |
4683 v8::internal::Semaphore sem_; | 4712 STATIC_CHECK(N > 0); |
4684 bool invalid_; | 4713 |
| 4714 DISALLOW_COPY_AND_ASSIGN(ThreadBarrier); |
4685 }; | 4715 }; |
4686 | 4716 |
4687 ThreadBarrier::ThreadBarrier(int num_threads) | |
4688 : num_threads_(num_threads), num_blocked_(0), sem_(0) { | |
4689 invalid_ = false; // A barrier may only be used once. Then it is invalid. | |
4690 } | |
4691 | |
4692 | |
4693 // Do not call, due to race condition with Wait(). | |
4694 // Could be resolved with Pthread condition variables. | |
4695 ThreadBarrier::~ThreadBarrier() { | |
4696 } | |
4697 | |
4698 | |
4699 void ThreadBarrier::Wait() { | |
4700 lock_.Lock(); | |
4701 CHECK(!invalid_); | |
4702 if (num_blocked_ == num_threads_ - 1) { | |
4703 // Signal and unblock all waiting threads. | |
4704 for (int i = 0; i < num_threads_ - 1; ++i) { | |
4705 sem_.Signal(); | |
4706 } | |
4707 invalid_ = true; | |
4708 printf("BARRIER\n\n"); | |
4709 fflush(stdout); | |
4710 lock_.Unlock(); | |
4711 } else { // Wait for the semaphore. | |
4712 ++num_blocked_; | |
4713 lock_.Unlock(); // Potential race condition with destructor because | |
4714 sem_.Wait(); // these two lines are not atomic. | |
4715 } | |
4716 } | |
4717 | |
4718 | 4717 |
4719 // A set containing enough barriers and semaphores for any of the tests. | 4718 // A set containing enough barriers and semaphores for any of the tests. |
4720 class Barriers { | 4719 class Barriers { |
4721 public: | 4720 public: |
4722 Barriers(); | 4721 Barriers() : semaphore_1(0), semaphore_2(0) {} |
4723 void Initialize(); | 4722 ThreadBarrier<2> barrier_1; |
4724 ThreadBarrier barrier_1; | 4723 ThreadBarrier<2> barrier_2; |
4725 ThreadBarrier barrier_2; | 4724 ThreadBarrier<2> barrier_3; |
4726 ThreadBarrier barrier_3; | 4725 ThreadBarrier<2> barrier_4; |
4727 ThreadBarrier barrier_4; | 4726 ThreadBarrier<2> barrier_5; |
4728 ThreadBarrier barrier_5; | 4727 v8::internal::Semaphore semaphore_1; |
4729 v8::internal::Semaphore* semaphore_1; | 4728 v8::internal::Semaphore semaphore_2; |
4730 v8::internal::Semaphore* semaphore_2; | |
4731 }; | 4729 }; |
4732 | 4730 |
4733 Barriers::Barriers() : barrier_1(2), barrier_2(2), | |
4734 barrier_3(2), barrier_4(2), barrier_5(2) {} | |
4735 | |
4736 void Barriers::Initialize() { | |
4737 semaphore_1 = new v8::internal::Semaphore(0); | |
4738 semaphore_2 = new v8::internal::Semaphore(0); | |
4739 } | |
4740 | |
4741 | 4731 |
4742 // We match parts of the message to decide if it is a break message. | 4732 // We match parts of the message to decide if it is a break message. |
4743 bool IsBreakEventMessage(char *message) { | 4733 bool IsBreakEventMessage(char *message) { |
4744 const char* type_event = "\"type\":\"event\""; | 4734 const char* type_event = "\"type\":\"event\""; |
4745 const char* event_break = "\"event\":\"break\""; | 4735 const char* event_break = "\"event\":\"break\""; |
4746 // Does the message contain both type:event and event:break? | 4736 // Does the message contain both type:event and event:break? |
4747 return strstr(message, type_event) != NULL && | 4737 return strstr(message, type_event) != NULL && |
4748 strstr(message, event_break) != NULL; | 4738 strstr(message, event_break) != NULL; |
4749 } | 4739 } |
4750 | 4740 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4842 void Run(); | 4832 void Run(); |
4843 }; | 4833 }; |
4844 | 4834 |
4845 | 4835 |
4846 static void MessageHandler(const v8::Debug::Message& message) { | 4836 static void MessageHandler(const v8::Debug::Message& message) { |
4847 v8::Handle<v8::String> json = message.GetJSON(); | 4837 v8::Handle<v8::String> json = message.GetJSON(); |
4848 v8::String::AsciiValue ascii(json); | 4838 v8::String::AsciiValue ascii(json); |
4849 if (IsBreakEventMessage(*ascii)) { | 4839 if (IsBreakEventMessage(*ascii)) { |
4850 // Lets test script wait until break occurs to send commands. | 4840 // Lets test script wait until break occurs to send commands. |
4851 // Signals when a break is reported. | 4841 // Signals when a break is reported. |
4852 message_queue_barriers.semaphore_2->Signal(); | 4842 message_queue_barriers.semaphore_2.Signal(); |
4853 } | 4843 } |
4854 | 4844 |
4855 // Allow message handler to block on a semaphore, to test queueing of | 4845 // Allow message handler to block on a semaphore, to test queueing of |
4856 // messages while blocked. | 4846 // messages while blocked. |
4857 message_queue_barriers.semaphore_1->Wait(); | 4847 message_queue_barriers.semaphore_1.Wait(); |
4858 } | 4848 } |
4859 | 4849 |
4860 | 4850 |
4861 void MessageQueueDebuggerThread::Run() { | 4851 void MessageQueueDebuggerThread::Run() { |
4862 const int kBufferSize = 1000; | 4852 const int kBufferSize = 1000; |
4863 uint16_t buffer_1[kBufferSize]; | 4853 uint16_t buffer_1[kBufferSize]; |
4864 uint16_t buffer_2[kBufferSize]; | 4854 uint16_t buffer_2[kBufferSize]; |
4865 const char* command_1 = | 4855 const char* command_1 = |
4866 "{\"seq\":117," | 4856 "{\"seq\":117," |
4867 "\"type\":\"request\"," | 4857 "\"type\":\"request\"," |
(...skipping 14 matching lines...) Expand all Loading... |
4882 "\"type\":\"request\"," | 4872 "\"type\":\"request\"," |
4883 "\"command\":\"continue\"}"; | 4873 "\"command\":\"continue\"}"; |
4884 const char* command_single_step = | 4874 const char* command_single_step = |
4885 "{\"seq\":107," | 4875 "{\"seq\":107," |
4886 "\"type\":\"request\"," | 4876 "\"type\":\"request\"," |
4887 "\"command\":\"continue\"," | 4877 "\"command\":\"continue\"," |
4888 "\"arguments\":{\"stepaction\":\"next\"}}"; | 4878 "\"arguments\":{\"stepaction\":\"next\"}}"; |
4889 | 4879 |
4890 /* Interleaved sequence of actions by the two threads:*/ | 4880 /* Interleaved sequence of actions by the two threads:*/ |
4891 // Main thread compiles and runs source_1 | 4881 // Main thread compiles and runs source_1 |
4892 message_queue_barriers.semaphore_1->Signal(); | 4882 message_queue_barriers.semaphore_1.Signal(); |
4893 message_queue_barriers.barrier_1.Wait(); | 4883 message_queue_barriers.barrier_1.Wait(); |
4894 // Post 6 commands, filling the command queue and making it expand. | 4884 // Post 6 commands, filling the command queue and making it expand. |
4895 // These calls return immediately, but the commands stay on the queue | 4885 // These calls return immediately, but the commands stay on the queue |
4896 // until the execution of source_2. | 4886 // until the execution of source_2. |
4897 // Note: AsciiToUtf16 executes before SendCommand, so command is copied | 4887 // Note: AsciiToUtf16 executes before SendCommand, so command is copied |
4898 // to buffer before buffer is sent to SendCommand. | 4888 // to buffer before buffer is sent to SendCommand. |
4899 v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_1, buffer_1)); | 4889 v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_1, buffer_1)); |
4900 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_2, buffer_2)); | 4890 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_2, buffer_2)); |
4901 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); | 4891 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); |
4902 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); | 4892 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); |
4903 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); | 4893 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); |
4904 message_queue_barriers.barrier_2.Wait(); | 4894 message_queue_barriers.barrier_2.Wait(); |
4905 // Main thread compiles and runs source_2. | 4895 // Main thread compiles and runs source_2. |
4906 // Queued commands are executed at the start of compilation of source_2( | 4896 // Queued commands are executed at the start of compilation of source_2( |
4907 // beforeCompile event). | 4897 // beforeCompile event). |
4908 // Free the message handler to process all the messages from the queue. 7 | 4898 // Free the message handler to process all the messages from the queue. 7 |
4909 // messages are expected: 2 afterCompile events and 5 responses. | 4899 // messages are expected: 2 afterCompile events and 5 responses. |
4910 // All the commands added so far will fail to execute as long as call stack | 4900 // All the commands added so far will fail to execute as long as call stack |
4911 // is empty on beforeCompile event. | 4901 // is empty on beforeCompile event. |
4912 for (int i = 0; i < 6 ; ++i) { | 4902 for (int i = 0; i < 6 ; ++i) { |
4913 message_queue_barriers.semaphore_1->Signal(); | 4903 message_queue_barriers.semaphore_1.Signal(); |
4914 } | 4904 } |
4915 message_queue_barriers.barrier_3.Wait(); | 4905 message_queue_barriers.barrier_3.Wait(); |
4916 // Main thread compiles and runs source_3. | 4906 // Main thread compiles and runs source_3. |
4917 // Don't stop in the afterCompile handler. | 4907 // Don't stop in the afterCompile handler. |
4918 message_queue_barriers.semaphore_1->Signal(); | 4908 message_queue_barriers.semaphore_1.Signal(); |
4919 // source_3 includes a debugger statement, which causes a break event. | 4909 // source_3 includes a debugger statement, which causes a break event. |
4920 // Wait on break event from hitting "debugger" statement | 4910 // Wait on break event from hitting "debugger" statement |
4921 message_queue_barriers.semaphore_2->Wait(); | 4911 message_queue_barriers.semaphore_2.Wait(); |
4922 // These should execute after the "debugger" statement in source_2 | 4912 // These should execute after the "debugger" statement in source_2 |
4923 v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_1, buffer_1)); | 4913 v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_1, buffer_1)); |
4924 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_2, buffer_2)); | 4914 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_2, buffer_2)); |
4925 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); | 4915 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); |
4926 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_single_step, buffer_2)); | 4916 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_single_step, buffer_2)); |
4927 // Run after 2 break events, 4 responses. | 4917 // Run after 2 break events, 4 responses. |
4928 for (int i = 0; i < 6 ; ++i) { | 4918 for (int i = 0; i < 6 ; ++i) { |
4929 message_queue_barriers.semaphore_1->Signal(); | 4919 message_queue_barriers.semaphore_1.Signal(); |
4930 } | 4920 } |
4931 // Wait on break event after a single step executes. | 4921 // Wait on break event after a single step executes. |
4932 message_queue_barriers.semaphore_2->Wait(); | 4922 message_queue_barriers.semaphore_2.Wait(); |
4933 v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_2, buffer_1)); | 4923 v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_2, buffer_1)); |
4934 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_continue, buffer_2)); | 4924 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_continue, buffer_2)); |
4935 // Run after 2 responses. | 4925 // Run after 2 responses. |
4936 for (int i = 0; i < 2 ; ++i) { | 4926 for (int i = 0; i < 2 ; ++i) { |
4937 message_queue_barriers.semaphore_1->Signal(); | 4927 message_queue_barriers.semaphore_1.Signal(); |
4938 } | 4928 } |
4939 // Main thread continues running source_3 to end, waits for this thread. | 4929 // Main thread continues running source_3 to end, waits for this thread. |
4940 } | 4930 } |
4941 | 4931 |
4942 | 4932 |
4943 // This thread runs the v8 engine. | 4933 // This thread runs the v8 engine. |
4944 TEST(MessageQueues) { | 4934 TEST(MessageQueues) { |
4945 MessageQueueDebuggerThread message_queue_debugger_thread; | 4935 MessageQueueDebuggerThread message_queue_debugger_thread; |
4946 | 4936 |
4947 // Create a V8 environment | 4937 // Create a V8 environment |
4948 DebugLocalContext env; | 4938 DebugLocalContext env; |
4949 v8::HandleScope scope(env->GetIsolate()); | 4939 v8::HandleScope scope(env->GetIsolate()); |
4950 message_queue_barriers.Initialize(); | |
4951 v8::Debug::SetMessageHandler2(MessageHandler); | 4940 v8::Debug::SetMessageHandler2(MessageHandler); |
4952 message_queue_debugger_thread.Start(); | 4941 message_queue_debugger_thread.Start(); |
4953 | 4942 |
4954 const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;"; | 4943 const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;"; |
4955 const char* source_2 = "e = 17;"; | 4944 const char* source_2 = "e = 17;"; |
4956 const char* source_3 = "a = 4; debugger; a = 5; a = 6; a = 7;"; | 4945 const char* source_3 = "a = 4; debugger; a = 5; a = 6; a = 7;"; |
4957 | 4946 |
4958 // See MessageQueueDebuggerThread::Run for interleaved sequence of | 4947 // See MessageQueueDebuggerThread::Run for interleaved sequence of |
4959 // API calls and events in the two threads. | 4948 // API calls and events in the two threads. |
4960 CompileRun(source_1); | 4949 CompileRun(source_1); |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5176 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer)); | 5165 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer)); |
5177 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); | 5166 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); |
5178 } | 5167 } |
5179 | 5168 |
5180 | 5169 |
5181 TEST(ThreadedDebugging) { | 5170 TEST(ThreadedDebugging) { |
5182 DebuggerThread debugger_thread; | 5171 DebuggerThread debugger_thread; |
5183 V8Thread v8_thread; | 5172 V8Thread v8_thread; |
5184 | 5173 |
5185 // Create a V8 environment | 5174 // Create a V8 environment |
5186 threaded_debugging_barriers.Initialize(); | |
5187 | |
5188 v8_thread.Start(); | 5175 v8_thread.Start(); |
5189 debugger_thread.Start(); | 5176 debugger_thread.Start(); |
5190 | 5177 |
5191 v8_thread.Join(); | 5178 v8_thread.Join(); |
5192 debugger_thread.Join(); | 5179 debugger_thread.Join(); |
5193 } | 5180 } |
5194 | 5181 |
5195 | 5182 |
5196 /* Test RecursiveBreakpoints */ | 5183 /* Test RecursiveBreakpoints */ |
5197 /* In this test, the debugger evaluates a function with a breakpoint, after | 5184 /* In this test, the debugger evaluates a function with a breakpoint, after |
(...skipping 25 matching lines...) Expand all Loading... |
5223 int evaluate_int_result; | 5210 int evaluate_int_result; |
5224 | 5211 |
5225 static void BreakpointsMessageHandler(const v8::Debug::Message& message) { | 5212 static void BreakpointsMessageHandler(const v8::Debug::Message& message) { |
5226 static char print_buffer[1000]; | 5213 static char print_buffer[1000]; |
5227 v8::String::Value json(message.GetJSON()); | 5214 v8::String::Value json(message.GetJSON()); |
5228 Utf16ToAscii(*json, json.length(), print_buffer); | 5215 Utf16ToAscii(*json, json.length(), print_buffer); |
5229 | 5216 |
5230 if (IsBreakEventMessage(print_buffer)) { | 5217 if (IsBreakEventMessage(print_buffer)) { |
5231 break_event_breakpoint_id = | 5218 break_event_breakpoint_id = |
5232 GetBreakpointIdFromBreakEventMessage(print_buffer); | 5219 GetBreakpointIdFromBreakEventMessage(print_buffer); |
5233 breakpoints_barriers->semaphore_1->Signal(); | 5220 breakpoints_barriers->semaphore_1.Signal(); |
5234 } else if (IsEvaluateResponseMessage(print_buffer)) { | 5221 } else if (IsEvaluateResponseMessage(print_buffer)) { |
5235 evaluate_int_result = GetEvaluateIntResult(print_buffer); | 5222 evaluate_int_result = GetEvaluateIntResult(print_buffer); |
5236 breakpoints_barriers->semaphore_1->Signal(); | 5223 breakpoints_barriers->semaphore_1.Signal(); |
5237 } | 5224 } |
5238 } | 5225 } |
5239 | 5226 |
5240 | 5227 |
5241 void BreakpointsV8Thread::Run() { | 5228 void BreakpointsV8Thread::Run() { |
5242 const char* source_1 = "var y_global = 3;\n" | 5229 const char* source_1 = "var y_global = 3;\n" |
5243 "function cat( new_value ) {\n" | 5230 "function cat( new_value ) {\n" |
5244 " var x = new_value;\n" | 5231 " var x = new_value;\n" |
5245 " y_global = y_global + 4;\n" | 5232 " y_global = y_global + 4;\n" |
5246 " x = 3 * x + 1;\n" | 5233 " x = 3 * x + 1;\n" |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5335 | 5322 |
5336 // v8 thread initializes, runs source_1 | 5323 // v8 thread initializes, runs source_1 |
5337 breakpoints_barriers->barrier_1.Wait(); | 5324 breakpoints_barriers->barrier_1.Wait(); |
5338 // 1:Set breakpoint in cat() (will get id 1). | 5325 // 1:Set breakpoint in cat() (will get id 1). |
5339 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer)); | 5326 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer)); |
5340 // 2:Set breakpoint in dog() (will get id 2). | 5327 // 2:Set breakpoint in dog() (will get id 2). |
5341 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); | 5328 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); |
5342 breakpoints_barriers->barrier_2.Wait(); | 5329 breakpoints_barriers->barrier_2.Wait(); |
5343 // V8 thread starts compiling source_2. | 5330 // V8 thread starts compiling source_2. |
5344 // Automatic break happens, to run queued commands | 5331 // Automatic break happens, to run queued commands |
5345 // breakpoints_barriers->semaphore_1->Wait(); | 5332 // breakpoints_barriers->semaphore_1.Wait(); |
5346 // Commands 1 through 3 run, thread continues. | 5333 // Commands 1 through 3 run, thread continues. |
5347 // v8 thread runs source_2 to breakpoint in cat(). | 5334 // v8 thread runs source_2 to breakpoint in cat(). |
5348 // message callback receives break event. | 5335 // message callback receives break event. |
5349 breakpoints_barriers->semaphore_1->Wait(); | 5336 breakpoints_barriers->semaphore_1.Wait(); |
5350 // Must have hit breakpoint #1. | 5337 // Must have hit breakpoint #1. |
5351 CHECK_EQ(1, break_event_breakpoint_id); | 5338 CHECK_EQ(1, break_event_breakpoint_id); |
5352 // 4:Evaluate dog() (which has a breakpoint). | 5339 // 4:Evaluate dog() (which has a breakpoint). |
5353 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_3, buffer)); | 5340 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_3, buffer)); |
5354 // V8 thread hits breakpoint in dog(). | 5341 // V8 thread hits breakpoint in dog(). |
5355 breakpoints_barriers->semaphore_1->Wait(); // wait for break event | 5342 breakpoints_barriers->semaphore_1.Wait(); // wait for break event |
5356 // Must have hit breakpoint #2. | 5343 // Must have hit breakpoint #2. |
5357 CHECK_EQ(2, break_event_breakpoint_id); | 5344 CHECK_EQ(2, break_event_breakpoint_id); |
5358 // 5:Evaluate (x + 1). | 5345 // 5:Evaluate (x + 1). |
5359 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_4, buffer)); | 5346 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_4, buffer)); |
5360 // Evaluate (x + 1) finishes. | 5347 // Evaluate (x + 1) finishes. |
5361 breakpoints_barriers->semaphore_1->Wait(); | 5348 breakpoints_barriers->semaphore_1.Wait(); |
5362 // Must have result 108. | 5349 // Must have result 108. |
5363 CHECK_EQ(108, evaluate_int_result); | 5350 CHECK_EQ(108, evaluate_int_result); |
5364 // 6:Continue evaluation of dog(). | 5351 // 6:Continue evaluation of dog(). |
5365 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_5, buffer)); | 5352 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_5, buffer)); |
5366 // Evaluate dog() finishes. | 5353 // Evaluate dog() finishes. |
5367 breakpoints_barriers->semaphore_1->Wait(); | 5354 breakpoints_barriers->semaphore_1.Wait(); |
5368 // Must have result 107. | 5355 // Must have result 107. |
5369 CHECK_EQ(107, evaluate_int_result); | 5356 CHECK_EQ(107, evaluate_int_result); |
5370 // 7:Continue evaluation of source_2, finish cat(17), hit breakpoint | 5357 // 7:Continue evaluation of source_2, finish cat(17), hit breakpoint |
5371 // in cat(19). | 5358 // in cat(19). |
5372 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_6, buffer)); | 5359 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_6, buffer)); |
5373 // Message callback gets break event. | 5360 // Message callback gets break event. |
5374 breakpoints_barriers->semaphore_1->Wait(); // wait for break event | 5361 breakpoints_barriers->semaphore_1.Wait(); // wait for break event |
5375 // Must have hit breakpoint #1. | 5362 // Must have hit breakpoint #1. |
5376 CHECK_EQ(1, break_event_breakpoint_id); | 5363 CHECK_EQ(1, break_event_breakpoint_id); |
5377 // 8: Evaluate dog() with breaks disabled. | 5364 // 8: Evaluate dog() with breaks disabled. |
5378 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_7, buffer)); | 5365 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_7, buffer)); |
5379 // Evaluate dog() finishes. | 5366 // Evaluate dog() finishes. |
5380 breakpoints_barriers->semaphore_1->Wait(); | 5367 breakpoints_barriers->semaphore_1.Wait(); |
5381 // Must have result 116. | 5368 // Must have result 116. |
5382 CHECK_EQ(116, evaluate_int_result); | 5369 CHECK_EQ(116, evaluate_int_result); |
5383 // 9: Continue evaluation of source2, reach end. | 5370 // 9: Continue evaluation of source2, reach end. |
5384 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_8, buffer)); | 5371 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_8, buffer)); |
5385 } | 5372 } |
5386 | 5373 |
5387 | 5374 |
5388 void TestRecursiveBreakpointsGeneric(bool global_evaluate) { | 5375 void TestRecursiveBreakpointsGeneric(bool global_evaluate) { |
5389 i::FLAG_debugger_auto_break = true; | 5376 i::FLAG_debugger_auto_break = true; |
5390 | 5377 |
5391 BreakpointsDebuggerThread breakpoints_debugger_thread(global_evaluate); | 5378 BreakpointsDebuggerThread breakpoints_debugger_thread(global_evaluate); |
5392 BreakpointsV8Thread breakpoints_v8_thread; | 5379 BreakpointsV8Thread breakpoints_v8_thread; |
5393 | 5380 |
5394 // Create a V8 environment | 5381 // Create a V8 environment |
5395 Barriers stack_allocated_breakpoints_barriers; | 5382 Barriers stack_allocated_breakpoints_barriers; |
5396 stack_allocated_breakpoints_barriers.Initialize(); | |
5397 breakpoints_barriers = &stack_allocated_breakpoints_barriers; | 5383 breakpoints_barriers = &stack_allocated_breakpoints_barriers; |
5398 | 5384 |
5399 breakpoints_v8_thread.Start(); | 5385 breakpoints_v8_thread.Start(); |
5400 breakpoints_debugger_thread.Start(); | 5386 breakpoints_debugger_thread.Start(); |
5401 | 5387 |
5402 breakpoints_v8_thread.Join(); | 5388 breakpoints_v8_thread.Join(); |
5403 breakpoints_debugger_thread.Join(); | 5389 breakpoints_debugger_thread.Join(); |
5404 } | 5390 } |
5405 | 5391 |
5406 | 5392 |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5779 Barriers* host_dispatch_barriers; | 5765 Barriers* host_dispatch_barriers; |
5780 | 5766 |
5781 static void HostDispatchMessageHandler(const v8::Debug::Message& message) { | 5767 static void HostDispatchMessageHandler(const v8::Debug::Message& message) { |
5782 static char print_buffer[1000]; | 5768 static char print_buffer[1000]; |
5783 v8::String::Value json(message.GetJSON()); | 5769 v8::String::Value json(message.GetJSON()); |
5784 Utf16ToAscii(*json, json.length(), print_buffer); | 5770 Utf16ToAscii(*json, json.length(), print_buffer); |
5785 } | 5771 } |
5786 | 5772 |
5787 | 5773 |
5788 static void HostDispatchDispatchHandler() { | 5774 static void HostDispatchDispatchHandler() { |
5789 host_dispatch_barriers->semaphore_1->Signal(); | 5775 host_dispatch_barriers->semaphore_1.Signal(); |
5790 } | 5776 } |
5791 | 5777 |
5792 | 5778 |
5793 void HostDispatchV8Thread::Run() { | 5779 void HostDispatchV8Thread::Run() { |
5794 const char* source_1 = "var y_global = 3;\n" | 5780 const char* source_1 = "var y_global = 3;\n" |
5795 "function cat( new_value ) {\n" | 5781 "function cat( new_value ) {\n" |
5796 " var x = new_value;\n" | 5782 " var x = new_value;\n" |
5797 " y_global = 4;\n" | 5783 " y_global = 4;\n" |
5798 " x = 3 * x + 1;\n" | 5784 " x = 3 * x + 1;\n" |
5799 " y_global = 5;\n" | 5785 " y_global = 5;\n" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5831 | 5817 |
5832 // v8 thread initializes, runs source_1 | 5818 // v8 thread initializes, runs source_1 |
5833 host_dispatch_barriers->barrier_1.Wait(); | 5819 host_dispatch_barriers->barrier_1.Wait(); |
5834 // 1: Set breakpoint in cat(). | 5820 // 1: Set breakpoint in cat(). |
5835 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer)); | 5821 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer)); |
5836 | 5822 |
5837 host_dispatch_barriers->barrier_2.Wait(); | 5823 host_dispatch_barriers->barrier_2.Wait(); |
5838 // v8 thread starts compiling source_2. | 5824 // v8 thread starts compiling source_2. |
5839 // Break happens, to run queued commands and host dispatches. | 5825 // Break happens, to run queued commands and host dispatches. |
5840 // Wait for host dispatch to be processed. | 5826 // Wait for host dispatch to be processed. |
5841 host_dispatch_barriers->semaphore_1->Wait(); | 5827 host_dispatch_barriers->semaphore_1.Wait(); |
5842 // 2: Continue evaluation | 5828 // 2: Continue evaluation |
5843 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); | 5829 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); |
5844 } | 5830 } |
5845 | 5831 |
5846 | 5832 |
5847 TEST(DebuggerHostDispatch) { | 5833 TEST(DebuggerHostDispatch) { |
5848 HostDispatchDebuggerThread host_dispatch_debugger_thread; | 5834 HostDispatchDebuggerThread host_dispatch_debugger_thread; |
5849 HostDispatchV8Thread host_dispatch_v8_thread; | 5835 HostDispatchV8Thread host_dispatch_v8_thread; |
5850 i::FLAG_debugger_auto_break = true; | 5836 i::FLAG_debugger_auto_break = true; |
5851 | 5837 |
5852 // Create a V8 environment | 5838 // Create a V8 environment |
5853 Barriers stack_allocated_host_dispatch_barriers; | 5839 Barriers stack_allocated_host_dispatch_barriers; |
5854 stack_allocated_host_dispatch_barriers.Initialize(); | |
5855 host_dispatch_barriers = &stack_allocated_host_dispatch_barriers; | 5840 host_dispatch_barriers = &stack_allocated_host_dispatch_barriers; |
5856 | 5841 |
5857 host_dispatch_v8_thread.Start(); | 5842 host_dispatch_v8_thread.Start(); |
5858 host_dispatch_debugger_thread.Start(); | 5843 host_dispatch_debugger_thread.Start(); |
5859 | 5844 |
5860 host_dispatch_v8_thread.Join(); | 5845 host_dispatch_v8_thread.Join(); |
5861 host_dispatch_debugger_thread.Join(); | 5846 host_dispatch_debugger_thread.Join(); |
5862 } | 5847 } |
5863 | 5848 |
5864 | 5849 |
(...skipping 13 matching lines...) Expand all Loading... |
5878 public: | 5863 public: |
5879 DebugMessageDispatchDebuggerThread() | 5864 DebugMessageDispatchDebuggerThread() |
5880 : Thread("DebugMessageDispatchDebuggerThread") { } | 5865 : Thread("DebugMessageDispatchDebuggerThread") { } |
5881 void Run(); | 5866 void Run(); |
5882 }; | 5867 }; |
5883 | 5868 |
5884 Barriers* debug_message_dispatch_barriers; | 5869 Barriers* debug_message_dispatch_barriers; |
5885 | 5870 |
5886 | 5871 |
5887 static void DebugMessageHandler() { | 5872 static void DebugMessageHandler() { |
5888 debug_message_dispatch_barriers->semaphore_1->Signal(); | 5873 debug_message_dispatch_barriers->semaphore_1.Signal(); |
5889 } | 5874 } |
5890 | 5875 |
5891 | 5876 |
5892 void DebugMessageDispatchV8Thread::Run() { | 5877 void DebugMessageDispatchV8Thread::Run() { |
5893 v8::V8::Initialize(); | 5878 v8::V8::Initialize(); |
5894 DebugLocalContext env; | 5879 DebugLocalContext env; |
5895 v8::HandleScope scope(env->GetIsolate()); | 5880 v8::HandleScope scope(env->GetIsolate()); |
5896 | 5881 |
5897 // Set up debug message dispatch handler. | 5882 // Set up debug message dispatch handler. |
5898 v8::Debug::SetDebugMessageDispatchHandler(DebugMessageHandler); | 5883 v8::Debug::SetDebugMessageDispatchHandler(DebugMessageHandler); |
5899 | 5884 |
5900 CompileRun("var y = 1 + 2;\n"); | 5885 CompileRun("var y = 1 + 2;\n"); |
5901 debug_message_dispatch_barriers->barrier_1.Wait(); | 5886 debug_message_dispatch_barriers->barrier_1.Wait(); |
5902 debug_message_dispatch_barriers->semaphore_1->Wait(); | 5887 debug_message_dispatch_barriers->semaphore_1.Wait(); |
5903 debug_message_dispatch_barriers->barrier_2.Wait(); | 5888 debug_message_dispatch_barriers->barrier_2.Wait(); |
5904 } | 5889 } |
5905 | 5890 |
5906 | 5891 |
5907 void DebugMessageDispatchDebuggerThread::Run() { | 5892 void DebugMessageDispatchDebuggerThread::Run() { |
5908 debug_message_dispatch_barriers->barrier_1.Wait(); | 5893 debug_message_dispatch_barriers->barrier_1.Wait(); |
5909 SendContinueCommand(); | 5894 SendContinueCommand(); |
5910 debug_message_dispatch_barriers->barrier_2.Wait(); | 5895 debug_message_dispatch_barriers->barrier_2.Wait(); |
5911 } | 5896 } |
5912 | 5897 |
5913 | 5898 |
5914 TEST(DebuggerDebugMessageDispatch) { | 5899 TEST(DebuggerDebugMessageDispatch) { |
5915 DebugMessageDispatchDebuggerThread debug_message_dispatch_debugger_thread; | 5900 DebugMessageDispatchDebuggerThread debug_message_dispatch_debugger_thread; |
5916 DebugMessageDispatchV8Thread debug_message_dispatch_v8_thread; | 5901 DebugMessageDispatchV8Thread debug_message_dispatch_v8_thread; |
5917 | 5902 |
5918 i::FLAG_debugger_auto_break = true; | 5903 i::FLAG_debugger_auto_break = true; |
5919 | 5904 |
5920 // Create a V8 environment | 5905 // Create a V8 environment |
5921 Barriers stack_allocated_debug_message_dispatch_barriers; | 5906 Barriers stack_allocated_debug_message_dispatch_barriers; |
5922 stack_allocated_debug_message_dispatch_barriers.Initialize(); | |
5923 debug_message_dispatch_barriers = | 5907 debug_message_dispatch_barriers = |
5924 &stack_allocated_debug_message_dispatch_barriers; | 5908 &stack_allocated_debug_message_dispatch_barriers; |
5925 | 5909 |
5926 debug_message_dispatch_v8_thread.Start(); | 5910 debug_message_dispatch_v8_thread.Start(); |
5927 debug_message_dispatch_debugger_thread.Start(); | 5911 debug_message_dispatch_debugger_thread.Start(); |
5928 | 5912 |
5929 debug_message_dispatch_v8_thread.Join(); | 5913 debug_message_dispatch_v8_thread.Join(); |
5930 debug_message_dispatch_debugger_thread.Join(); | 5914 debug_message_dispatch_debugger_thread.Join(); |
5931 } | 5915 } |
5932 | 5916 |
(...skipping 1615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7548 TEST(LiveEditDisabled) { | 7532 TEST(LiveEditDisabled) { |
7549 v8::internal::FLAG_allow_natives_syntax = true; | 7533 v8::internal::FLAG_allow_natives_syntax = true; |
7550 LocalContext env; | 7534 LocalContext env; |
7551 v8::HandleScope scope(env->GetIsolate()); | 7535 v8::HandleScope scope(env->GetIsolate()); |
7552 v8::Debug::SetLiveEditEnabled(false); | 7536 v8::Debug::SetLiveEditEnabled(false); |
7553 CompileRun("%LiveEditCompareStrings('', '')"); | 7537 CompileRun("%LiveEditCompareStrings('', '')"); |
7554 } | 7538 } |
7555 | 7539 |
7556 | 7540 |
7557 #endif // ENABLE_DEBUGGER_SUPPORT | 7541 #endif // ENABLE_DEBUGGER_SUPPORT |
OLD | NEW |