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