| Index: src/debug.cc
 | 
| diff --git a/src/debug.cc b/src/debug.cc
 | 
| index 87e28f8f15be90f18e69853304ad064a8a7a92bf..752dd25da3d9a6c6ec848257e2b4b7454bff91c7 100644
 | 
| --- a/src/debug.cc
 | 
| +++ b/src/debug.cc
 | 
| @@ -39,10 +39,10 @@ Debug::Debug(Isolate* isolate)
 | 
|        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 @@ bool BreakLocationIterator::Done() const {
 | 
|  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::ClearBreakPoint(Handle<Object> break_point_object) {
 | 
|  
 | 
|  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::SetOneShot() {
 | 
|  
 | 
|  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::ClearOneShot() {
 | 
|  
 | 
|  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::SetDebugBreak() {
 | 
|  
 | 
|  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::CompileDebuggerScript(Isolate* isolate, int index) {
 | 
|  
 | 
|  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 @@ void Debug::Unload() {
 | 
|    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 @@ void Debug::Break(Arguments args, JavaScriptFrame* frame) {
 | 
|    }
 | 
|  
 | 
|    // 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 @@ void Debug::PrepareStep(StepAction step_action,
 | 
|  
 | 
|    PrepareForBreakPoints();
 | 
|  
 | 
| -  ASSERT(Debug::InDebugger());
 | 
| +  ASSERT(is_entered());
 | 
|  
 | 
|    // Remember this step action and count.
 | 
|    thread_local_.last_step_action_ = step_action;
 | 
| @@ -1647,18 +1635,6 @@ Handle<Object> Debug::GetSourceBreakLocations(
 | 
|  }
 | 
|  
 | 
|  
 | 
| -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.
 | 
|  void Debug::HandleStepIn(Handle<JSFunction> function,
 | 
|                           Handle<Object> holder,
 | 
| @@ -2446,7 +2422,7 @@ void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
 | 
|  
 | 
|  
 | 
|  bool Debug::IsDebugGlobal(GlobalObject* global) {
 | 
| -  return IsLoaded() && global == debug_context()->global_object();
 | 
| +  return is_loaded() && global == debug_context()->global_object();
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -2456,16 +2432,15 @@ void Debug::ClearMirrorCache() {
 | 
|    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 @@ void Debug::AfterGarbageCollection() {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -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 @@ MaybeHandle<Object> Debug::MakeBreakEvent(Handle<Object> break_points_hit) {
 | 
|    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 @@ MaybeHandle<Object> Debug::MakeExceptionEvent(Handle<Object> exception,
 | 
|                              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 @@ MaybeHandle<Object> Debug::MakeCompileEvent(Handle<Script> script,
 | 
|    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 @@ MaybeHandle<Object> Debug::MakeScriptCollectedEvent(int id) {
 | 
|    // 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 @@ void Debug::OnException(Handle<Object> exception, bool uncaught) {
 | 
|    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 @@ void Debug::OnBeforeCompile(Handle<Script> script) {
 | 
|    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 @@ void Debug::OnAfterCompile(Handle<Script> script,
 | 
|    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 @@ void Debug::OnScriptCollected(int id) {
 | 
|    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 @@ void Debug::ProcessDebugEvent(v8::DebugEvent event,
 | 
|    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,50 +2815,32 @@ void Debug::CallEventCallback(v8::DebugEvent event,
 | 
|                                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::EventCallback2 callback =
 | 
| +        FUNCTION_CAST<v8::Debug::EventCallback2>(
 | 
| +            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::EventCallback2 callback =
 | 
| -      FUNCTION_CAST<v8::Debug::EventCallback2>(
 | 
| -          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() {
 | 
|    EnterDebugger debugger(isolate_);
 | 
|    // The global handle may be destroyed soon after.  Return it reboxed.
 | 
| @@ -2936,7 +2881,7 @@ void Debug::NotifyMessageHandler(v8::DebugEvent event,
 | 
|    // 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 @@ void Debug::NotifyMessageHandler(v8::DebugEvent event,
 | 
|    // 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 @@ void Debug::NotifyMessageHandler(v8::DebugEvent event,
 | 
|      // 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::SetEventListener(Handle<Object> callback,
 | 
|  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::SetMessageHandler(v8::Debug::MessageHandler handler) {
 | 
|  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 @@ void Debug::EnqueueCommandMessage(Vector<const uint16_t> command,
 | 
|    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 @@ void Debug::EnqueueDebugCommand(v8::Debug::ClientData* client_data) {
 | 
|    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();
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -3152,6 +3090,56 @@ MaybeHandle<Object> Debug::Call(Handle<JSFunction> fun, Handle<Object> data) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| +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)
 | 
|      : isolate_(isolate),
 | 
|        prev_(isolate_->debug()->debugger_entry()),
 | 
| @@ -3159,7 +3147,7 @@ EnterDebugger::EnterDebugger(Isolate* isolate)
 | 
|    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 @@ EnterDebugger::EnterDebugger(Isolate* isolate)
 | 
|    // 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 @@ EnterDebugger::~EnterDebugger() {
 | 
|    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 @@ EnterDebugger::~EnterDebugger() {
 | 
|  
 | 
|      // 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();
 | 
|  }
 | 
| 
 |