Revision: 21604
Author: [email protected]
Date: Mon Jun 2 11:41:50 2014 UTC
Log: Some debugger-related clean-ups and renamings.
[email protected]
Review URL: https://codereview.chromium.org/300553008
http://code.google.com/p/v8/source/detail?r=21604
Modified:
/branches/bleeding_edge/src/api.cc
/branches/bleeding_edge/src/bootstrapper.cc
/branches/bleeding_edge/src/debug.cc
/branches/bleeding_edge/src/debug.h
/branches/bleeding_edge/src/execution.cc
/branches/bleeding_edge/src/execution.h
/branches/bleeding_edge/src/isolate.cc
/branches/bleeding_edge/src/mark-compact.cc
/branches/bleeding_edge/src/runtime.cc
/branches/bleeding_edge/test/cctest/test-debug.cc
=======================================
--- /branches/bleeding_edge/src/api.cc Mon Jun 2 11:02:06 2014 UTC
+++ /branches/bleeding_edge/src/api.cc Mon Jun 2 11:41:50 2014 UTC
@@ -6905,7 +6905,7 @@
void Debug::ProcessDebugMessages() {
- i::Execution::ProcessDebugMessages(i::Isolate::Current(), true);
+ i::Isolate::Current()->debug()->ProcessDebugMessages(true);
}
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Tue May 27 15:00:26 2014 UTC
+++ /branches/bleeding_edge/src/bootstrapper.cc Mon Jun 2 11:41:50 2014 UTC
@@ -1477,7 +1477,7 @@
Vector<const char> name,
Handle<String> source) {
HandleScope scope(isolate);
- Debug::IgnoreScope compiling_natives(isolate->debug());
+ SuppressDebug compiling_natives(isolate->debug());
// During genesis, the boilerplate for stack overflow won't work until
the
// environment has been at least partially initialized. Add a stack check
// before entering JS code to catch overflow early.
=======================================
--- /branches/bleeding_edge/src/debug.cc Mon Jun 2 06:22:09 2014 UTC
+++ /branches/bleeding_edge/src/debug.cc Mon Jun 2 11:41:50 2014 UTC
@@ -39,10 +39,10 @@
command_queue_(isolate->logger(), kQueueInitialSize),
event_command_queue_(isolate->logger(), kQueueInitialSize),
is_active_(false),
- ignore_debugger_(false),
+ is_suppressed_(false),
live_edit_enabled_(true), // TODO(yangguo): set to false by default.
has_break_points_(false),
- disable_break_(false),
+ break_disabled_(false),
break_on_exception_(false),
break_on_uncaught_exception_(false),
script_cache_(NULL),
@@ -257,9 +257,7 @@
void BreakLocationIterator::SetBreakPoint(Handle<Object>
break_point_object) {
// If there is not already a real break point here patch code with debug
// break.
- if (!HasBreakPoint()) {
- SetDebugBreak();
- }
+ if (!HasBreakPoint()) SetDebugBreak();
ASSERT(IsDebugBreak() || IsDebuggerStatement());
// Set the break point information.
DebugInfo::SetBreakPoint(debug_info_, code_position(),
@@ -281,9 +279,7 @@
void BreakLocationIterator::SetOneShot() {
// Debugger statement always calls debugger. No need to modify it.
- if (IsDebuggerStatement()) {
- return;
- }
+ if (IsDebuggerStatement()) return;
// If there is a real break point here no more to do.
if (HasBreakPoint()) {
@@ -298,9 +294,7 @@
void BreakLocationIterator::ClearOneShot() {
// Debugger statement always calls debugger. No need to modify it.
- if (IsDebuggerStatement()) {
- return;
- }
+ if (IsDebuggerStatement()) return;
// If there is a real break point here no more to do.
if (HasBreakPoint()) {
@@ -316,17 +310,13 @@
void BreakLocationIterator::SetDebugBreak() {
// Debugger statement always calls debugger. No need to modify it.
- if (IsDebuggerStatement()) {
- return;
- }
+ if (IsDebuggerStatement()) return;
// If there is already a break point here just return. This might happen
if
// the same code is flooded with break points twice. Flooding the same
// function twice might happen when stepping in a function with an
exception
// handler as the handler and the function is the same.
- if (IsDebugBreak()) {
- return;
- }
+ if (IsDebugBreak()) return;
if (RelocInfo::IsJSReturn(rmode())) {
// Patch the frame exit code with a break point.
@@ -344,9 +334,7 @@
void BreakLocationIterator::ClearDebugBreak() {
// Debugger statement always calls debugger. No need to modify it.
- if (IsDebuggerStatement()) {
- return;
- }
+ if (IsDebuggerStatement()) return;
if (RelocInfo::IsJSReturn(rmode())) {
// Restore the frame exit code.
@@ -728,16 +716,16 @@
bool Debug::Load() {
// Return if debugger is already loaded.
- if (IsLoaded()) return true;
+ if (is_loaded()) return true;
// Bail out if we're already in the process of compiling the native
// JavaScript source code for the debugger.
- if (isolate_->debug()->ignore_debugger()) return false;
- Debug::IgnoreScope during_create(isolate_->debug());
+ if (is_suppressed_) return false;
+ SuppressDebug while_loading(this);
// Disable breakpoints and interrupts while compiling and running the
// debugger scripts including the context creation code.
- DisableBreak disable(isolate_, true);
+ DisableBreak disable(this, true);
PostponeInterruptsScope postpone(isolate_);
// Create the debugger context.
@@ -794,7 +782,7 @@
while (thread_local_.promise_on_stack_) PromiseHandleEpilogue();
// Return debugger is not loaded.
- if (!IsLoaded()) return;
+ if (!is_loaded()) return;
// Clear the script cache.
DestroyScriptCache();
@@ -815,7 +803,7 @@
}
// Just continue if breaks are disabled or debugger cannot be loaded.
- if (disable_break()) return;
+ if (break_disabled_) return;
// Enter the debugger.
EnterDebugger debugger(isolate_);
@@ -1271,7 +1259,7 @@
PrepareForBreakPoints();
- ASSERT(Debug::InDebugger());
+ ASSERT(is_entered());
// Remember this step action and count.
thread_local_.last_step_action_ = step_action;
@@ -1645,18 +1633,6 @@
}
return locations;
}
-
-
-void Debug::NewBreak(StackFrame::Id break_frame_id) {
- thread_local_.break_frame_id_ = break_frame_id;
- thread_local_.break_id_ = ++thread_local_.break_count_;
-}
-
-
-void Debug::SetBreak(StackFrame::Id break_frame_id, int break_id) {
- thread_local_.break_frame_id_ = break_frame_id;
- thread_local_.break_id_ = break_id;
-}
// Handle stepping into a function.
@@ -2446,7 +2422,7 @@
bool Debug::IsDebugGlobal(GlobalObject* global) {
- return IsLoaded() && global == debug_context()->global_object();
+ return is_loaded() && global == debug_context()->global_object();
}
@@ -2456,16 +2432,15 @@
ASSERT(isolate_->context() == *Debug::debug_context());
// Clear the mirror cache.
- Handle<String> function_name =
isolate_->factory()->InternalizeOneByteString(
- STATIC_ASCII_VECTOR("ClearMirrorCache"));
Handle<Object> fun = Object::GetProperty(
- isolate_->global_object(), function_name).ToHandleChecked();
+ isolate_,
+ isolate_->global_object(),
+ "ClearMirrorCache").ToHandleChecked();
ASSERT(fun->IsJSFunction());
- Execution::TryCall(
- Handle<JSFunction>::cast(fun),
- Handle<JSObject>(Debug::debug_context()->global_object()),
- 0,
- NULL);
+ Execution::TryCall(Handle<JSFunction>::cast(fun),
+
Handle<JSObject>(Debug::debug_context()->global_object()),
+ 0,
+ NULL);
}
@@ -2557,34 +2532,26 @@
}
-MaybeHandle<Object> Debug::MakeJSObject(
- Vector<const char> constructor_name,
- int argc,
- Handle<Object> argv[]) {
- ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
-
+MaybeHandle<Object> Debug::MakeJSObject(const char* constructor_name,
+ int argc,
+ Handle<Object> argv[]) {
+ ASSERT(isolate_->context() == *debug_context());
// Create the execution state object.
- Handle<String> constructor_str =
- isolate_->factory()->InternalizeUtf8String(constructor_name);
- ASSERT(!constructor_str.is_null());
Handle<Object> constructor = Object::GetProperty(
- isolate_->global_object(), constructor_str).ToHandleChecked();
+ isolate_, isolate_->global_object(),
constructor_name).ToHandleChecked();
ASSERT(constructor->IsJSFunction());
if (!constructor->IsJSFunction()) return MaybeHandle<Object>();
- return Execution::TryCall(
- Handle<JSFunction>::cast(constructor),
-
Handle<JSObject>(isolate_->debug()->debug_context()->global_object()),
- argc,
- argv);
+ return Execution::TryCall(Handle<JSFunction>::cast(constructor),
+
Handle<JSObject>(debug_context()->global_object()),
+ argc,
+ argv);
}
MaybeHandle<Object> Debug::MakeExecutionState() {
// Create the execution state object.
- Handle<Object> break_id = isolate_->factory()->NewNumberFromInt(
- isolate_->debug()->break_id());
- Handle<Object> argv[] = { break_id };
- return MakeJSObject(CStrVector("MakeExecutionState"), ARRAY_SIZE(argv),
argv);
+ Handle<Object> argv[] = {
isolate_->factory()->NewNumberFromInt(break_id()) };
+ return MakeJSObject("MakeExecutionState", ARRAY_SIZE(argv), argv);
}
@@ -2593,13 +2560,13 @@
if (!MakeExecutionState().ToHandle(&exec_state)) return
MaybeHandle<Object>();
// Create the new break event object.
Handle<Object> argv[] = { exec_state, break_points_hit };
- return MakeJSObject(CStrVector("MakeBreakEvent"), ARRAY_SIZE(argv),
argv);
+ return MakeJSObject("MakeBreakEvent", ARRAY_SIZE(argv), argv);
}
MaybeHandle<Object> Debug::MakeExceptionEvent(Handle<Object> exception,
- bool uncaught,
- Handle<Object> promise) {
+ bool uncaught,
+ Handle<Object> promise) {
Handle<Object> exec_state;
if (!MakeExecutionState().ToHandle(&exec_state)) return
MaybeHandle<Object>();
// Create the new exception event object.
@@ -2607,12 +2574,12 @@
exception,
isolate_->factory()->ToBoolean(uncaught),
promise };
- return MakeJSObject(CStrVector("MakeExceptionEvent"), ARRAY_SIZE(argv),
argv);
+ return MakeJSObject("MakeExceptionEvent", ARRAY_SIZE(argv), argv);
}
MaybeHandle<Object> Debug::MakeCompileEvent(Handle<Script> script,
- bool before) {
+ bool before) {
Handle<Object> exec_state;
if (!MakeExecutionState().ToHandle(&exec_state)) return
MaybeHandle<Object>();
// Create the compile event object.
@@ -2620,7 +2587,7 @@
Handle<Object> argv[] = { exec_state,
script_wrapper,
isolate_->factory()->ToBoolean(before) };
- return MakeJSObject(CStrVector("MakeCompileEvent"), ARRAY_SIZE(argv),
argv);
+ return MakeJSObject("MakeCompileEvent", ARRAY_SIZE(argv), argv);
}
@@ -2630,31 +2597,27 @@
// Create the script collected event object.
Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_);
Handle<Object> argv[] = { exec_state, id_object };
-
- return MakeJSObject(
- CStrVector("MakeScriptCollectedEvent"), ARRAY_SIZE(argv), argv);
+ return MakeJSObject("MakeScriptCollectedEvent", ARRAY_SIZE(argv), argv);
}
void Debug::OnException(Handle<Object> exception, bool uncaught) {
HandleScope scope(isolate_);
- Debug* debug = isolate_->debug();
// Bail out based on state or if there is no listener for this event
- if (debug->InDebugger()) return;
+ if (is_entered()) return;
if (!EventActive()) return;
- Handle<Object> promise = debug->GetPromiseForUncaughtException();
+ Handle<Object> promise = GetPromiseForUncaughtException();
uncaught |= !promise->IsUndefined();
// Bail out if exception breaks are not active
if (uncaught) {
// Uncaught exceptions are reported by either flags.
- if (!(debug->break_on_uncaught_exception() ||
- debug->break_on_exception())) return;
+ if (!(break_on_uncaught_exception() || break_on_exception())) return;
} else {
// Caught exceptions are reported is activated.
- if (!debug->break_on_exception()) return;
+ if (!break_on_exception()) return;
}
// Enter the debugger.
@@ -2662,7 +2625,7 @@
if (debugger.FailedToEnter()) return;
// Clear all current stepping setup.
- debug->ClearStepping();
+ ClearStepping();
// Create the event data object.
Handle<Object> event_data;
@@ -2704,7 +2667,7 @@
HandleScope scope(isolate_);
// Bail out based on state or if there is no listener for this event
- if (InDebugger()) return;
+ if (is_entered()) return;
if (!EventActive()) return;
// Enter the debugger.
@@ -2735,7 +2698,7 @@
if (!EventActive()) return;
// Store whether in debugger before entering debugger.
- bool in_debugger = InDebugger();
+ bool in_debugger = is_entered();
// Enter the debugger.
EnterDebugger debugger(isolate_);
@@ -2786,7 +2749,7 @@
HandleScope scope(isolate_);
// No more to do if not debugging.
- if (InDebugger()) return;
+ if (is_entered()) return;
if (!EventActive()) return;
// Enter the debugger.
@@ -2811,7 +2774,7 @@
HandleScope scope(isolate_);
// Clear any pending debug break if this is a real break.
- if (!auto_continue) set_has_pending_interrupt(false);
+ if (!auto_continue) thread_local_.has_pending_interrupt_ = false;
// Create the execution state.
Handle<Object> exec_state;
@@ -2852,48 +2815,30 @@
Handle<Object> event_data,
v8::Debug::ClientData* client_data) {
if (event_listener_->IsForeign()) {
- CallCEventCallback(event, exec_state, event_data, client_data);
+ // Invoke the C debug event listener.
+ v8::Debug::EventCallback callback =
+ FUNCTION_CAST<v8::Debug::EventCallback>(
+ Handle<Foreign>::cast(event_listener_)->foreign_address());
+ EventDetailsImpl event_details(event,
+ Handle<JSObject>::cast(exec_state),
+ Handle<JSObject>::cast(event_data),
+ event_listener_data_,
+ client_data);
+ callback(event_details);
+ ASSERT(!isolate_->has_scheduled_exception());
} else {
- CallJSEventCallback(event, exec_state, event_data);
+ // Invoke the JavaScript debug event listener.
+ ASSERT(event_listener_->IsJSFunction());
+ Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event),
isolate_),
+ exec_state,
+ event_data,
+ event_listener_data_ };
+ Execution::TryCall(Handle<JSFunction>::cast(event_listener_),
+ isolate_->global_object(),
+ ARRAY_SIZE(argv),
+ argv);
}
}
-
-
-void Debug::CallCEventCallback(v8::DebugEvent event,
- Handle<Object> exec_state,
- Handle<Object> event_data,
- v8::Debug::ClientData* client_data) {
- Handle<Foreign> callback_obj(Handle<Foreign>::cast(event_listener_));
- v8::Debug::EventCallback callback =
- FUNCTION_CAST<v8::Debug::EventCallback>(
- callback_obj->foreign_address());
- EventDetailsImpl event_details(
- event,
- Handle<JSObject>::cast(exec_state),
- Handle<JSObject>::cast(event_data),
- event_listener_data_,
- client_data);
- callback(event_details);
-}
-
-
-void Debug::CallJSEventCallback(v8::DebugEvent event,
- Handle<Object> exec_state,
- Handle<Object> event_data) {
- ASSERT(event_listener_->IsJSFunction());
- Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_));
-
- // Invoke the JavaScript debug event listener.
- Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event), isolate_),
- exec_state,
- event_data,
- event_listener_data_ };
- Execution::TryCall(fun,
- isolate_->global_object(),
- ARRAY_SIZE(argv),
- argv);
- // Silently ignore exceptions from debug event listeners.
-}
Handle<Context> Debug::GetDebugContext() {
@@ -2936,7 +2881,7 @@
// 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(InDebugger());
+ ASSERT(is_entered());
isolate_->stack_guard()->ClearDebugCommand();
// Notify the debugger that a debug event has occurred unless auto
continue is
@@ -2954,7 +2899,7 @@
// in the queue if any. For script collected events don't even process
// messages in the queue as the execution state might not be what is
expected
// by the client.
- if ((auto_continue && !HasCommands()) || event == v8::ScriptCollected) {
+ if ((auto_continue && !has_commands()) || event == v8::ScriptCollected) {
return;
}
@@ -3030,7 +2975,7 @@
// Return from debug event processing if either the VM is put into the
// running state (through a continue command) or auto continue is
active
// and there are no more commands queued.
- } while (!running || HasCommands());
+ } while (!running || has_commands());
}
@@ -3058,7 +3003,7 @@
void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
message_handler_ = handler;
UpdateState();
- if (handler == NULL && InDebugger()) {
+ if (handler == NULL && is_entered()) {
// 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());
@@ -3070,19 +3015,19 @@
void Debug::UpdateState() {
bool activate = message_handler_ != NULL ||
!event_listener_.is_null() ||
- InDebugger();
+ is_entered();
if (!is_active_ && activate) {
// Note that the debug context could have already been loaded to
// bootstrap test cases.
isolate_->compilation_cache()->Disable();
activate = Load();
- } else if (IsLoaded() && !activate) {
+ } else if (is_loaded() && !activate) {
isolate_->compilation_cache()->Enable();
Unload();
}
is_active_ = activate;
// At this point the debug context is loaded iff the debugger is active.
- ASSERT(IsLoaded() == is_active_);
+ ASSERT(is_loaded() == is_active());
}
@@ -3109,14 +3054,7 @@
command_received_.Signal();
// Set the debug command break flag to have the command processed.
- if (!isolate_->debug()->InDebugger()) {
- isolate_->stack_guard()->RequestDebugCommand();
- }
-}
-
-
-bool Debug::HasCommands() {
- return !command_queue_.IsEmpty();
+ if (!is_entered()) isolate_->stack_guard()->RequestDebugCommand();
}
@@ -3125,7 +3063,7 @@
event_command_queue_.Put(message);
// Set the debug command break flag to have the command processed.
- if (!InDebugger()) isolate_->stack_guard()->RequestDebugCommand();
+ if (!is_entered()) isolate_->stack_guard()->RequestDebugCommand();
}
@@ -3150,6 +3088,56 @@
ARRAY_SIZE(argv),
argv);
}
+
+
+void Debug::DebugBreakHelper() {
+ // Ignore debug break during bootstrapping.
+ if (isolate_->bootstrapper()->IsActive()) return;
+ // Just continue if breaks are disabled.
+ if (break_disabled_) return;
+ // Ignore debug break if debugger is not active.
+ if (!is_active()) return;
+
+ StackLimitCheck check(isolate_);
+ if (check.HasOverflowed()) return;
+
+ { JavaScriptFrameIterator it(isolate_);
+ ASSERT(!it.done());
+ Object* fun = it.frame()->function();
+ if (fun && fun->IsJSFunction()) {
+ // Don't stop in builtin functions.
+ if (JSFunction::cast(fun)->IsBuiltin()) return;
+ GlobalObject* global =
JSFunction::cast(fun)->context()->global_object();
+ // Don't stop in debugger functions.
+ if (IsDebugGlobal(global)) return;
+ }
+ }
+
+ // Collect the break state before clearing the flags.
+ bool debug_command_only = isolate_->stack_guard()->CheckDebugCommand() &&
+ !isolate_->stack_guard()->CheckDebugBreak();
+
+ isolate_->stack_guard()->ClearDebugBreak();
+
+ ProcessDebugMessages(debug_command_only);
+}
+
+
+void Debug::ProcessDebugMessages(bool debug_command_only) {
+ isolate_->stack_guard()->ClearDebugCommand();
+
+ StackLimitCheck check(isolate_);
+ if (check.HasOverflowed()) return;
+
+ HandleScope scope(isolate_);
+ // Enter the debugger. Just continue if we fail to enter the debugger.
+ EnterDebugger debugger(isolate_);
+ if (debugger.FailedToEnter()) return;
+
+ // Notify the debug event listeners. Indicate auto continue if the break
was
+ // a debug command break.
+ OnDebugBreak(isolate_->factory()->undefined_value(), debug_command_only);
+}
EnterDebugger::EnterDebugger(Isolate* isolate)
@@ -3159,7 +3147,7 @@
Debug* debug = isolate_->debug();
// Link recursive debugger entry.
- debug->set_debugger_entry(this);
+ debug->thread_local_.debugger_entry_ = this;
// Store the previous break id and frame id.
break_id_ = debug->break_id();
@@ -3169,12 +3157,14 @@
// break frame id.
JavaScriptFrameIterator it(isolate_);
has_js_frames_ = !it.done();
- debug->NewBreak(has_js_frames_ ? it.frame()->id() : StackFrame::NO_ID);
+ debug->thread_local_.break_frame_id_ = has_js_frames_ ? it.frame()->id()
+ :
StackFrame::NO_ID;
+ debug->SetNextBreakId();
debug->UpdateState();
// Make sure that debugger is loaded and enter the debugger context.
// The previous context is kept in save_.
- load_failed_ = !debug->IsLoaded();
+ load_failed_ = !debug->is_loaded();
if (!load_failed_) isolate_->set_context(*debug->debug_context());
}
@@ -3183,7 +3173,8 @@
Debug* debug = isolate_->debug();
// Restore to the previous break state.
- debug->SetBreak(break_frame_id_, break_id_);
+ debug->thread_local_.break_frame_id_ = break_frame_id_;
+ debug->thread_local_.break_id_ = break_id_;
// Check for leaving the debugger.
if (!load_failed_ && prev_ == NULL) {
@@ -3197,13 +3188,11 @@
// If there are commands in the queue when leaving the debugger request
// that these commands are processed.
- if (debug->HasCommands()) {
- isolate_->stack_guard()->RequestDebugCommand();
- }
+ if (debug->has_commands())
isolate_->stack_guard()->RequestDebugCommand();
}
// Leaving this debugger entry.
- debug->set_debugger_entry(prev_);
+ debug->thread_local_.debugger_entry_ = prev_;
debug->UpdateState();
}
=======================================
--- /branches/bleeding_edge/src/debug.h Wed May 28 10:41:13 2014 UTC
+++ /branches/bleeding_edge/src/debug.h Mon Jun 2 11:41:50 2014 UTC
@@ -351,70 +351,52 @@
// DebugInfo.
class Debug {
public:
- void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue);
- void OnException(Handle<Object> exception, bool uncaught);
- void OnBeforeCompile(Handle<Script> script);
-
enum AfterCompileFlags {
NO_AFTER_COMPILE_FLAGS,
SEND_WHEN_DEBUGGING
};
+
+ // Debug event triggers.
+ void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue);
+ void OnException(Handle<Object> exception, bool uncaught);
+ void OnBeforeCompile(Handle<Script> script);
void OnAfterCompile(Handle<Script> script,
AfterCompileFlags after_compile_flags);
void OnScriptCollected(int id);
+ // API facing.
void SetEventListener(Handle<Object> callback, Handle<Object> data);
void SetMessageHandler(v8::Debug::MessageHandler handler);
-
- // Add a debugger command to the command queue.
void EnqueueCommandMessage(Vector<const uint16_t> command,
v8::Debug::ClientData* client_data = NULL);
-
- // Check whether there are commands in the command queue.
- bool HasCommands();
-
// Enqueue a debugger command to the command queue for event listeners.
void EnqueueDebugCommand(v8::Debug::ClientData* client_data = NULL);
-
MUST_USE_RESULT MaybeHandle<Object> Call(Handle<JSFunction> fun,
Handle<Object> data);
-
Handle<Context> GetDebugContext();
+ void DebugBreakHelper();
+ void ProcessDebugMessages(bool debug_command_only);
- bool ignore_debugger() const { return ignore_debugger_; }
+ // Flags and states.
void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; }
bool live_edit_enabled() const {
return FLAG_enable_liveedit && live_edit_enabled_ ;
}
- bool is_active() { return is_active_; }
+ inline bool is_active() const { return is_active_; }
+ inline bool is_loaded() const { return !debug_context_.is_null(); }
+ inline bool has_break_points() const { return has_break_points_; }
+ inline bool is_entered() const {
+ return thread_local_.debugger_entry_ != NULL;
+ }
- class IgnoreScope {
- public:
- explicit IgnoreScope(Debug* debug)
- : debug_(debug),
- old_state_(debug->ignore_debugger_) {
- debug_->ignore_debugger_ = true;
- }
-
- ~IgnoreScope() {
- debug_->ignore_debugger_ = old_state_;
- }
-
- private:
- Debug* debug_;
- bool old_state_;
- DISALLOW_COPY_AND_ASSIGN(IgnoreScope);
- };
-
+ void set_disable_break(bool v) { break_disabled_ = v; }
bool Load();
- void Unload();
- bool IsLoaded() { return !debug_context_.is_null(); }
- bool InDebugger() { return thread_local_.debugger_entry_ != NULL; }
void Break(Arguments args, JavaScriptFrame*);
void SetAfterBreakTarget(JavaScriptFrame* frame);
+
bool SetBreakPoint(Handle<JSFunction> function,
Handle<Object> break_point_object,
int* source_position);
@@ -443,6 +425,12 @@
bool IsStepping() { return thread_local_.step_count_ > 0; }
bool StepNextContinue(BreakLocationIterator* break_location_iterator,
JavaScriptFrame* frame);
+
+ // Returns whether the operation succeeded. Compilation can only be
triggered
+ // if a valid closure is passed as the second argument, otherwise the
shared
+ // function needs to be compiled already.
+ bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared,
+ Handle<JSFunction> function);
static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared);
static bool HasDebugInfo(Handle<SharedFunctionInfo> shared);
@@ -451,23 +439,16 @@
// This function is used in FunctionNameUsing* tests.
Object* FindSharedFunctionInfoInScript(Handle<Script> script, int
position);
- // Returns whether the operation succeeded. Compilation can only be
triggered
- // if a valid closure is passed as the second argument, otherwise the
shared
- // function needs to be compiled already.
- bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared,
- Handle<JSFunction> function);
// Returns true if the current stub call is patched to call the debugger.
static bool IsDebugBreak(Address addr);
// Returns true if the current return statement has been patched to be
// a debugger breakpoint.
static bool IsDebugBreakAtReturn(RelocInfo* rinfo);
-
// Check whether a code stub with the specified major key is a possible
break
// point location.
static bool IsSourceBreakStub(Code* code);
static bool IsBreakStub(Code* code);
-
// Find the builtin to use for invoking the debug break
static Handle<Code> FindDebugBreak(Handle<Code> code, RelocInfo::Mode
mode);
@@ -484,14 +465,7 @@
// Check whether this frame is just about to return.
bool IsBreakAtReturn(JavaScriptFrame* frame);
- // Fast check to see if any break points are active.
- inline bool has_break_points() { return has_break_points_; }
-
- void NewBreak(StackFrame::Id break_frame_id);
- void SetBreak(StackFrame::Id break_frame_id, int break_id);
- StackFrame::Id break_frame_id() {
- return thread_local_.break_frame_id_;
- }
+ StackFrame::Id break_frame_id() { return thread_local_.break_frame_id_; }
int break_id() { return thread_local_.break_id_; }
bool StepInActive() { return thread_local_.step_into_fp_ != 0; }
@@ -505,12 +479,7 @@
bool StepOutActive() { return thread_local_.step_out_fp_ != 0; }
Address step_out_fp() { return thread_local_.step_out_fp_; }
- EnterDebugger* debugger_entry() {
- return thread_local_.debugger_entry_;
- }
- void set_debugger_entry(EnterDebugger* entry) {
- thread_local_.debugger_entry_ = entry;
- }
+ EnterDebugger* debugger_entry() { return thread_local_.debugger_entry_; }
// Check whether any of the specified interrupts are pending.
bool has_pending_interrupt() {
@@ -521,12 +490,6 @@
void set_has_pending_interrupt(bool value) {
thread_local_.has_pending_interrupt_ = value;
}
-
- // Getter and setter for the disable break state.
- bool disable_break() { return disable_break_; }
- void set_disable_break(bool disable_break) {
- disable_break_ = disable_break;
- }
// Getters for the current exception break state.
bool break_on_exception() { return break_on_exception_; }
@@ -562,9 +525,6 @@
char* RestoreDebug(char* from);
static int ArchiveSpacePerThread();
void FreeThreadResources() { }
-
- // Mirror cache handling.
- void ClearMirrorCache();
// Script cache handling.
void CreateScriptCache();
@@ -581,8 +541,22 @@
private:
explicit Debug(Isolate* isolate);
+ void UpdateState();
+ void Unload();
+
+ // Mirror cache handling.
+ void ClearMirrorCache();
+
+ void SetNextBreakId() {
+ thread_local_.break_id_ = ++thread_local_.break_count_;
+ }
+
+ // Check whether there are commands in the command queue.
+ inline bool has_commands() const { return !command_queue_.IsEmpty(); }
+
+ // Constructors for debug event objects.
MUST_USE_RESULT MaybeHandle<Object> MakeJSObject(
- Vector<const char> constructor_name,
+ const char* constructor_name,
int argc,
Handle<Object> argv[]);
MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState();
@@ -596,18 +570,11 @@
Handle<Script> script, bool before);
MUST_USE_RESULT MaybeHandle<Object> MakeScriptCollectedEvent(int id);
+
void CallEventCallback(v8::DebugEvent event,
Handle<Object> exec_state,
Handle<Object> event_data,
v8::Debug::ClientData* client_data);
- void CallCEventCallback(v8::DebugEvent event,
- Handle<Object> exec_state,
- Handle<Object> event_data,
- v8::Debug::ClientData* client_data);
- void CallJSEventCallback(v8::DebugEvent event,
- Handle<Object> exec_state,
- Handle<Object> event_data);
- void UpdateState();
void ProcessDebugEvent(v8::DebugEvent event,
Handle<JSObject> event_data,
@@ -624,7 +591,7 @@
// 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_;
+ return !is_suppressed_ && is_active_;
}
static bool CompileDebuggerScript(Isolate* isolate, int index);
@@ -673,10 +640,10 @@
LockingCommandMessageQueue event_command_queue_;
bool is_active_;
- bool ignore_debugger_;
+ bool is_suppressed_;
bool live_edit_enabled_;
bool has_break_points_;
- bool disable_break_;
+ bool break_disabled_;
bool break_on_exception_;
bool break_on_uncaught_exception_;
@@ -753,6 +720,8 @@
friend class Isolate;
friend class EnterDebugger;
friend class FrameDropper;
+ friend class DisableBreak;
+ friend class SuppressDebug;
DISALLOW_COPY_AND_ASSIGN(Debug);
};
@@ -793,20 +762,31 @@
// Stack allocated class for disabling break.
class DisableBreak BASE_EMBEDDED {
public:
- explicit DisableBreak(Isolate* isolate, bool disable_break)
- : isolate_(isolate) {
- prev_disable_break_ = isolate_->debug()->disable_break();
- isolate_->debug()->set_disable_break(disable_break);
+ explicit DisableBreak(Debug* debug, bool disable_break)
+ : debug_(debug), old_state_(debug->break_disabled_) {
+ debug_->break_disabled_ = disable_break;
}
- ~DisableBreak() {
- isolate_->debug()->set_disable_break(prev_disable_break_);
+ ~DisableBreak() { debug_->break_disabled_ = old_state_; }
+
+ private:
+ Debug* debug_;
+ bool old_state_;
+ DISALLOW_COPY_AND_ASSIGN(DisableBreak);
+};
+
+
+class SuppressDebug BASE_EMBEDDED {
+ public:
+ explicit SuppressDebug(Debug* debug)
+ : debug_(debug), old_state_(debug->is_suppressed_) {
+ debug_->is_suppressed_ = true;
}
+ ~SuppressDebug() { debug_->is_suppressed_ = old_state_; }
private:
- Isolate* isolate_;
- // The previous state of the disable break used to restore the value
when this
- // object is destructed.
- bool prev_disable_break_;
+ Debug* debug_;
+ bool old_state_;
+ DISALLOW_COPY_AND_ASSIGN(SuppressDebug);
};
=======================================
--- /branches/bleeding_edge/src/execution.cc Tue May 27 13:20:58 2014 UTC
+++ /branches/bleeding_edge/src/execution.cc Mon Jun 2 11:41:50 2014 UTC
@@ -652,60 +652,6 @@
return Handle<String>::cast(result);
}
-
-
-void Execution::DebugBreakHelper(Isolate* isolate) {
- // Just continue if breaks are disabled.
- if (isolate->debug()->disable_break()) return;
-
- // Ignore debug break during bootstrapping.
- if (isolate->bootstrapper()->IsActive()) return;
-
- // Ignore debug break if debugger is not active.
- if (!isolate->debug()->is_active()) return;
-
- StackLimitCheck check(isolate);
- if (check.HasOverflowed()) return;
-
- { JavaScriptFrameIterator it(isolate);
- ASSERT(!it.done());
- Object* fun = it.frame()->function();
- if (fun && fun->IsJSFunction()) {
- // Don't stop in builtin functions.
- if (JSFunction::cast(fun)->IsBuiltin()) return;
- GlobalObject* global =
JSFunction::cast(fun)->context()->global_object();
- // Don't stop in debugger functions.
- if (isolate->debug()->IsDebugGlobal(global)) return;
- }
- }
-
- // Collect the break state before clearing the flags.
- bool debug_command_only = isolate->stack_guard()->CheckDebugCommand() &&
- !isolate->stack_guard()->CheckDebugBreak();
-
- isolate->stack_guard()->ClearDebugBreak();
-
- Execution::ProcessDebugMessages(isolate, debug_command_only);
-}
-
-
-void Execution::ProcessDebugMessages(Isolate* isolate,
- bool debug_command_only) {
- isolate->stack_guard()->ClearDebugCommand();
-
- StackLimitCheck check(isolate);
- if (check.HasOverflowed()) return;
-
- HandleScope scope(isolate);
- // Enter the debugger. Just continue if we fail to enter the debugger.
- EnterDebugger debugger(isolate);
- if (debugger.FailedToEnter()) return;
-
- // Notify the debug event listeners. Indicate auto continue if the break
was
- // a debug command break.
- isolate->debug()->OnDebugBreak(isolate->factory()->undefined_value(),
- debug_command_only);
-}
Object* StackGuard::HandleInterrupts() {
@@ -721,7 +667,7 @@
}
if (CheckDebugBreak() || CheckDebugCommand()) {
- Execution::DebugBreakHelper(isolate_);
+ isolate_->debug()->DebugBreakHelper();
}
if (CheckAndClearInterrupt(TERMINATE_EXECUTION, access)) {
=======================================
--- /branches/bleeding_edge/src/execution.h Mon May 26 12:58:55 2014 UTC
+++ /branches/bleeding_edge/src/execution.h Mon Jun 2 11:41:50 2014 UTC
@@ -104,9 +104,6 @@
Handle<Object> pos,
Handle<Object> is_global);
- static void DebugBreakHelper(Isolate* isolate);
- static void ProcessDebugMessages(Isolate* isolate, bool
debug_command_only);
-
// Get a function delegate (or undefined) for the given non-function
// object. Used for support calling objects as functions.
static Handle<Object> GetFunctionDelegate(Isolate* isolate,
=======================================
--- /branches/bleeding_edge/src/isolate.cc Wed May 28 18:40:04 2014 UTC
+++ /branches/bleeding_edge/src/isolate.cc Mon Jun 2 11:41:50 2014 UTC
@@ -1324,7 +1324,7 @@
Handle<Context> Isolate::GetCallingNativeContext() {
JavaScriptFrameIterator it(this);
- if (debug_->InDebugger()) {
+ if (debug_->is_entered()) {
while (!it.done()) {
JavaScriptFrame* frame = it.frame();
Context* context = Context::cast(frame->context());
=======================================
--- /branches/bleeding_edge/src/mark-compact.cc Wed May 28 11:17:02 2014 UTC
+++ /branches/bleeding_edge/src/mark-compact.cc Mon Jun 2 11:41:50 2014 UTC
@@ -4248,7 +4248,7 @@
void MarkCompactCollector::EnableCodeFlushing(bool enable) {
- if (isolate()->debug()->IsLoaded() ||
+ if (isolate()->debug()->is_loaded() ||
isolate()->debug()->has_break_points()) {
enable = false;
}
=======================================
--- /branches/bleeding_edge/src/runtime.cc Fri May 30 17:07:38 2014 UTC
+++ /branches/bleeding_edge/src/runtime.cc Mon Jun 2 11:41:50 2014 UTC
@@ -10698,7 +10698,7 @@
RUNTIME_FUNCTION(Runtime_DebugBreak) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 0);
- Execution::DebugBreakHelper(isolate);
+ isolate->debug()->DebugBreakHelper();
return isolate->heap()->undefined_value();
}
@@ -10815,7 +10815,7 @@
// could have the assumption that its own native context is the current
// context and not some internal debugger context.
SaveContext save(isolate);
- if (isolate->debug()->InDebugger()) {
+ if (isolate->debug()->is_entered()) {
isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
}
@@ -12862,7 +12862,7 @@
CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 5);
// Handle the processing of break.
- DisableBreak disable_break_save(isolate, disable_break);
+ DisableBreak disable_break_scope(isolate->debug(), disable_break);
// Get the frame where the debugging is performed.
StackFrame::Id id = UnwrapFrameId(wrapped_id);
@@ -12926,7 +12926,7 @@
CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 3);
// Handle the processing of break.
- DisableBreak disable_break_save(isolate, disable_break);
+ DisableBreak disable_break_scope(isolate->debug(), disable_break);
// Enter the top context from before the debugger was invoked.
SaveContext save(isolate);
=======================================
--- /branches/bleeding_edge/test/cctest/test-debug.cc Mon Jun 2 06:22:09
2014 UTC
+++ /branches/bleeding_edge/test/cctest/test-debug.cc Mon Jun 2 11:41:50
2014 UTC
@@ -4189,7 +4189,7 @@
{
v8::Debug::DebugBreak(env->GetIsolate());
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(env->GetIsolate());
- v8::internal::DisableBreak disable_break(isolate, true);
+ v8::internal::DisableBreak disable_break(isolate->debug(), true);
f->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.