Simplify debugger state.

R=ulan@chromium.org

Review URL: https://codereview.chromium.org/287873005

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21346 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
yangguo@chromium.org 2014-05-16 14:58:03 +00:00
parent 5cfca21295
commit 2d1a75d608
10 changed files with 113 additions and 208 deletions

View File

@ -2120,20 +2120,18 @@ bool Genesis::InstallSpecialObjects(Handle<Context> native_context) {
// Expose the debug global object in global if a name for it is specified. // Expose the debug global object in global if a name for it is specified.
if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) { if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
Debug* debug = isolate->debug();
// If loading fails we just bail out without installing the // If loading fails we just bail out without installing the
// debugger but without tanking the whole context. // debugger but without tanking the whole context.
Debug* debug = isolate->debug();
if (!debug->Load()) return true; if (!debug->Load()) return true;
Handle<Context> debug_context = debug->debug_context();
// Set the security token for the debugger context to the same as // Set the security token for the debugger context to the same as
// the shell native context to allow calling between these (otherwise // the shell native context to allow calling between these (otherwise
// exposing debug global object doesn't make much sense). // exposing debug global object doesn't make much sense).
debug->debug_context()->set_security_token( debug_context->set_security_token(native_context->security_token());
native_context->security_token());
Handle<String> debug_string = Handle<String> debug_string =
factory->InternalizeUtf8String(FLAG_expose_debug_as); factory->InternalizeUtf8String(FLAG_expose_debug_as);
Handle<Object> global_proxy( Handle<Object> global_proxy(debug_context->global_proxy(), isolate);
debug->debug_context()->global_proxy(), isolate);
RETURN_ON_EXCEPTION_VALUE( RETURN_ON_EXCEPTION_VALUE(
isolate, isolate,
JSObject::SetLocalPropertyIgnoreAttributes( JSObject::SetLocalPropertyIgnoreAttributes(

View File

@ -753,11 +753,12 @@ void Shell::InstallUtilityScript(Isolate* isolate) {
// Install the debugger object in the utility scope // Install the debugger object in the utility scope
i::Debug* debug = reinterpret_cast<i::Isolate*>(isolate)->debug(); i::Debug* debug = reinterpret_cast<i::Isolate*>(isolate)->debug();
debug->Load(); debug->Load();
i::Handle<i::Context> debug_context = debug->debug_context();
i::Handle<i::JSObject> js_debug i::Handle<i::JSObject> js_debug
= i::Handle<i::JSObject>(debug->debug_context()->global_object()); = i::Handle<i::JSObject>(debug_context->global_object());
utility_context->Global()->Set(String::NewFromUtf8(isolate, "$debug"), utility_context->Global()->Set(String::NewFromUtf8(isolate, "$debug"),
Utils::ToLocal(js_debug)); Utils::ToLocal(js_debug));
debug->debug_context()->set_security_token( debug_context->set_security_token(
reinterpret_cast<i::Isolate*>(isolate)->heap()->undefined_value()); reinterpret_cast<i::Isolate*>(isolate)->heap()->undefined_value());
// Run the d8 shell utility script in the utility context // Run the d8 shell utility script in the utility context

View File

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

View File

@ -490,7 +490,6 @@ class Debug {
private: private:
explicit Debug(Isolate* isolate); explicit Debug(Isolate* isolate);
~Debug();
static bool CompileDebuggerScript(Isolate* isolate, int index); static bool CompileDebuggerScript(Isolate* isolate, int index);
void ClearOneShot(); void ClearOneShot();
@ -743,25 +742,6 @@ class LockingCommandMessageQueue BASE_EMBEDDED {
class Debugger { class Debugger {
public: public:
~Debugger();
void DebugRequest(const uint16_t* json_request, int length);
MUST_USE_RESULT MaybeHandle<Object> MakeJSObject(
Vector<const char> constructor_name,
int argc,
Handle<Object> argv[]);
MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState();
MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent(
Handle<Object> break_points_hit);
MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent(
Handle<Object> exception,
bool uncaught,
Handle<Object> promise);
MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent(
Handle<Script> script, bool before);
MUST_USE_RESULT MaybeHandle<Object> MakeScriptCollectedEvent(int id);
void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue); void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue);
void OnException(Handle<Object> exception, bool uncaught); void OnException(Handle<Object> exception, bool uncaught);
void OnBeforeCompile(Handle<Script> script); void OnBeforeCompile(Handle<Script> script);
@ -773,13 +753,7 @@ class Debugger {
void OnAfterCompile(Handle<Script> script, void OnAfterCompile(Handle<Script> script,
AfterCompileFlags after_compile_flags); AfterCompileFlags after_compile_flags);
void OnScriptCollected(int id); void OnScriptCollected(int id);
void ProcessDebugEvent(v8::DebugEvent event,
Handle<JSObject> event_data,
bool auto_continue);
void NotifyMessageHandler(v8::DebugEvent event,
Handle<JSObject> exec_state,
Handle<JSObject> event_data,
bool auto_continue);
void SetEventListener(Handle<Object> callback, Handle<Object> data); void SetEventListener(Handle<Object> callback, Handle<Object> data);
void SetMessageHandler(v8::Debug::MessageHandler handler); void SetMessageHandler(v8::Debug::MessageHandler handler);
@ -798,36 +772,13 @@ class Debugger {
Handle<Context> GetDebugContext(); Handle<Context> GetDebugContext();
// Unload the debugger if possible. Only called when no debugger is currently
// active.
void UnloadDebugger();
friend void ForceUnloadDebugger(); // In test-debug.cc
inline bool EventActive() {
LockGuard<RecursiveMutex> lock_guard(&debugger_access_);
// Check whether the message handler was been cleared.
// TODO(yangguo): handle loading and unloading of the debugger differently.
if (debugger_unload_pending_) {
if (isolate_->debug()->debugger_entry() == NULL) {
UnloadDebugger();
}
}
// Currently argument event is not used.
return !ignore_debugger_ && is_active_;
}
bool ignore_debugger() const { return ignore_debugger_; } bool ignore_debugger() const { return ignore_debugger_; }
void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; } void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; }
bool live_edit_enabled() const { bool live_edit_enabled() const {
return FLAG_enable_liveedit && live_edit_enabled_ ; return FLAG_enable_liveedit && live_edit_enabled_ ;
} }
bool is_active() { bool is_active() { return is_active_; }
LockGuard<RecursiveMutex> lock_guard(&debugger_access_);
return is_active_;
}
class IgnoreScope { class IgnoreScope {
public: public:
@ -849,6 +800,22 @@ class Debugger {
private: private:
explicit Debugger(Isolate* isolate); explicit Debugger(Isolate* isolate);
~Debugger();
MUST_USE_RESULT MaybeHandle<Object> MakeJSObject(
Vector<const char> constructor_name,
int argc,
Handle<Object> argv[]);
MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState();
MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent(
Handle<Object> break_points_hit);
MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent(
Handle<Object> exception,
bool uncaught,
Handle<Object> promise);
MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent(
Handle<Script> script, bool before);
MUST_USE_RESULT MaybeHandle<Object> MakeScriptCollectedEvent(int id);
void CallEventCallback(v8::DebugEvent event, void CallEventCallback(v8::DebugEvent event,
Handle<Object> exec_state, Handle<Object> exec_state,
@ -861,18 +828,31 @@ class Debugger {
void CallJSEventCallback(v8::DebugEvent event, void CallJSEventCallback(v8::DebugEvent event,
Handle<Object> exec_state, Handle<Object> exec_state,
Handle<Object> event_data); Handle<Object> event_data);
void ListenersChanged(); void UpdateState();
void ProcessDebugEvent(v8::DebugEvent event,
Handle<JSObject> event_data,
bool auto_continue);
void NotifyMessageHandler(v8::DebugEvent event,
Handle<JSObject> exec_state,
Handle<JSObject> event_data,
bool auto_continue);
// Invoke the message handler function. // Invoke the message handler function.
void InvokeMessageHandler(MessageImpl message); void InvokeMessageHandler(MessageImpl message);
RecursiveMutex debugger_access_; // Mutex guarding debugger variables. inline bool EventActive() {
// Check whether the message handler was been cleared.
// TODO(yangguo): handle loading and unloading of the debugger differently.
// Currently argument event is not used.
return !ignore_debugger_ && is_active_;
}
Handle<Object> event_listener_; // Global handle to listener. Handle<Object> event_listener_; // Global handle to listener.
Handle<Object> event_listener_data_; Handle<Object> event_listener_data_;
bool is_active_; bool is_active_;
bool ignore_debugger_; // Are we temporarily ignoring the debugger? bool ignore_debugger_; // Are we temporarily ignoring the debugger?
bool live_edit_enabled_; // Enable LiveEdit. bool live_edit_enabled_; // Enable LiveEdit.
bool never_unload_debugger_; // Can we unload the debugger?
v8::Debug::MessageHandler message_handler_; v8::Debug::MessageHandler message_handler_;
bool debugger_unload_pending_; // Was message handler cleared? bool debugger_unload_pending_; // Was message handler cleared?
@ -911,8 +891,7 @@ class EnterDebugger BASE_EMBEDDED {
private: private:
Isolate* isolate_; Isolate* isolate_;
EnterDebugger* prev_; // Previous debugger entry if entered recursively. EnterDebugger* prev_; // Previous debugger entry if entered recursively.
JavaScriptFrameIterator it_; bool has_js_frames_; // Were there any JavaScript frames?
const bool has_js_frames_; // Were there any JavaScript frames?
StackFrame::Id break_frame_id_; // Previous break frame id. StackFrame::Id break_frame_id_; // Previous break frame id.
int break_id_; // Previous break id. int break_id_; // Previous break id.
bool load_failed_; // Did the debugger fail to load? bool load_failed_; // Did the debugger fail to load?

View File

@ -714,9 +714,6 @@ void Execution::DebugBreakHelper(Isolate* isolate) {
void Execution::ProcessDebugMessages(Isolate* isolate, void Execution::ProcessDebugMessages(Isolate* isolate,
bool debug_command_only) { bool debug_command_only) {
// Assert that we are on the main thread of the isolate.
ASSERT(ThreadId::Current().Equals(isolate->thread_id()));
isolate->stack_guard()->ClearDebugCommand(); isolate->stack_guard()->ClearDebugCommand();
StackLimitCheck check(isolate); StackLimitCheck check(isolate);

View File

@ -1546,8 +1546,6 @@ void Isolate::Deinit() {
if (state_ == INITIALIZED) { if (state_ == INITIALIZED) {
TRACE_ISOLATE(deinit); TRACE_ISOLATE(deinit);
debugger()->UnloadDebugger();
if (concurrent_recompilation_enabled()) { if (concurrent_recompilation_enabled()) {
optimizing_compiler_thread_->Stop(); optimizing_compiler_thread_->Stop();
delete optimizing_compiler_thread_; delete optimizing_compiler_thread_;

View File

@ -11042,8 +11042,9 @@ RUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) {
static bool CheckExecutionState(Isolate* isolate, int break_id) { static bool CheckExecutionState(Isolate* isolate, int break_id) {
return (isolate->debug()->break_id() != 0 && return !isolate->debug()->debug_context().is_null() &&
break_id == isolate->debug()->break_id()); isolate->debug()->break_id() != 0 &&
isolate->debug()->break_id() == break_id;
} }

View File

@ -98,10 +98,11 @@ class DebugLocalContext {
v8::internal::Isolate* isolate = v8::internal::Isolate* isolate =
reinterpret_cast<v8::internal::Isolate*>(context_->GetIsolate()); reinterpret_cast<v8::internal::Isolate*>(context_->GetIsolate());
v8::internal::Factory* factory = isolate->factory(); v8::internal::Factory* factory = isolate->factory();
v8::internal::Debug* debug = isolate->debug();
// Expose the debug context global object in the global object for testing. // Expose the debug context global object in the global object for testing.
debug->Load(); CHECK(isolate->debug()->Load());
debug->debug_context()->set_security_token( Handle<v8::internal::Context> debug_context =
isolate->debug()->debug_context();
debug_context->set_security_token(
v8::Utils::OpenHandle(*context_)->security_token()); v8::Utils::OpenHandle(*context_)->security_token());
Handle<JSGlobalProxy> global(Handle<JSGlobalProxy>::cast( Handle<JSGlobalProxy> global(Handle<JSGlobalProxy>::cast(
@ -109,7 +110,7 @@ class DebugLocalContext {
Handle<v8::internal::String> debug_string = Handle<v8::internal::String> debug_string =
factory->InternalizeOneByteString(STATIC_ASCII_VECTOR("debug")); factory->InternalizeOneByteString(STATIC_ASCII_VECTOR("debug"));
v8::internal::Runtime::SetObjectProperty(isolate, global, debug_string, v8::internal::Runtime::SetObjectProperty(isolate, global, debug_string,
Handle<Object>(debug->debug_context()->global_proxy(), isolate), Handle<Object>(debug_context->global_proxy(), isolate),
DONT_ENUM, DONT_ENUM,
::v8::internal::SLOPPY).Check(); ::v8::internal::SLOPPY).Check();
} }
@ -421,12 +422,6 @@ void CheckDebuggerUnloaded(bool check_functions) {
} }
void ForceUnloadDebugger() {
CcTest::i_isolate()->debugger()->never_unload_debugger_ = false;
CcTest::i_isolate()->debugger()->UnloadDebugger();
}
} } // namespace v8::internal } } // namespace v8::internal
@ -5500,13 +5495,12 @@ static void CheckDataParameter(
v8::String::NewFromUtf8(args.GetIsolate(), "Test"); v8::String::NewFromUtf8(args.GetIsolate(), "Test");
CHECK(v8::Debug::Call(debugger_call_with_data, data)->IsString()); CHECK(v8::Debug::Call(debugger_call_with_data, data)->IsString());
CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty()); for (int i = 0; i < 3; i++) {
CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty()); v8::TryCatch catcher;
CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty());
v8::TryCatch catcher; CHECK(catcher.HasCaught());
v8::Debug::Call(debugger_call_with_data); CHECK(catcher.Exception()->IsString());
CHECK(catcher.HasCaught()); }
CHECK(catcher.Exception()->IsString());
} }
@ -6872,9 +6866,11 @@ TEST(CallingContextIsNotDebugContext) {
TEST(DebugContextIsPreservedBetweenAccesses) { TEST(DebugContextIsPreservedBetweenAccesses) {
v8::HandleScope scope(CcTest::isolate()); v8::HandleScope scope(CcTest::isolate());
v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
v8::Local<v8::Context> context1 = v8::Debug::GetDebugContext(); v8::Local<v8::Context> context1 = v8::Debug::GetDebugContext();
v8::Local<v8::Context> context2 = v8::Debug::GetDebugContext(); v8::Local<v8::Context> context2 = v8::Debug::GetDebugContext();
CHECK_EQ(*context1, *context2); CHECK_EQ(*context1, *context2);
v8::Debug::SetDebugEventListener(NULL);
} }

View File

@ -1888,7 +1888,7 @@ TEST(NoDebugObjectInSnapshot) {
v8::HandleScope scope(env->GetIsolate()); v8::HandleScope scope(env->GetIsolate());
v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
CcTest::i_isolate()->debug()->Load(); CHECK(CcTest::i_isolate()->debug()->Load());
CompileRun("foo = {};"); CompileRun("foo = {};");
const v8::HeapSnapshot* snapshot = const v8::HeapSnapshot* snapshot =
heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); heap_profiler->TakeHeapSnapshot(v8_str("snapshot"));

View File

@ -37,12 +37,13 @@ function TestCase(fun, frame_number) {
var exception = false; var exception = false;
var codeSnippet = undefined; var codeSnippet = undefined;
var resultPositions = undefined; var resultPositions = undefined;
var step = 0;
function listener(event, exec_state, event_data, data) { function listener(event, exec_state, event_data, data) {
try { try {
if (event == Debug.DebugEvent.Break || if (event == Debug.DebugEvent.Break ||
event == Debug.DebugEvent.Exception) { event == Debug.DebugEvent.Exception) {
Debug.setListener(null); if (step++ > 0) return;
assertHasLineMark(/pause/, exec_state.frame(0)); assertHasLineMark(/pause/, exec_state.frame(0));
assertHasLineMark(/positions/, exec_state.frame(frame_number)); assertHasLineMark(/positions/, exec_state.frame(frame_number));
var frame = exec_state.frame(frame_number); var frame = exec_state.frame(frame_number);