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

Unified Diff: src/debug.cc

Issue 292713002: Revert "Simplify debugger state." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/debug.h ('k') | src/execution.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/debug.cc
diff --git a/src/debug.cc b/src/debug.cc
index 059c144832ffa66d21d7da85c564675b364b6c86..e3cbf326c8e533bd97702bc8285c92270d41522b 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -45,6 +45,10 @@ Debug::Debug(Isolate* isolate)
}
+Debug::~Debug() {
+}
+
+
static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) {
Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
// Isolate::context() may have been NULL when "script collected" event
@@ -690,7 +694,9 @@ bool Debug::CompileDebuggerScript(Isolate* isolate, int index) {
HandleScope scope(isolate);
// Bail out if the index is invalid.
- if (index == -1) return false;
+ if (index == -1) {
+ return false;
+ }
// Find source and name for the requested script.
Handle<String> source_code =
@@ -756,11 +762,13 @@ bool Debug::Load() {
// Return if debugger is already loaded.
if (IsLoaded()) return true;
+ Debugger* debugger = isolate_->debugger();
+
// Bail out if we're already in the process of compiling the native
// JavaScript source code for the debugger.
- if (isolate_->debugger()->ignore_debugger()) return false;
- Debugger::IgnoreScope during_create(isolate_->debugger());
+ if (debugger->ignore_debugger()) return false;
+ Debugger::IgnoreScope during_load(debugger);
// Disable breakpoints and interrupts while compiling and running the
// debugger scripts including the context creation code.
DisableBreak disable(isolate_, true);
@@ -785,13 +793,14 @@ bool Debug::Load() {
// Expose the builtins object in the debugger context.
Handle<String> key = isolate_->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("builtins"));
- Handle<GlobalObject> global =
- Handle<GlobalObject>(context->global_object(), isolate_);
- Handle<JSBuiltinsObject> builtin =
- Handle<JSBuiltinsObject>(global->builtins(), isolate_);
+ Handle<GlobalObject> global = Handle<GlobalObject>(context->global_object());
RETURN_ON_EXCEPTION_VALUE(
isolate_,
- JSReceiver::SetProperty(global, key, builtin, NONE, SLOPPY),
+ JSReceiver::SetProperty(global,
+ key,
+ Handle<Object>(global->builtins(), isolate_),
+ NONE,
+ SLOPPY),
false);
// Compile the JavaScript for the debugger in the debugger context.
@@ -803,24 +812,32 @@ bool Debug::Load() {
caught_exception = caught_exception ||
!CompileDebuggerScript(isolate_, Natives::GetIndex("liveedit"));
}
+
+ // Make sure we mark the debugger as not loading before we might
+ // return.
+
// Check for caught exceptions.
if (caught_exception) return false;
+ // Debugger loaded, create debugger context global handle.
debug_context_ = Handle<Context>::cast(
isolate_->global_handles()->Create(*context));
+
return true;
}
void Debug::Unload() {
// Return debugger is not loaded.
- if (!IsLoaded()) return;
+ if (!IsLoaded()) {
+ return;
+ }
// Clear the script cache.
DestroyScriptCache();
// Clear debugger context global handle.
- GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location());
+ GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location()));
debug_context_ = Handle<Context>();
}
@@ -837,7 +854,7 @@ Object* Debug::Break(Arguments args) {
JavaScriptFrame* frame = it.frame();
// Just continue if breaks are disabled or debugger cannot be loaded.
- if (disable_break()) {
+ if (disable_break() || !Load()) {
SetAfterBreakTarget(frame);
return heap->undefined_value();
}
@@ -2612,7 +2629,9 @@ Debugger::Debugger(Isolate* isolate)
is_active_(false),
ignore_debugger_(false),
live_edit_enabled_(true),
+ never_unload_debugger_(false),
message_handler_(NULL),
+ debugger_unload_pending_(false),
command_queue_(isolate->logger(), kQueueInitialSize),
command_received_(0),
event_command_queue_(isolate->logger(), kQueueInitialSize),
@@ -2969,17 +2988,36 @@ void Debugger::CallJSEventCallback(v8::DebugEvent event,
Handle<Context> Debugger::GetDebugContext() {
+ never_unload_debugger_ = true;
EnterDebugger debugger(isolate_);
return isolate_->debug()->debug_context();
}
+void Debugger::UnloadDebugger() {
+ Debug* debug = isolate_->debug();
+
+ // Make sure that there are no breakpoints left.
+ debug->ClearAllBreakPoints();
+
+ // Unload the debugger if feasible.
+ if (!never_unload_debugger_) {
+ debug->Unload();
+ }
+
+ // Clear the flag indicating that the debugger should be unloaded.
+ debugger_unload_pending_ = false;
+}
+
+
void Debugger::NotifyMessageHandler(v8::DebugEvent event,
Handle<JSObject> exec_state,
Handle<JSObject> event_data,
bool auto_continue) {
- ASSERT(is_active_);
HandleScope scope(isolate_);
+
+ if (!isolate_->debug()->Load()) return;
+
// Process the individual events.
bool sendEventMessage = false;
switch (event) {
@@ -3107,60 +3145,77 @@ void Debugger::NotifyMessageHandler(v8::DebugEvent event,
void Debugger::SetEventListener(Handle<Object> callback,
Handle<Object> data) {
+ HandleScope scope(isolate_);
GlobalHandles* global_handles = isolate_->global_handles();
- // Remove existing entry.
- GlobalHandles::Destroy(event_listener_.location());
- event_listener_ = Handle<Object>();
- GlobalHandles::Destroy(event_listener_data_.location());
- event_listener_data_ = Handle<Object>();
+ // Clear the global handles for the event listener and the event listener data
+ // object.
+ if (!event_listener_.is_null()) {
+ GlobalHandles::Destroy(
+ reinterpret_cast<Object**>(event_listener_.location()));
+ event_listener_ = Handle<Object>();
+ }
+ if (!event_listener_data_.is_null()) {
+ GlobalHandles::Destroy(
+ reinterpret_cast<Object**>(event_listener_data_.location()));
+ event_listener_data_ = Handle<Object>();
+ }
- // Set new entry.
+ // If there is a new debug event listener register it together with its data
+ // object.
if (!callback->IsUndefined() && !callback->IsNull()) {
- event_listener_ = global_handles->Create(*callback);
- if (data.is_null()) data = isolate_->factory()->undefined_value();
- event_listener_data_ = global_handles->Create(*data);
+ event_listener_ = Handle<Object>::cast(
+ global_handles->Create(*callback));
+ if (data.is_null()) {
+ data = isolate_->factory()->undefined_value();
+ }
+ event_listener_data_ = Handle<Object>::cast(
+ global_handles->Create(*data));
}
- UpdateState();
+ ListenersChanged();
}
void Debugger::SetMessageHandler(v8::Debug::MessageHandler handler) {
+ LockGuard<RecursiveMutex> with(&debugger_access_);
+
message_handler_ = handler;
- UpdateState();
- if (handler == NULL && isolate_->debug()->InDebugger()) {
+ ListenersChanged();
+ if (handler == NULL) {
// Send an empty command to the debugger if in a break to make JavaScript
// run again if the debugger is closed.
- EnqueueCommandMessage(Vector<const uint16_t>::empty());
+ if (isolate_->debug()->InDebugger()) {
+ EnqueueCommandMessage(Vector<const uint16_t>::empty());
+ }
}
}
-void Debugger::UpdateState() {
- bool activate = message_handler_ != NULL ||
- !event_listener_.is_null() ||
- isolate_->debug()->InDebugger();
- if (!is_active_ && activate) {
- // Note that the debug context could have already been loaded to
- // bootstrap test cases.
+void Debugger::ListenersChanged() {
+ LockGuard<RecursiveMutex> with(&debugger_access_);
+ is_active_ = message_handler_ != NULL || !event_listener_.is_null();
+ if (is_active_) {
+ // Disable the compilation cache when the debugger is active.
isolate_->compilation_cache()->Disable();
- activate = isolate_->debug()->Load();
- } else if (is_active_ && !activate) {
+ debugger_unload_pending_ = false;
+ } else {
isolate_->compilation_cache()->Enable();
- isolate_->debug()->ClearAllBreakPoints();
- isolate_->debug()->Unload();
+ // Unload the debugger if event listener and message handler cleared.
+ // Schedule this for later, because we may be in non-V8 thread.
+ debugger_unload_pending_ = true;
}
- is_active_ = activate;
- // At this point the debug context is loaded iff the debugger is active.
- ASSERT(isolate_->debug()->IsLoaded() == is_active_);
}
// Calls the registered debug message handler. This callback is part of the
// public API.
void Debugger::InvokeMessageHandler(MessageImpl message) {
- if (message_handler_ != NULL) message_handler_(message);
+ LockGuard<RecursiveMutex> with(&debugger_access_);
+
+ if (message_handler_ != NULL) {
+ message_handler_(message);
+ }
}
@@ -3204,6 +3259,9 @@ void Debugger::EnqueueDebugCommand(v8::Debug::ClientData* client_data) {
MaybeHandle<Object> Debugger::Call(Handle<JSFunction> fun,
Handle<Object> data) {
+ // When calling functions in the debugger prevent it from beeing unloaded.
+ Debugger::never_unload_debugger_ = true;
+
// Enter the debugger.
EnterDebugger debugger(isolate_);
if (debugger.FailedToEnter()) {
@@ -3230,9 +3288,10 @@ MaybeHandle<Object> Debugger::Call(Handle<JSFunction> fun,
EnterDebugger::EnterDebugger(Isolate* isolate)
: isolate_(isolate),
prev_(isolate_->debug()->debugger_entry()),
+ it_(isolate_),
+ has_js_frames_(!it_.done()),
save_(isolate_) {
Debug* debug = isolate_->debug();
-
// Link recursive debugger entry.
debug->set_debugger_entry(this);
@@ -3242,24 +3301,25 @@ EnterDebugger::EnterDebugger(Isolate* isolate)
// Create the new break info. If there is no JavaScript frames there is no
// break frame id.
- JavaScriptFrameIterator it(isolate_);
- has_js_frames_ = !it.done();
- debug->NewBreak(has_js_frames_ ? it.frame()->id() : StackFrame::NO_ID);
+ if (has_js_frames_) {
+ debug->NewBreak(it_.frame()->id());
+ } else {
+ debug->NewBreak(StackFrame::NO_ID);
+ }
- isolate_->debugger()->UpdateState();
// Make sure that debugger is loaded and enter the debugger context.
- // The previous context is kept in save_.
- load_failed_ = !debug->IsLoaded();
- if (!load_failed_) isolate_->set_context(*debug->debug_context());
+ load_failed_ = !debug->Load();
+ if (!load_failed_) {
+ // NOTE the member variable save which saves the previous context before
+ // this change.
+ isolate_->set_context(*debug->debug_context());
+ }
}
EnterDebugger::~EnterDebugger() {
Debug* debug = isolate_->debug();
- // Leaving this debugger entry.
- debug->set_debugger_entry(prev_);
-
// Restore to the previous break state.
debug->SetBreak(break_frame_id_, break_id_);
@@ -3291,9 +3351,15 @@ EnterDebugger::~EnterDebugger() {
if (isolate_->debugger()->HasCommands()) {
isolate_->stack_guard()->RequestDebugCommand();
}
+
+ // If leaving the debugger with the debugger no longer active unload it.
+ if (!isolate_->debugger()->is_active()) {
+ isolate_->debugger()->UnloadDebugger();
+ }
}
- isolate_->debugger()->UpdateState();
+ // Leaving this debugger entry.
+ debug->set_debugger_entry(prev_);
}
« no previous file with comments | « src/debug.h ('k') | src/execution.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698