| Index: test/cctest/test-debug.cc
|
| diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
|
| index bfbd54bd2abe12e056b288f4a16572c041bea9fa..fea07c564696d03c62538da2cd34616faf834d45 100644
|
| --- a/test/cctest/test-debug.cc
|
| +++ b/test/cctest/test-debug.cc
|
| @@ -3564,13 +3564,17 @@ TEST(MessageQueueExpandAndDestroy) {
|
| new TestClientData()));
|
| queue.Put(Message::NewCommand(Vector<uint16_t>::empty(),
|
| new TestClientData()));
|
| - queue.Put(Message::NewHostDispatch(new TestClientData()));
|
| + queue.Put(Message::NewCommand(Vector<uint16_t>::empty(),
|
| + new TestClientData()));
|
| ASSERT_EQ(0, TestClientData::destructor_call_counter);
|
| queue.Get().Dispose();
|
| ASSERT_EQ(1, TestClientData::destructor_call_counter);
|
| - queue.Put(Message::NewHostDispatch(new TestClientData()));
|
| - queue.Put(Message::NewHostDispatch(new TestClientData()));
|
| - queue.Put(Message::NewHostDispatch(new TestClientData()));
|
| + queue.Put(Message::NewCommand(Vector<uint16_t>::empty(),
|
| + new TestClientData()));
|
| + queue.Put(Message::NewCommand(Vector<uint16_t>::empty(),
|
| + new TestClientData()));
|
| + queue.Put(Message::NewCommand(Vector<uint16_t>::empty(),
|
| + new TestClientData()));
|
| queue.Put(Message::NewOutput(v8::Handle<v8::String>(),
|
| new TestClientData()));
|
| queue.Put(Message::NewEmptyMessage());
|
| @@ -4219,53 +4223,107 @@ TEST(DebuggerClearMessageHandlerWhileActive) {
|
| }
|
|
|
|
|
| -int host_dispatch_hit_count = 0;
|
| -static void HostDispatchHandlerHitCount(v8::Debug::ClientData* dispatch) {
|
| - host_dispatch_hit_count++;
|
| +/* Test DebuggerHostDispatch */
|
| +/* In this test, the debugger waits for a command on a breakpoint
|
| + * and is dispatching host commands while in the infinite loop.
|
| + */
|
| +
|
| +class HostDispatchV8Thread : public v8::internal::Thread {
|
| + public:
|
| + void Run();
|
| +};
|
| +
|
| +class HostDispatchDebuggerThread : public v8::internal::Thread {
|
| + public:
|
| + void Run();
|
| +};
|
| +
|
| +Barriers* host_dispatch_barriers;
|
| +
|
| +static void HostDispatchMessageHandler(const uint16_t* message,
|
| + int length,
|
| + v8::Debug::ClientData* client_data) {
|
| + static char print_buffer[1000];
|
| + Utf16ToAscii(message, length, print_buffer);
|
| + printf("%s\n", print_buffer);
|
| + fflush(stdout);
|
| +}
|
| +
|
| +
|
| +static void HostDispatchDispatchHandler() {
|
| + host_dispatch_barriers->semaphore_1->Signal();
|
| }
|
|
|
|
|
| -// Test that clearing the debug event listener actually clears all break points
|
| -// and related information.
|
| -TEST(DebuggerHostDispatch) {
|
| - i::FLAG_debugger_auto_break = true;
|
| +void HostDispatchV8Thread::Run() {
|
| + const char* source_1 = "var y_global = 3;\n"
|
| + "function cat( new_value ) {\n"
|
| + " var x = new_value;\n"
|
| + " y_global = 4;\n"
|
| + " x = 3 * x + 1;\n"
|
| + " y_global = 5;\n"
|
| + " return x;\n"
|
| + "}\n"
|
| + "\n";
|
| + const char* source_2 = "cat(17);\n";
|
|
|
| v8::HandleScope scope;
|
| DebugLocalContext env;
|
|
|
| - const int kBufferSize = 1000;
|
| - uint16_t buffer[kBufferSize];
|
| - const char* command_continue =
|
| - "{\"seq\":0,"
|
| - "\"type\":\"request\","
|
| - "\"command\":\"continue\"}";
|
| + // Setup message and host dispatch handlers.
|
| + v8::Debug::SetMessageHandler(HostDispatchMessageHandler);
|
| + v8::Debug::SetHostDispatchHandler(HostDispatchDispatchHandler, 10 /* ms */);
|
|
|
| - // Create an empty function to call for processing debug commands
|
| - v8::Local<v8::Function> empty =
|
| - CompileFunction(&env, "function empty(){}", "empty");
|
| + CompileRun(source_1);
|
| + host_dispatch_barriers->barrier_1.Wait();
|
| + host_dispatch_barriers->barrier_2.Wait();
|
| + CompileRun(source_2);
|
| +}
|
|
|
| - // Setup message and host dispatch handlers.
|
| - v8::Debug::SetMessageHandler(DummyMessageHandler);
|
| - v8::Debug::SetHostDispatchHandler(HostDispatchHandlerHitCount);
|
|
|
| - // Send a host dispatch by itself.
|
| - v8::Debug::SendHostDispatch(NULL);
|
| - empty->Call(env->Global(), 0, NULL); // Run JavaScript to activate debugger.
|
| - CHECK_EQ(1, host_dispatch_hit_count);
|
| +void HostDispatchDebuggerThread::Run() {
|
| + const int kBufSize = 1000;
|
| + uint16_t buffer[kBufSize];
|
|
|
| - // Fill a host dispatch and a continue command on the command queue.
|
| - v8::Debug::SendHostDispatch(NULL);
|
| - v8::Debug::SendCommand(buffer, AsciiToUtf16(command_continue, buffer));
|
| - empty->Call(env->Global(), 0, NULL); // Run JavaScript to activate debugger.
|
| + const char* command_1 = "{\"seq\":101,"
|
| + "\"type\":\"request\","
|
| + "\"command\":\"setbreakpoint\","
|
| + "\"arguments\":{\"type\":\"function\",\"target\":\"cat\",\"line\":3}}";
|
| + const char* command_2 = "{\"seq\":102,"
|
| + "\"type\":\"request\","
|
| + "\"command\":\"continue\"}";
|
|
|
| - // Fill a continue command and a host dispatch on the command queue.
|
| - v8::Debug::SendCommand(buffer, AsciiToUtf16(command_continue, buffer));
|
| - v8::Debug::SendHostDispatch(NULL);
|
| - empty->Call(env->Global(), 0, NULL); // Run JavaScript to activate debugger.
|
| - empty->Call(env->Global(), 0, NULL); // Run JavaScript to activate debugger.
|
| + // v8 thread initializes, runs source_1
|
| + host_dispatch_barriers->barrier_1.Wait();
|
| + // 1: Set breakpoint in cat().
|
| + v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer));
|
| +
|
| + host_dispatch_barriers->barrier_2.Wait();
|
| + // v8 thread starts compiling source_2.
|
| + // Break happens, to run queued commands and host dispatches.
|
| + // Wait for host dispatch to be processed.
|
| + host_dispatch_barriers->semaphore_1->Wait();
|
| + // 2: Continue evaluation
|
| + v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer));
|
| +}
|
| +
|
| +HostDispatchDebuggerThread host_dispatch_debugger_thread;
|
| +HostDispatchV8Thread host_dispatch_v8_thread;
|
| +
|
| +
|
| +TEST(DebuggerHostDispatch) {
|
| + i::FLAG_debugger_auto_break = true;
|
| +
|
| + // Create a V8 environment
|
| + Barriers stack_allocated_host_dispatch_barriers;
|
| + stack_allocated_host_dispatch_barriers.Initialize();
|
| + host_dispatch_barriers = &stack_allocated_host_dispatch_barriers;
|
| +
|
| + host_dispatch_v8_thread.Start();
|
| + host_dispatch_debugger_thread.Start();
|
|
|
| - // All the host dispatch callback should be called.
|
| - CHECK_EQ(3, host_dispatch_hit_count);
|
| + host_dispatch_v8_thread.Join();
|
| + host_dispatch_debugger_thread.Join();
|
| }
|
|
|
|
|
|
|