1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef V8_DEBUG_DEBUG_H_ 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define V8_DEBUG_DEBUG_H_ 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/allocation.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/assembler.h" 10958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/base/atomicops.h" 1113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/base/hashmap.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/platform.h" 13c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/debug/debug-interface.h" 1462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/debug/interface-types.h" 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/execution.h" 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/factory.h" 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/flags.h" 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/frames.h" 19f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/globals.h" 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/runtime/runtime.h" 21f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/source-position-table.h" 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/string-stream.h" 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8threads.h" 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "include/v8-debug.h" 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Forward declarations. 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass DebugScope; 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Step actions. NOTE: These values are in macros.py as well. 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochenum StepAction : int8_t { 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StepNone = -1, // Stepping not prepared. 38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StepOut = 0, // Step out of the current function. 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StepNext = 1, // Step to the next statement in the current function. 40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StepIn = 2, // Step into new functions invoked or the next statement 41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // in the current function. 4262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch LastStepAction = StepIn 4313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}; 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Type of exception break. NOTE: These values are in macros.py as well. 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum ExceptionBreakType { 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block BreakException = 0, 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block BreakUncaughtException = 1 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The different types of breakpoint position alignments. 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Must match Debug.BreakPositionAlignment in debug.js 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum BreakPositionAlignment { 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATEMENT_ALIGNED = 0, 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BREAK_POSITION_ALIGNED = 1 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 59f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochenum DebugBreakType { 60f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NOT_DEBUG_BREAK, 61f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DEBUGGER_STATEMENT, 62f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DEBUG_BREAK_SLOT, 63f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DEBUG_BREAK_SLOT_AT_CALL, 64f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DEBUG_BREAK_SLOT_AT_RETURN, 65f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DEBUG_BREAK_SLOT_AT_TAIL_CALL, 66f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}; 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass BreakLocation { 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 70109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static BreakLocation FromFrame(Handle<DebugInfo> debug_info, 71109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch JavaScriptFrame* frame); 72109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 73f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static void AllAtCurrentStatement(Handle<DebugInfo> debug_info, 74f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch JavaScriptFrame* frame, 75f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch List<BreakLocation>* result_out); 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 77109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch inline bool IsReturn() const { return type_ == DEBUG_BREAK_SLOT_AT_RETURN; } 78109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch inline bool IsCall() const { return type_ == DEBUG_BREAK_SLOT_AT_CALL; } 793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline bool IsTailCall() const { 803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return type_ == DEBUG_BREAK_SLOT_AT_TAIL_CALL; 813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 82109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch inline bool IsDebugBreakSlot() const { return type_ >= DEBUG_BREAK_SLOT; } 83109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch inline bool IsDebuggerStatement() const { 84109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return type_ == DEBUGGER_STATEMENT; 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 87f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool HasBreakPoint(Handle<DebugInfo> debug_info) const; 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 89f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inline int position() const { return position_; } 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 91f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private: 92f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BreakLocation(Handle<AbstractCode> abstract_code, DebugBreakType type, 93f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int code_offset, int position) 94f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch : abstract_code_(abstract_code), 95f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch code_offset_(code_offset), 96f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch type_(type), 97f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch position_(position) { 98f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_NE(NOT_DEBUG_BREAK, type_); 99f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 101f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static int BreakIndexFromCodeOffset(Handle<DebugInfo> debug_info, 102f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<AbstractCode> abstract_code, 103f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int offset); 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 105f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void SetDebugBreak(); 106f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void ClearDebugBreak(); 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 108f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<AbstractCode> abstract_code_; 109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int code_offset_; 110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DebugBreakType type_; 111f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int position_; 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 113f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch friend class CodeBreakIterator; 114f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch friend class BytecodeArrayBreakIterator; 115f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}; 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass BreakIterator { 118f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public: 119f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static std::unique_ptr<BreakIterator> GetIterator( 12062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<DebugInfo> debug_info, Handle<AbstractCode> abstract_code); 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 122f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch virtual ~BreakIterator() {} 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 124f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch virtual BreakLocation GetBreakLocation() = 0; 125f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch virtual bool Done() const = 0; 126f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch virtual void Next() = 0; 1277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 128f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void SkipTo(int count) { 129f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch while (count-- > 0) Next(); 130f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 132f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch virtual int code_offset() = 0; 133f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int break_index() const { return break_index_; } 134f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inline int position() const { return position_; } 135f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inline int statement_position() const { return statement_position_; } 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 137f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch virtual bool IsDebugBreak() = 0; 138f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch virtual void ClearDebugBreak() = 0; 139f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch virtual void SetDebugBreak() = 0; 1403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 141f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch protected: 14262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch explicit BreakIterator(Handle<DebugInfo> debug_info); 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 144f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int BreakIndexFromPosition(int position, BreakPositionAlignment alignment); 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 146f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Isolate* isolate() { return debug_info_->GetIsolate(); } 1478389745919cae02139ddc085a63c00d024269cf2Ben Murdoch 148f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<DebugInfo> debug_info_; 149f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int break_index_; 150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int position_; 151f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int statement_position_; 152109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 153f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private: 154f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DisallowHeapAllocation no_gc_; 155f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DISALLOW_COPY_AND_ASSIGN(BreakIterator); 156f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}; 157109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 158f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass CodeBreakIterator : public BreakIterator { 159f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public: 16062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch explicit CodeBreakIterator(Handle<DebugInfo> debug_info); 161f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ~CodeBreakIterator() override {} 162109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BreakLocation GetBreakLocation() override; 164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool Done() const override { return reloc_iterator_.done(); } 165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void Next() override; 166109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool IsDebugBreak() override; 168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void ClearDebugBreak() override; 169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void SetDebugBreak() override; 170109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void SkipToPosition(int position, BreakPositionAlignment alignment); 172109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int code_offset() override { 174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return static_cast<int>(rinfo()->pc() - 175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch debug_info_->DebugCode()->instruction_start()); 176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 177109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private: 17962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int GetModeMask(); 180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DebugBreakType GetDebugBreakType(); 181109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch RelocInfo::Mode rmode() { return reloc_iterator_.rinfo()->rmode(); } 183f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch RelocInfo* rinfo() { return reloc_iterator_.rinfo(); } 184109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch RelocIterator reloc_iterator_; 186f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch SourcePositionTableIterator source_position_iterator_; 187f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DISALLOW_COPY_AND_ASSIGN(CodeBreakIterator); 188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}; 189109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass BytecodeArrayBreakIterator : public BreakIterator { 191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public: 19262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch explicit BytecodeArrayBreakIterator(Handle<DebugInfo> debug_info); 193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ~BytecodeArrayBreakIterator() override {} 194109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BreakLocation GetBreakLocation() override; 196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool Done() const override { return source_position_iterator_.done(); } 197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void Next() override; 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool IsDebugBreak() override; 200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void ClearDebugBreak() override; 201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void SetDebugBreak() override; 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void SkipToPosition(int position, BreakPositionAlignment alignment); 204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int code_offset() override { return source_position_iterator_.code_offset(); } 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private: 208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DebugBreakType GetDebugBreakType(); 209f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 210f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch SourcePositionTableIterator source_position_iterator_; 211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DISALLOW_COPY_AND_ASSIGN(BytecodeArrayBreakIterator); 212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}; 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Linked list holding debug info objects. The debug info objects are kept as 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// weak handles to avoid a debug info object to keep a function alive. 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass DebugInfoListNode { 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit DebugInfoListNode(DebugInfo* debug_info); 219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ~DebugInfoListNode(); 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugInfoListNode* next() { return next_; } 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void set_next(DebugInfoListNode* next) { next_ = next; } 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<DebugInfo> debug_info() { return Handle<DebugInfo>(debug_info_); } 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Global (weak) handle to the debug info object. 227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DebugInfo** debug_info_; 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Next pointer for linked list. 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugInfoListNode* next_; 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass DebugFeatureTracker { 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum Feature { 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kActive = 1, 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kBreakPoint = 2, 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kStepping = 3, 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kHeapSnapshot = 4, 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kAllocationTracking = 5, 241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kProfiler = 6, 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kLiveEdit = 7, 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit DebugFeatureTracker(Isolate* isolate) 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : isolate_(isolate), bitfield_(0) {} 247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Track(Feature feature); 248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate_; 251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t bitfield_; 252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// This class contains the debugger support. The main purpose is to handle 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// setting break points in the code. 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// This class controls the debug info for all functions which currently have 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// active breakpoints in them. This debug info is held in the heap root object 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// debug_info which is a FixedArray. Each entry in this list is of class 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// DebugInfo. 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Debug { 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Debug event triggers. 26562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void OnDebugBreak(Handle<Object> break_points_hit); 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void OnThrow(Handle<Object> exception); 268f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void OnPromiseReject(Handle<Object> promise, Handle<Object> value); 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void OnCompileError(Handle<Script> script); 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void OnAfterCompile(Handle<Script> script); 27162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id, 27262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int parent_id); 27362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MUST_USE_RESULT MaybeHandle<Object> Call(Handle<Object> fun, 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> data); 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Context> GetDebugContext(); 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void HandleDebugBreak(); 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Internal logic 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool Load(); 2813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void Break(JavaScriptFrame* frame); 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Scripts handling. 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> GetLoadedScripts(); 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Break point handling. 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool SetBreakPoint(Handle<JSFunction> function, 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> break_point_object, 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int* source_position); 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool SetBreakPointForScript(Handle<Script> script, 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> break_point_object, 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int* source_position, 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakPositionAlignment alignment); 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearBreakPoint(Handle<Object> break_point_object); 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ChangeBreakOnException(ExceptionBreakType type, bool enable); 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsBreakOnException(ExceptionBreakType type); 2973bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 29862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // The parameter is either a BreakPointInfo object, or a FixedArray of 29962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // BreakPointInfo objects. 30062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Returns an empty handle if no breakpoint is hit, or a FixedArray with all 30162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // hit breakpoints. 30262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MaybeHandle<FixedArray> GetHitBreakPointObjects( 30362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> break_point_objects); 30462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Stepping handling. 306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void PrepareStep(StepAction step_action); 307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void PrepareStepIn(Handle<JSFunction> function); 30813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void PrepareStepInSuspendedGenerator(); 309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void PrepareStepOnThrow(); 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearStepping(); 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearStepOut(); 312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool PrepareFunctionForBreakPoints(Handle<SharedFunctionInfo> shared); 314c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch bool GetPossibleBreakpoints(Handle<Script> script, int start_position, 315c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int end_position, std::set<int>* positions); 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void RecordGenerator(Handle<JSGeneratorObject> generator_object); 31862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 31962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void RunPromiseHook(PromiseHookType type, Handle<JSPromise> promise, 32062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> parent); 32162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 32262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int NextAsyncTaskId(Handle<JSObject> promise); 32362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 32462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool IsBlackboxed(Handle<SharedFunctionInfo> shared); 32562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 32662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void SetDebugDelegate(debug::DebugDelegate* delegate, bool pass_ownership); 32713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 32862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Returns whether the operation succeeded. 32962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared); 330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void CreateDebugInfo(Handle<SharedFunctionInfo> shared); 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared); 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch template <typename C> 334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool CompileToRevealInnerFunctions(C* compilable); 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This function is used in FunctionNameUsing* tests. 337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> FindSharedFunctionInfoInScript(Handle<Script> script, 338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int position); 339e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Handle<Object> GetSourceBreakLocations( 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<SharedFunctionInfo> shared, 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakPositionAlignment position_aligment); 3436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check whether a global object is the debug global object. 345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool IsDebugGlobal(JSGlobalObject* global); 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check whether this frame is just about to return. 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsBreakAtReturn(JavaScriptFrame* frame); 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Support for LiveEdit 35162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void ScheduleFrameRestart(StackFrame* frame); 35262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 35362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool IsFrameBlackboxed(JavaScriptFrame* frame); 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Threading support. 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch char* ArchiveDebug(char* to); 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch char* RestoreDebug(char* from); 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static int ArchiveSpacePerThread(); 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void FreeThreadResources() { } 36013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void Iterate(ObjectVisitor* v); 361086aeeaae12517475c22695a200be45495516549Ben Murdoch 362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool CheckExecutionState(int id) { 363c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return CheckExecutionState() && break_id() == id; 364c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 365c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 366c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch bool CheckExecutionState() { 367c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return is_active() && !debug_context().is_null() && break_id() != 0; 368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 37062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool PerformSideEffectCheck(Handle<JSFunction> function); 37162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool PerformSideEffectCheckForCallback(Address function); 37262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Flags and states. 374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DebugScope* debugger_entry() { 375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return reinterpret_cast<DebugScope*>( 376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier base::NoBarrier_Load(&thread_local_.current_debug_scope_)); 377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline Handle<Context> debug_context() { return debug_context_; } 379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; } 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool live_edit_enabled() const { 382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return FLAG_enable_liveedit && live_edit_enabled_; 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool is_active() const { return is_active_; } 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool is_loaded() const { return !debug_context_.is_null(); } 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool in_debug_scope() const { 388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return !!base::NoBarrier_Load(&thread_local_.current_debug_scope_); 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void set_break_points_active(bool v) { break_points_active_ = v; } 391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool break_points_active() const { return break_points_active_; } 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StackFrame::Id break_frame_id() { return thread_local_.break_frame_id_; } 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int break_id() { return thread_local_.break_id_; } 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 39662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> return_value_handle() { 39762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return handle(thread_local_.return_value_, isolate_); 3983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 39962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Object* return_value() { return thread_local_.return_value_; } 40062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void set_return_value(Object* value) { thread_local_.return_value_ = value; } 4013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Support for embedding into generated code. 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address is_active_address() { 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<Address>(&is_active_); 4053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Address hook_on_function_call_address() { 40862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return reinterpret_cast<Address>(&hook_on_function_call_); 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 41113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Address last_step_action_address() { 41213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return reinterpret_cast<Address>(&thread_local_.last_step_action_); 41313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 41413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 41513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Address suspended_generator_address() { 41613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return reinterpret_cast<Address>(&thread_local_.suspended_generator_); 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 418f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 41962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Address restart_fp_address() { 42062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return reinterpret_cast<Address>(&thread_local_.restart_fp_); 42162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 42262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StepAction last_step_action() { return thread_local_.last_step_action_; } 424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DebugFeatureTracker* feature_tracker() { return &feature_tracker_; } 426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 427f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke private: 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit Debug(Isolate* isolate); 42962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ~Debug() { DCHECK_NULL(debug_delegate_); } 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void UpdateState(); 43262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void UpdateHookOnFunctionCall(); 43362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void RemoveDebugDelegate(); 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Unload(); 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetNextBreakId() { 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch thread_local_.break_id_ = ++thread_local_.break_count_; 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 43962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Return the number of virtual frames below debugger entry. 44062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int CurrentFrameCount(); 44162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 44262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch inline bool ignore_events() const { 44362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return is_suppressed_ || !is_active_ || isolate_->needs_side_effect_check(); 444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 44562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch inline bool break_disabled() const { return break_disabled_; } 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 44713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void clear_suspended_generator() { 448c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch thread_local_.suspended_generator_ = Smi::kZero; 44913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 45013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 45113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch bool has_suspended_generator() const { 452c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return thread_local_.suspended_generator_ != Smi::kZero; 45313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 45413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 45562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool IsExceptionBlackboxed(bool uncaught); 45662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void OnException(Handle<Object> exception, Handle<Object> promise); 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Constructors for debug event objects. 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState(); 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent( 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> break_points_hit); 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent( 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> exception, 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool uncaught, 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> promise); 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent( 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Script> script, v8::DebugEvent type); 46962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MUST_USE_RESULT MaybeHandle<Object> MakeAsyncTaskEvent( 47062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::debug::PromiseDebugActionType type, int id); 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script); 47362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data); 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 475f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Find the closest source position for a break point for a given position. 476f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int FindBreakablePosition(Handle<DebugInfo> debug_info, int source_position, 477f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BreakPositionAlignment alignment); 478f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Instrument code to break at break points. 479f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void ApplyBreakPoints(Handle<DebugInfo> debug_info); 480f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Clear code from instrumentation. 481f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void ClearBreakPoints(Handle<DebugInfo> debug_info); 482f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Clear all code from instrumentation. 483f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void ClearAllBreakPoints(); 484f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Instrument a function with one-shots. 48562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void FloodWithOneShot(Handle<SharedFunctionInfo> function); 486f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Clear all one-shot instrumentations, but restore break points. 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClearOneShot(); 488f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ActivateStepOut(StackFrame* frame); 490958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void RemoveDebugInfoAndClearFromShared(Handle<DebugInfo> debug_info); 49162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MaybeHandle<FixedArray> CheckBreakPoints(Handle<DebugInfo> debug_info, 49262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch BreakLocation* location, 49362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool* has_break_points = nullptr); 494109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bool IsMutedAtCurrentLocation(JavaScriptFrame* frame); 495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool CheckBreakPoint(Handle<Object> break_point_object); 496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MaybeHandle<Object> CallFunction(const char* name, int argc, 497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> args[]); 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void AssertDebugContext() { 500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(isolate_->context() == *debug_context()); 501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(in_debug_scope()); 502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ThreadInit(); 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void PrintBreakLocation(); 5073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Global handles. 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Context> debug_context_; 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 51162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch debug::DebugDelegate* debug_delegate_ = nullptr; 51262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool owns_debug_delegate_ = false; 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 51462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Debugger is active, i.e. there is a debug event listener attached. 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_active_; 51662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Debugger needs to be notified on every new function call. 51762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Used for stepping and read-only checks 51862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool hook_on_function_call_; 51962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Suppress debug events. 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_suppressed_; 52162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // LiveEdit is enabled. 522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool live_edit_enabled_; 52362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Do not trigger debug break events. 524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool break_disabled_; 52562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Do not break on break points. 526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool break_points_active_; 52762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Trigger debug break events for all exceptions. 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool break_on_exception_; 52962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Trigger debug break events for uncaught exceptions. 530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool break_on_uncaught_exception_; 53162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Termination exception because side effect check has failed. 53262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool side_effect_check_failed_; 533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 53462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // List of active debug info objects. 53562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DebugInfoListNode* debug_info_list_; 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Used to collect histogram data on debugger feature usage. 538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DebugFeatureTracker feature_tracker_; 539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Per-thread data. 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class ThreadLocal { 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Top debugger entry. 544958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier base::AtomicWord current_debug_scope_; 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Counter for generating next break id. 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int break_count_; 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Current break id. 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int break_id_; 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Frame id for the frame of the current break. 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StackFrame::Id break_frame_id_; 554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Step action for last step performed. 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StepAction last_step_action_; 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Source statement position from last step next action. 559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int last_statement_position_; 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 561958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Frame pointer from last step next or step frame action. 56262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int last_frame_count_; 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Frame pointer of the target frame we want to arrive at. 56562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int target_frame_count_; 5663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 56762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Value of the accumulator at the point of entering the debugger. 56862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Object* return_value_; 56913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 57062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // The suspended generator object to track when stepping. 57113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Object* suspended_generator_; 57262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 57362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // The new frame pointer to drop to when restarting a frame. 57462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Address restart_fp_; 57562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 57662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int async_task_count_; 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Storage location for registers when handling debug break calls 580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ThreadLocal thread_local_; 581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 58244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate_; 5833bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 58444f0eee88ff00398ff7f715fab053374d808c90dSteve Block friend class Isolate; 585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class DebugScope; 586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class DisableBreak; 587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class LiveEdit; 588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class SuppressDebug; 58962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch friend class NoSideEffectScope; 59062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch friend class LegacyDebugDelegate; 59144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend Handle<FixedArray> GetDebuggedFunctions(); // In test-debug.cc 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend void CheckDebuggerUnloaded(bool check_functions); // In test-debug.cc 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(Debug); 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 59862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochclass LegacyDebugDelegate : public v8::debug::DebugDelegate { 59962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch public: 60062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch explicit LegacyDebugDelegate(Isolate* isolate) : isolate_(isolate) {} 60162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void PromiseEventOccurred(v8::debug::PromiseDebugActionType type, int id, 60262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int parent_id) override; 60362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void ScriptCompiled(v8::Local<v8::debug::Script> script, 60462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool has_compile_error) override; 60562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void BreakProgramRequested(v8::Local<v8::Context> paused_context, 60662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::Local<v8::Object> exec_state, 60762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::Local<v8::Value> break_points_hit) override; 60862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void ExceptionThrown(v8::Local<v8::Context> paused_context, 60962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::Local<v8::Object> exec_state, 61062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::Local<v8::Value> exception, 61162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::Local<v8::Value> promise, bool is_uncaught) override; 61262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool IsFunctionBlackboxed(v8::Local<v8::debug::Script> script, 61362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const v8::debug::Location& start, 61462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const v8::debug::Location& end) override { 61562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return false; 61662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 61762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 61862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch protected: 61962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Isolate* isolate_; 62062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 62162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch private: 62262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data); 62362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch virtual void ProcessDebugEvent(v8::DebugEvent event, 62462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<JSObject> event_data, 62562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<JSObject> exec_state) = 0; 62662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}; 62762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 62862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochclass JavaScriptDebugDelegate : public LegacyDebugDelegate { 62962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch public: 63062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JavaScriptDebugDelegate(Isolate* isolate, Handle<JSFunction> listener, 63162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> data); 63262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch virtual ~JavaScriptDebugDelegate(); 63362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 63462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch private: 63562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data, 63662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<JSObject> exec_state) override; 63762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 63862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<JSFunction> listener_; 63962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> data_; 64062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}; 64162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 64262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochclass NativeDebugDelegate : public LegacyDebugDelegate { 64362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch public: 64462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch NativeDebugDelegate(Isolate* isolate, v8::Debug::EventCallback callback, 64562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> data); 64662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch virtual ~NativeDebugDelegate(); 64762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 64862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch private: 64962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Details of the debug event delivered to the debug event listener. 65062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch class EventDetails : public v8::Debug::EventDetails { 65162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch public: 65262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch EventDetails(DebugEvent event, Handle<JSObject> exec_state, 65362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<JSObject> event_data, Handle<Object> callback_data); 65462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch virtual DebugEvent GetEvent() const; 65562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch virtual v8::Local<v8::Object> GetExecutionState() const; 65662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch virtual v8::Local<v8::Object> GetEventData() const; 65762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch virtual v8::Local<v8::Context> GetEventContext() const; 65862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch virtual v8::Local<v8::Value> GetCallbackData() const; 65962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch virtual v8::Debug::ClientData* GetClientData() const { return nullptr; } 66062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch virtual v8::Isolate* GetIsolate() const; 66162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 66262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch private: 66362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DebugEvent event_; // Debug event causing the break. 66462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<JSObject> exec_state_; // Current execution state. 66562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<JSObject> event_data_; // Data associated with the event. 66662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> callback_data_; // User data passed with the callback 66762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // when it was registered. 66862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch }; 66962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 67062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data, 67162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<JSObject> exec_state) override; 67262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 67362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::Debug::EventCallback callback_; 67462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> data_; 67562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}; 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// This scope is used to load and enter the debug context and create a new 678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// break state. Leaving the scope will restore the previous state. 679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// On failure to load, FailedToEnter returns true. 680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass DebugScope BASE_EMBEDDED { 681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit DebugScope(Debug* debug); 683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~DebugScope(); 684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check whether loading was successful. 686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool failed() { return failed_; } 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the active context from before entering the debugger. 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Handle<Context> GetContext() { return save_.context(); } 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate() { return debug_->isolate_; } 693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Debug* debug_; 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebugScope* prev_; // Previous scope if entered recursively. 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackFrame::Id break_frame_id_; // Previous break frame id. 697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int break_id_; // Previous break id. 698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool failed_; // Did the debug context fail to load? 699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveContext save_; // Saves previous context. 700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PostponeInterruptsScope no_termination_exceptons_; 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 70362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// This scope is used to handle return values in nested debug break points. 70462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// When there are nested debug breaks, we use this to restore the return 70562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// value to the previous state. This is not merged with DebugScope because 70662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// return_value_ will not be cleared when we use DebugScope. 70762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochclass ReturnValueScope { 70862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch public: 70962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch explicit ReturnValueScope(Debug* debug); 71062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ~ReturnValueScope(); 71162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 71262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch private: 71362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Debug* debug_; 71462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> return_value_; // Previous result. 71562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}; 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Stack allocated class for disabling break. 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass DisableBreak BASE_EMBEDDED { 719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 72062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch explicit DisableBreak(Debug* debug) 72162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : debug_(debug), previous_break_disabled_(debug->break_disabled_) { 72262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch debug_->break_disabled_ = true; 723958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 724958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ~DisableBreak() { 725958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier debug_->break_disabled_ = previous_break_disabled_; 726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Debug* debug_; 730958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool previous_break_disabled_; 731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(DisableBreak); 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass SuppressDebug BASE_EMBEDDED { 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit SuppressDebug(Debug* debug) 738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : debug_(debug), old_state_(debug->is_suppressed_) { 739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch debug_->is_suppressed_ = true; 740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~SuppressDebug() { debug_->is_suppressed_ = old_state_; } 742589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Debug* debug_; 745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool old_state_; 746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(SuppressDebug); 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 74962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochclass NoSideEffectScope { 75062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch public: 75162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch NoSideEffectScope(Isolate* isolate, bool disallow_side_effects) 75262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : isolate_(isolate), 75362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch old_needs_side_effect_check_(isolate->needs_side_effect_check()) { 75462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate->set_needs_side_effect_check(old_needs_side_effect_check_ || 75562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch disallow_side_effects); 75662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate->debug()->UpdateHookOnFunctionCall(); 75762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate->debug()->side_effect_check_failed_ = false; 75862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 75962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ~NoSideEffectScope(); 76062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 76162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch private: 76262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Isolate* isolate_; 76362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool old_needs_side_effect_check_; 76462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DISALLOW_COPY_AND_ASSIGN(NoSideEffectScope); 76562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}; 766e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Code generator routines. 768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass DebugCodegen : public AllStatic { 769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch enum DebugBreakCallHelperMode { 771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SAVE_RESULT_REGISTER, 772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IGNORE_RESULT_REGISTER 773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void GenerateDebugBreakStub(MacroAssembler* masm, 776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DebugBreakCallHelperMode mode); 777e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 77862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static void GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode); 779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 78062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Builtin to drop frames to restart function. 78162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static void GenerateFrameDropperTrampoline(MacroAssembler* masm); 782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 78362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Builtin to atomically (wrt deopts) handle debugger statement and 78462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // drop frames to restart function if necessary. 78562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static void GenerateHandleDebuggerStatement(MacroAssembler* masm); 786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void PatchDebugBreakSlot(Isolate* isolate, Address pc, 788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> code); 789109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static bool DebugBreakSlotIsPatched(Address pc); 790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void ClearDebugBreakSlot(Isolate* isolate, Address pc); 791e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}; 792e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif // V8_DEBUG_DEBUG_H_ 798