| 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?
|
|
|