1. Send 'afterCompile' event to the debug message handler.2. Process messages from the debugger command queue on each event not only break and exception.3. auto_continue is always true for compilation events.

Review URL: http://codereview.chromium.org/100034

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1801 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
yurys@chromium.org 2009-04-27 12:38:20 +00:00
parent 889eac7f13
commit c56b22c72a
3 changed files with 48 additions and 28 deletions

View File

@ -977,6 +977,7 @@ CompileEvent.prototype.script = function() {
CompileEvent.prototype.toJSONProtocol = function() {
var o = new ProtocolMessage();
o.running = true;
if (this.before_) {
o.event = "beforeCompile";
} else {

View File

@ -1612,7 +1612,7 @@ void Debugger::OnBeforeCompile(Handle<Script> script) {
}
// Process debug event
ProcessDebugEvent(v8::BeforeCompile, event_data, false);
ProcessDebugEvent(v8::BeforeCompile, event_data, true);
}
@ -1673,7 +1673,7 @@ void Debugger::OnAfterCompile(Handle<Script> script, Handle<JSFunction> fun) {
return;
}
// Process debug event
ProcessDebugEvent(v8::AfterCompile, event_data, false);
ProcessDebugEvent(v8::AfterCompile, event_data, true);
}
@ -1698,7 +1698,7 @@ void Debugger::OnNewFunction(Handle<JSFunction> function) {
return;
}
// Process debug event.
ProcessDebugEvent(v8::NewFunction, event_data, false);
ProcessDebugEvent(v8::NewFunction, event_data, true);
}
@ -1776,17 +1776,18 @@ void Debugger::NotifyMessageHandler(v8::DebugEvent event,
if (!Debug::Load()) return;
// Process the individual events.
bool interactive = false;
bool sendEventMessage = false;
switch (event) {
case v8::Break:
interactive = true; // Break event is always interactive
sendEventMessage = !auto_continue;
break;
case v8::Exception:
interactive = true; // Exception event is always interactive
sendEventMessage = true;
break;
case v8::BeforeCompile:
break;
case v8::AfterCompile:
sendEventMessage = true;
break;
case v8::NewFunction:
break;
@ -1794,8 +1795,20 @@ void Debugger::NotifyMessageHandler(v8::DebugEvent event,
UNREACHABLE();
}
// Done if not interactive.
if (!interactive) return;
// The debug command interrupt flag might have been set when the command was
// added. It should be enough to clear the flag only once while we are in the
// debugger.
ASSERT(Debug::InDebugger());
StackGuard::Continue(DEBUGCOMMAND);
// Notify the debugger that a debug event has occurred unless auto continue is
// active in which case no event is send.
if (sendEventMessage) {
InvokeMessageHandlerWithEvent(event_data);
}
if (auto_continue && !HasCommands()) {
return;
}
// Get the DebugCommandProcessor.
v8::Local<v8::Object> api_exec_state =
@ -1812,16 +1825,6 @@ void Debugger::NotifyMessageHandler(v8::DebugEvent event,
return;
}
// Notify the debugger that a debug event has occurred unless auto continue is
// active in which case no event is send.
if (!auto_continue) {
bool success = InvokeMessageHandlerWithEvent(event_data);
if (!success) {
// If failed to notify debugger just continue running.
return;
}
}
// Process requests from the debugger.
while (true) {
// Wait for new command in the queue.
@ -1837,10 +1840,6 @@ void Debugger::NotifyMessageHandler(v8::DebugEvent event,
command_received_->Wait();
}
// The debug command interrupt flag might have been set when the command was
// added.
StackGuard::Continue(DEBUGCOMMAND);
// Get the command from the queue.
CommandMessage command = command_queue_.Get();
Logger::DebugTag("Got request from command queue, in interactive loop.");

View File

@ -3436,6 +3436,7 @@ static void MessageHandler(const uint16_t* message, int length,
// Signals when a break is reported.
message_queue_barriers.semaphore_2->Signal();
}
// Allow message handler to block on a semaphore, to test queueing of
// messages while blocked.
message_queue_barriers.semaphore_1->Wait();
@ -3474,6 +3475,7 @@ void MessageQueueDebuggerThread::Run() {
/* Interleaved sequence of actions by the two threads:*/
// Main thread compiles and runs source_1
message_queue_barriers.semaphore_1->Signal();
message_queue_barriers.barrier_1.Wait();
// Post 6 commands, filling the command queue and making it expand.
// These calls return immediately, but the commands stay on the queue
@ -3487,22 +3489,39 @@ void MessageQueueDebuggerThread::Run() {
v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2));
message_queue_barriers.barrier_2.Wait();
// Main thread compiles and runs source_2.
// Queued commands are executed at the start of compilation of source_2.
message_queue_barriers.barrier_3.Wait();
// Free the message handler to process all the messages from the queue.
for (int i = 0; i < 20 ; ++i) {
// Queued commands are executed at the start of compilation of source_2(
// beforeCompile event).
// Free the message handler to process all the messages from the queue. 7
// messages are expected: 2 afterCompile events and 5 responses.
// All the commands added so far will fail to execute as long as call stack
// is empty on beforeCompile event.
for (int i = 0; i < 6 ; ++i) {
message_queue_barriers.semaphore_1->Signal();
}
message_queue_barriers.barrier_3.Wait();
// Main thread compiles and runs source_3.
// Don't stop in the afterCompile handler.
message_queue_barriers.semaphore_1->Signal();
// source_3 includes a debugger statement, which causes a break event.
// Wait on break event from hitting "debugger" statement
message_queue_barriers.semaphore_2->Wait();
// These should execute after the "debugger" statement in source_2
v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_1, buffer_1));
v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_2, buffer_2));
v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2));
v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_single_step, buffer_2));
// Run after 2 break events, 4 responses.
for (int i = 0; i < 6 ; ++i) {
message_queue_barriers.semaphore_1->Signal();
}
// Wait on break event after a single step executes.
message_queue_barriers.semaphore_2->Wait();
v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_2, buffer_1));
v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_continue, buffer_2));
// Run after 2 responses.
for (int i = 0; i < 2 ; ++i) {
message_queue_barriers.semaphore_1->Signal();
}
// Main thread continues running source_3 to end, waits for this thread.
}
@ -3610,7 +3629,7 @@ TEST(SendClientDataToHandler) {
TestClientData::ResetCounters();
handled_client_data_instances_count = 0;
v8::Debug::SetMessageHandler(MessageHandlerCountingClientData);
const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5; debugger;";
const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;";
const int kBufferSize = 1000;
uint16_t buffer[kBufferSize];
const char* command_1 =
@ -3635,8 +3654,9 @@ TEST(SendClientDataToHandler) {
new TestClientData());
v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer),
new TestClientData());
v8::Debug::SendCommand(buffer, AsciiToUtf16(command_continue, buffer));
// All the messages will be processed on beforeCompile event.
CompileRun(source_1);
v8::Debug::SendCommand(buffer, AsciiToUtf16(command_continue, buffer));
CHECK_EQ(3, TestClientData::constructor_call_counter);
CHECK_EQ(TestClientData::constructor_call_counter,
handled_client_data_instances_count);