| Index: src/debug.h | 
| diff --git a/src/debug.h b/src/debug.h | 
| index 950570db4fa34bed0060f777d9472ee7864f844a..58c41c00fbdf090fe5c0a974b8b67e043b4bd339 100644 | 
| --- a/src/debug.h | 
| +++ b/src/debug.h | 
| @@ -150,10 +150,7 @@ class BreakLocationIterator { | 
| // the cache is the script id. | 
| class ScriptCache : private HashMap { | 
| public: | 
| -  explicit ScriptCache(Isolate* isolate) | 
| -      : HashMap(HashMap::PointersMatch), | 
| -        isolate_(isolate), | 
| -        collected_scripts_(10) {} | 
| +  explicit ScriptCache(Isolate* isolate); | 
| virtual ~ScriptCache() { Clear(); } | 
|  | 
| // Add script to the cache. | 
| @@ -287,7 +284,6 @@ class CommandMessage { | 
| static CommandMessage New(const Vector<uint16_t>& command, | 
| v8::Debug::ClientData* data); | 
| CommandMessage(); | 
| -  ~CommandMessage(); | 
|  | 
| // Deletes user data and disposes of the text. | 
| void Dispose(); | 
| @@ -342,6 +338,23 @@ class LockingCommandMessageQueue BASE_EMBEDDED { | 
| }; | 
|  | 
|  | 
| +class PromiseOnStack { | 
| + public: | 
| +  PromiseOnStack(Isolate* isolate, | 
| +                 PromiseOnStack* prev, | 
| +                 Handle<JSFunction> getter); | 
| +  ~PromiseOnStack(); | 
| +  StackHandler* handler() { return handler_; } | 
| +  Handle<JSFunction> getter() { return getter_; } | 
| +  PromiseOnStack* prev() { return prev_; } | 
| + private: | 
| +  Isolate* isolate_; | 
| +  StackHandler* handler_; | 
| +  Handle<JSFunction> getter_; | 
| +  PromiseOnStack* prev_; | 
| +}; | 
| + | 
| + | 
| // This class contains the debugger support. The main purpose is to handle | 
| // setting break points in the code. | 
| // | 
| @@ -374,29 +387,18 @@ class Debug { | 
| MUST_USE_RESULT MaybeHandle<Object> Call(Handle<JSFunction> fun, | 
| Handle<Object> data); | 
| Handle<Context> GetDebugContext(); | 
| -  void DebugBreakHelper(); | 
| +  void HandleDebugBreak(); | 
| void ProcessDebugMessages(bool debug_command_only); | 
|  | 
| -  // 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_ ; | 
| -  } | 
| - | 
| -  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; | 
| -  } | 
| - | 
| -  void set_disable_break(bool v) { break_disabled_ = v; } | 
| - | 
| +  // Internal logic | 
| bool Load(); | 
| - | 
| void Break(Arguments args, JavaScriptFrame*); | 
| void SetAfterBreakTarget(JavaScriptFrame* frame); | 
|  | 
| +  // Scripts handling. | 
| +  Handle<FixedArray> GetLoadedScripts(); | 
| + | 
| +  // Break point handling. | 
| bool SetBreakPoint(Handle<JSFunction> function, | 
| Handle<Object> break_point_object, | 
| int* source_position); | 
| @@ -412,11 +414,7 @@ class Debug { | 
| void ChangeBreakOnException(ExceptionBreakType type, bool enable); | 
| bool IsBreakOnException(ExceptionBreakType type); | 
|  | 
| -  void PromiseHandlePrologue(Handle<JSFunction> promise_getter); | 
| -  void PromiseHandleEpilogue(); | 
| -  // Returns a promise if it does not have a reject handler. | 
| -  Handle<Object> GetPromiseForUncaughtException(); | 
| - | 
| +  // Stepping handling. | 
| void PrepareStep(StepAction step_action, | 
| int step_count, | 
| StackFrame::Id frame_id); | 
| @@ -425,6 +423,15 @@ class Debug { | 
| bool IsStepping() { return thread_local_.step_count_ > 0; } | 
| bool StepNextContinue(BreakLocationIterator* break_location_iterator, | 
| JavaScriptFrame* frame); | 
| +  bool StepInActive() { return thread_local_.step_into_fp_ != 0; } | 
| +  void HandleStepIn(Handle<JSFunction> function, | 
| +                    Handle<Object> holder, | 
| +                    Address fp, | 
| +                    bool is_constructor); | 
| +  bool StepOutActive() { return thread_local_.step_out_fp_ != 0; } | 
| + | 
| +  // Purge all code objects that have no debug break slots. | 
| +  void PrepareForBreakPoints(); | 
|  | 
| // Returns whether the operation succeeded. Compilation can only be triggered | 
| // if a valid closure is passed as the second argument, otherwise the shared | 
| @@ -434,125 +441,95 @@ class Debug { | 
| static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared); | 
| static bool HasDebugInfo(Handle<SharedFunctionInfo> shared); | 
|  | 
| -  void PrepareForBreakPoints(); | 
| - | 
| // This function is used in FunctionNameUsing* tests. | 
| Object* FindSharedFunctionInfoInScript(Handle<Script> script, int position); | 
|  | 
| - | 
| // 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); | 
|  | 
| static Handle<Object> GetSourceBreakLocations( | 
| Handle<SharedFunctionInfo> shared, | 
| BreakPositionAlignment position_aligment); | 
|  | 
| -  // Getter for the debug_context. | 
| -  inline Handle<Context> debug_context() { return debug_context_; } | 
| - | 
| // Check whether a global object is the debug global object. | 
| bool IsDebugGlobal(GlobalObject* global); | 
|  | 
| // Check whether this frame is just about to return. | 
| bool IsBreakAtReturn(JavaScriptFrame* frame); | 
|  | 
| -  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; } | 
| -  void HandleStepIn(Handle<JSFunction> function, | 
| -                    Handle<Object> holder, | 
| -                    Address fp, | 
| -                    bool is_constructor); | 
| -  Address step_in_fp() { return thread_local_.step_into_fp_; } | 
| -  Address* step_in_fp_addr() { return &thread_local_.step_into_fp_; } | 
| - | 
| -  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_; } | 
| - | 
| -  // Check whether any of the specified interrupts are pending. | 
| -  bool has_pending_interrupt() { | 
| -    return thread_local_.has_pending_interrupt_; | 
| -  } | 
| - | 
| -  // Set specified interrupts as pending. | 
| -  void set_has_pending_interrupt(bool value) { | 
| -    thread_local_.has_pending_interrupt_ = value; | 
| -  } | 
| - | 
| -  // Getters for the current exception break state. | 
| -  bool break_on_exception() { return break_on_exception_; } | 
| -  bool break_on_uncaught_exception() { | 
| -    return break_on_uncaught_exception_; | 
| -  } | 
| +  // Promise handling. | 
| +  void PromiseHandlePrologue(Handle<JSFunction> promise_getter); | 
| +  void PromiseHandleEpilogue(); | 
|  | 
| +  // Support for LiveEdit | 
| void FramesHaveBeenDropped(StackFrame::Id new_break_frame_id, | 
| LiveEdit::FrameDropMode mode, | 
| Object** restarter_frame_function_pointer); | 
|  | 
| -  // Support for setting the address to jump to when returning from break point. | 
| -  Address after_break_target_address() { | 
| -    return reinterpret_cast<Address>(&after_break_target_); | 
| -  } | 
| - | 
| -  Address restarter_frame_function_pointer_address() { | 
| -    Object*** address = &thread_local_.restarter_frame_function_pointer_; | 
| -    return reinterpret_cast<Address>(address); | 
| -  } | 
| - | 
| -  static const int kEstimatedNofBreakPointsInFunction = 16; | 
| - | 
| // Passed to MakeWeak. | 
| static void HandleWeakDebugInfo( | 
| const v8::WeakCallbackData<v8::Value, void>& data); | 
|  | 
| -  friend Handle<FixedArray> GetDebuggedFunctions();  // In test-debug.cc | 
| -  friend void CheckDebuggerUnloaded(bool check_functions);  // In test-debug.cc | 
| - | 
| // Threading support. | 
| char* ArchiveDebug(char* to); | 
| char* RestoreDebug(char* from); | 
| static int ArchiveSpacePerThread(); | 
| void FreeThreadResources() { } | 
|  | 
| -  // Script cache handling. | 
| -  void CreateScriptCache(); | 
| -  void DestroyScriptCache(); | 
| -  void AddScriptToScriptCache(Handle<Script> script); | 
| -  Handle<FixedArray> GetLoadedScripts(); | 
| - | 
| // Record function from which eval was called. | 
| static void RecordEvalCaller(Handle<Script> script); | 
|  | 
| // Garbage collection notifications. | 
| void AfterGarbageCollection(); | 
|  | 
| +  // Flags and states. | 
| +  EnterDebugger* debugger_entry() { return thread_local_.debugger_entry_; } | 
| +  inline Handle<Context> debug_context() { return debug_context_; } | 
| +  void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; } | 
| +  bool live_edit_enabled() const { | 
| +    return FLAG_enable_liveedit && live_edit_enabled_ ; | 
| +  } | 
| + | 
| +  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; | 
| +  } | 
| +  void set_disable_break(bool v) { break_disabled_ = v; } | 
| + | 
| +  StackFrame::Id break_frame_id() { return thread_local_.break_frame_id_; } | 
| +  int break_id() { return thread_local_.break_id_; } | 
| + | 
| +  // Support for embedding into generated code. | 
| +  Address after_break_target_address() { | 
| +    return reinterpret_cast<Address>(&after_break_target_); | 
| +  } | 
| + | 
| +  Address restarter_frame_function_pointer_address() { | 
| +    Object*** address = &thread_local_.restarter_frame_function_pointer_; | 
| +    return reinterpret_cast<Address>(address); | 
| +  } | 
| + | 
| +  Address step_in_fp_addr() { | 
| +    return reinterpret_cast<Address>(&thread_local_.step_into_fp_); | 
| +  } | 
| + | 
| 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(); } | 
| +  inline bool ignore_events() const { return is_suppressed_ || !is_active_; } | 
|  | 
| // Constructors for debug event objects. | 
| MUST_USE_RESULT MaybeHandle<Object> MakeJSObject( | 
| @@ -570,12 +547,16 @@ class Debug { | 
| Handle<Script> script, bool before); | 
| MUST_USE_RESULT MaybeHandle<Object> MakeScriptCollectedEvent(int id); | 
|  | 
| +  // Mirror cache handling. | 
| +  void ClearMirrorCache(); | 
| + | 
| +  // Returns a promise if it does not have a reject handler. | 
| +  Handle<Object> GetPromiseForUncaughtException(); | 
|  | 
| void CallEventCallback(v8::DebugEvent event, | 
| Handle<Object> exec_state, | 
| Handle<Object> event_data, | 
| v8::Debug::ClientData* client_data); | 
| - | 
| void ProcessDebugEvent(v8::DebugEvent event, | 
| Handle<JSObject> event_data, | 
| bool auto_continue); | 
| @@ -583,17 +564,8 @@ class Debug { | 
| Handle<JSObject> exec_state, | 
| Handle<JSObject> event_data, | 
| bool auto_continue); | 
| - | 
| -  // Invoke the message handler function. | 
| void InvokeMessageHandler(MessageImpl message); | 
|  | 
| -  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 !is_suppressed_ && is_active_; | 
| -  } | 
| - | 
| static bool CompileDebuggerScript(Isolate* isolate, int index); | 
| void ClearOneShot(); | 
| void ActivateStepIn(StackFrame* frame); | 
| @@ -605,28 +577,8 @@ class Debug { | 
| Handle<Object> CheckBreakPoints(Handle<Object> break_point); | 
| bool CheckBreakPoint(Handle<Object> break_point_object); | 
|  | 
| -  void EnsureFunctionHasDebugBreakSlots(Handle<JSFunction> function); | 
| -  void RecompileAndRelocateSuspendedGenerators( | 
| -      const List<Handle<JSGeneratorObject> > &suspended_generators); | 
| - | 
| void ThreadInit(); | 
|  | 
| -  class PromiseOnStack { | 
| -   public: | 
| -    PromiseOnStack(Isolate* isolate, | 
| -                   PromiseOnStack* prev, | 
| -                   Handle<JSFunction> getter); | 
| -    ~PromiseOnStack(); | 
| -    StackHandler* handler() { return handler_; } | 
| -    Handle<JSFunction> getter() { return getter_; } | 
| -    PromiseOnStack* prev() { return prev_; } | 
| -   private: | 
| -    Isolate* isolate_; | 
| -    StackHandler* handler_; | 
| -    Handle<JSFunction> getter_; | 
| -    PromiseOnStack* prev_; | 
| -  }; | 
| - | 
| // Global handles. | 
| Handle<Context> debug_context_; | 
| Handle<Object> event_listener_; | 
| @@ -692,9 +644,6 @@ class Debug { | 
| // step out action is completed. | 
| Address step_out_fp_; | 
|  | 
| -    // Pending interrupts scheduled while debugging. | 
| -    bool has_pending_interrupt_; | 
| - | 
| // Stores the way how LiveEdit has patched the stack. It is used when | 
| // debugger returns control back to user script. | 
| LiveEdit::FrameDropMode frame_drop_mode_; | 
| @@ -723,6 +672,9 @@ class Debug { | 
| friend class DisableBreak; | 
| friend class SuppressDebug; | 
|  | 
| +  friend Handle<FixedArray> GetDebuggedFunctions();  // In test-debug.cc | 
| +  friend void CheckDebuggerUnloaded(bool check_functions);  // In test-debug.cc | 
| + | 
| DISALLOW_COPY_AND_ASSIGN(Debug); | 
| }; | 
|  | 
| @@ -742,16 +694,12 @@ class EnterDebugger BASE_EMBEDDED { | 
| // Check whether the debugger could be entered. | 
| inline bool FailedToEnter() { return load_failed_; } | 
|  | 
| -  // Check whether there are any JavaScript frames on the stack. | 
| -  inline bool HasJavaScriptFrames() { return has_js_frames_; } | 
| - | 
| // Get the active context from before entering the debugger. | 
| inline Handle<Context> GetContext() { return save_.context(); } | 
|  | 
| private: | 
| Isolate* isolate_; | 
| EnterDebugger* prev_;  // Previous debugger entry if entered recursively. | 
| -  bool has_js_frames_;  // Were there any JavaScript frames? | 
| StackFrame::Id break_frame_id_;  // Previous break frame id. | 
| int break_id_;  // Previous break id. | 
| bool load_failed_;  // Did the debugger fail to load? | 
|  |