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

Side by Side Diff: test/cctest/test-debug.cc

Issue 23797003: Fix race conditions in cctest/test-debug. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 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 | Annotate | Revision Log
« 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 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
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
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
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
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
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
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
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
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
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
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
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
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