debug.h 29.8 KB
Newer Older
1
// Copyright 2012 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4

5 6
#ifndef V8_DEBUG_DEBUG_H_
#define V8_DEBUG_DEBUG_H_
7

8 9 10
#include "src/allocation.h"
#include "src/arguments.h"
#include "src/assembler.h"
11
#include "src/base/atomicops.h"
lpy's avatar
lpy committed
12
#include "src/base/hashmap.h"
13
#include "src/base/platform/platform.h"
14
#include "src/debug/debug-interface.h"
15
#include "src/debug/interface-types.h"
16 17 18
#include "src/execution.h"
#include "src/factory.h"
#include "src/flags.h"
19
#include "src/frames.h"
20
#include "src/globals.h"
21
#include "src/runtime/runtime.h"
22
#include "src/source-position-table.h"
23 24 25 26
#include "src/string-stream.h"
#include "src/v8threads.h"

#include "include/v8-debug.h"
27

28 29
namespace v8 {
namespace internal {
30

31 32

// Forward declarations.
33
class DebugScope;
34 35


36
// Step actions. NOTE: These values are in macros.py as well.
37
enum StepAction : int8_t {
38
  StepNone = -1,  // Stepping not prepared.
39 40 41 42
  StepOut = 0,    // Step out of the current function.
  StepNext = 1,   // Step to the next statement in the current function.
  StepIn = 2,     // Step into new functions invoked or the next statement
                  // in the current function.
43
  StepFrame = 3,  // Step into a new frame or return to previous frame.
44

45 46
  LastStepAction = StepFrame
};
47 48 49 50 51 52 53 54

// Type of exception break. NOTE: These values are in macros.py as well.
enum ExceptionBreakType {
  BreakException = 0,
  BreakUncaughtException = 1
};


55
// Type of exception break.
56
enum BreakLocatorType { ALL_BREAK_LOCATIONS, CALLS_AND_RETURNS };
57 58


59
// The different types of breakpoint position alignments.
60
// Must match Debug.BreakPositionAlignment in debug.js
61 62 63 64 65
enum BreakPositionAlignment {
  STATEMENT_ALIGNED = 0,
  BREAK_POSITION_ALIGNED = 1
};

66 67 68 69 70 71 72 73
enum DebugBreakType {
  NOT_DEBUG_BREAK,
  DEBUGGER_STATEMENT,
  DEBUG_BREAK_SLOT,
  DEBUG_BREAK_SLOT_AT_CALL,
  DEBUG_BREAK_SLOT_AT_RETURN,
  DEBUG_BREAK_SLOT_AT_TAIL_CALL,
};
74

75 76 77
const int kDebugPromiseNoID = 0;
const int kDebugPromiseFirstID = 1;

78
class BreakLocation {
79
 public:
80 81
  static BreakLocation FromFrame(Handle<DebugInfo> debug_info,
                                 JavaScriptFrame* frame);
82

83 84 85
  static void AllAtCurrentStatement(Handle<DebugInfo> debug_info,
                                    JavaScriptFrame* frame,
                                    List<BreakLocation>* result_out);
86

87 88
  inline bool IsReturn() const { return type_ == DEBUG_BREAK_SLOT_AT_RETURN; }
  inline bool IsCall() const { return type_ == DEBUG_BREAK_SLOT_AT_CALL; }
89 90 91
  inline bool IsTailCall() const {
    return type_ == DEBUG_BREAK_SLOT_AT_TAIL_CALL;
  }
92 93 94 95
  inline bool IsDebugBreakSlot() const { return type_ >= DEBUG_BREAK_SLOT; }
  inline bool IsDebuggerStatement() const {
    return type_ == DEBUGGER_STATEMENT;
  }
96

97
  bool HasBreakPoint(Handle<DebugInfo> debug_info) const;
98

99
  inline int position() const { return position_; }
100

101 102 103 104 105 106 107 108 109
 private:
  BreakLocation(Handle<AbstractCode> abstract_code, DebugBreakType type,
                int code_offset, int position)
      : abstract_code_(abstract_code),
        code_offset_(code_offset),
        type_(type),
        position_(position) {
    DCHECK_NE(NOT_DEBUG_BREAK, type_);
  }
110

111 112 113
  static int BreakIndexFromCodeOffset(Handle<DebugInfo> debug_info,
                                      Handle<AbstractCode> abstract_code,
                                      int offset);
114

115 116 117 118 119 120 121 122 123 124 125
  void SetDebugBreak();
  void ClearDebugBreak();

  Handle<AbstractCode> abstract_code_;
  int code_offset_;
  DebugBreakType type_;
  int position_;

  friend class CodeBreakIterator;
  friend class BytecodeArrayBreakIterator;
};
126

127 128 129 130 131 132 133
class BreakIterator {
 public:
  static std::unique_ptr<BreakIterator> GetIterator(
      Handle<DebugInfo> debug_info, Handle<AbstractCode> abstract_code,
      BreakLocatorType type = ALL_BREAK_LOCATIONS);

  virtual ~BreakIterator() {}
134

135 136 137 138 139 140
  virtual BreakLocation GetBreakLocation() = 0;
  virtual bool Done() const = 0;
  virtual void Next() = 0;

  void SkipTo(int count) {
    while (count-- > 0) Next();
141
  }
142

143 144 145 146
  virtual int code_offset() = 0;
  int break_index() const { return break_index_; }
  inline int position() const { return position_; }
  inline int statement_position() const { return statement_position_; }
147

148 149 150
  virtual bool IsDebugBreak() = 0;
  virtual void ClearDebugBreak() = 0;
  virtual void SetDebugBreak() = 0;
151

152 153 154
 protected:
  explicit BreakIterator(Handle<DebugInfo> debug_info,
                         BreakLocatorType break_locator_type);
155

156
  int BreakIndexFromPosition(int position, BreakPositionAlignment alignment);
157

158
  Isolate* isolate() { return debug_info_->GetIsolate(); }
159

160 161 162 163 164
  Handle<DebugInfo> debug_info_;
  int break_index_;
  int position_;
  int statement_position_;
  BreakLocatorType break_locator_type_;
165

166 167 168 169
 private:
  DisallowHeapAllocation no_gc_;
  DISALLOW_COPY_AND_ASSIGN(BreakIterator);
};
170

171 172 173 174
class CodeBreakIterator : public BreakIterator {
 public:
  CodeBreakIterator(Handle<DebugInfo> debug_info, BreakLocatorType type);
  ~CodeBreakIterator() override {}
175

176 177 178
  BreakLocation GetBreakLocation() override;
  bool Done() const override { return reloc_iterator_.done(); }
  void Next() override;
179

180 181 182
  bool IsDebugBreak() override;
  void ClearDebugBreak() override;
  void SetDebugBreak() override;
183

184
  void SkipToPosition(int position, BreakPositionAlignment alignment);
185

186 187 188 189
  int code_offset() override {
    return static_cast<int>(rinfo()->pc() -
                            debug_info_->DebugCode()->instruction_start());
  }
190

191 192 193
 private:
  int GetModeMask(BreakLocatorType type);
  DebugBreakType GetDebugBreakType();
194

195 196
  RelocInfo::Mode rmode() { return reloc_iterator_.rinfo()->rmode(); }
  RelocInfo* rinfo() { return reloc_iterator_.rinfo(); }
197

198 199 200 201
  RelocIterator reloc_iterator_;
  SourcePositionTableIterator source_position_iterator_;
  DISALLOW_COPY_AND_ASSIGN(CodeBreakIterator);
};
202

203 204 205 206 207
class BytecodeArrayBreakIterator : public BreakIterator {
 public:
  BytecodeArrayBreakIterator(Handle<DebugInfo> debug_info,
                             BreakLocatorType type);
  ~BytecodeArrayBreakIterator() override {}
208

209 210 211
  BreakLocation GetBreakLocation() override;
  bool Done() const override { return source_position_iterator_.done(); }
  void Next() override;
212

213 214 215
  bool IsDebugBreak() override;
  void ClearDebugBreak() override;
  void SetDebugBreak() override;
216

217
  void SkipToPosition(int position, BreakPositionAlignment alignment);
218

219
  int code_offset() override { return source_position_iterator_.code_offset(); }
220

221 222
 private:
  DebugBreakType GetDebugBreakType();
223

224 225 226
  SourcePositionTableIterator source_position_iterator_;
  DISALLOW_COPY_AND_ASSIGN(BytecodeArrayBreakIterator);
};
227 228 229 230 231 232

// Linked list holding debug info objects. The debug info objects are kept as
// weak handles to avoid a debug info object to keep a function alive.
class DebugInfoListNode {
 public:
  explicit DebugInfoListNode(DebugInfo* debug_info);
233
  ~DebugInfoListNode();
234 235 236

  DebugInfoListNode* next() { return next_; }
  void set_next(DebugInfoListNode* next) { next_ = next; }
dcarney's avatar
dcarney committed
237 238
  Handle<DebugInfo> debug_info() { return Handle<DebugInfo>(debug_info_); }

239 240
 private:
  // Global (weak) handle to the debug info object.
dcarney's avatar
dcarney committed
241
  DebugInfo** debug_info_;
242 243 244 245 246

  // Next pointer for linked list.
  DebugInfoListNode* next_;
};

247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
// Message delivered to the message handler callback. This is either a debugger
// event or the response to a command.
class MessageImpl : public v8::Debug::Message {
 public:
  // Create a message object for a debug event.
  static MessageImpl NewEvent(DebugEvent event, bool running,
                              Handle<JSObject> exec_state,
                              Handle<JSObject> event_data);

  // Create a message object for the response to a debug command.
  static MessageImpl NewResponse(DebugEvent event, bool running,
                                 Handle<JSObject> exec_state,
                                 Handle<JSObject> event_data,
                                 Handle<String> response_json,
                                 v8::Debug::ClientData* client_data);

  // Implementation of interface v8::Debug::Message.
  virtual bool IsEvent() const;
  virtual bool IsResponse() const;
  virtual DebugEvent GetEvent() const;
  virtual bool WillStartRunning() const;
  virtual v8::Local<v8::Object> GetExecutionState() const;
  virtual v8::Local<v8::Object> GetEventData() const;
  virtual v8::Local<v8::String> GetJSON() const;
  virtual v8::Local<v8::Context> GetEventContext() const;
  virtual v8::Debug::ClientData* GetClientData() const;
  virtual v8::Isolate* GetIsolate() const;

 private:
  MessageImpl(bool is_event, DebugEvent event, bool running,
              Handle<JSObject> exec_state, Handle<JSObject> event_data,
              Handle<String> response_json, v8::Debug::ClientData* client_data);

  bool is_event_;                 // Does this message represent a debug event?
  DebugEvent event_;              // Debug event causing the break.
  bool running_;                  // Will the VM start running after this event?
  Handle<JSObject> exec_state_;   // Current execution state.
  Handle<JSObject> event_data_;   // Data associated with the event.
  Handle<String> response_json_;  // Response JSON if message holds a response.
  v8::Debug::ClientData* client_data_;  // Client data passed with the request.
};

289
// Details of the debug event delivered to the debug event listener.
290
class EventDetailsImpl : public v8::Debug::EventDetails {
291
 public:
292 293 294 295 296
  EventDetailsImpl(DebugEvent event,
                   Handle<JSObject> exec_state,
                   Handle<JSObject> event_data,
                   Handle<Object> callback_data,
                   v8::Debug::ClientData* client_data);
297
  virtual DebugEvent GetEvent() const;
298 299 300 301
  virtual v8::Local<v8::Object> GetExecutionState() const;
  virtual v8::Local<v8::Object> GetEventData() const;
  virtual v8::Local<v8::Context> GetEventContext() const;
  virtual v8::Local<v8::Value> GetCallbackData() const;
302
  virtual v8::Debug::ClientData* GetClientData() const;
303 304
  virtual v8::Isolate* GetIsolate() const;

305 306 307 308 309 310
 private:
  DebugEvent event_;  // Debug event causing the break.
  Handle<JSObject> exec_state_;         // Current execution state.
  Handle<JSObject> event_data_;         // Data associated with the event.
  Handle<Object> callback_data_;        // User data passed with the callback
                                        // when it was registered.
311
  v8::Debug::ClientData* client_data_;  // Data passed to DebugBreakForCommand.
312 313
};

314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374
// Message send by user to v8 debugger or debugger output message.
// In addition to command text it may contain a pointer to some user data
// which are expected to be passed along with the command reponse to message
// handler.
class CommandMessage {
 public:
  static CommandMessage New(const Vector<uint16_t>& command,
                            v8::Debug::ClientData* data);
  CommandMessage();

  // Deletes user data and disposes of the text.
  void Dispose();
  Vector<uint16_t> text() const { return text_; }
  v8::Debug::ClientData* client_data() const { return client_data_; }

 private:
  CommandMessage(const Vector<uint16_t>& text, v8::Debug::ClientData* data);

  Vector<uint16_t> text_;
  v8::Debug::ClientData* client_data_;
};

// A Queue of CommandMessage objects.  A thread-safe version is
// LockingCommandMessageQueue, based on this class.
class CommandMessageQueue BASE_EMBEDDED {
 public:
  explicit CommandMessageQueue(int size);
  ~CommandMessageQueue();
  bool IsEmpty() const { return start_ == end_; }
  CommandMessage Get();
  void Put(const CommandMessage& message);
  void Clear() { start_ = end_ = 0; }  // Queue is empty after Clear().

 private:
  // Doubles the size of the message queue, and copies the messages.
  void Expand();

  CommandMessage* messages_;
  int start_;
  int end_;
  int size_;  // The size of the queue buffer.  Queue can hold size-1 messages.
};

// LockingCommandMessageQueue is a thread-safe circular buffer of CommandMessage
// messages.  The message data is not managed by LockingCommandMessageQueue.
// Pointers to the data are passed in and out. Implemented by adding a
// Mutex to CommandMessageQueue.  Includes logging of all puts and gets.
class LockingCommandMessageQueue BASE_EMBEDDED {
 public:
  LockingCommandMessageQueue(Logger* logger, int size);
  bool IsEmpty() const;
  CommandMessage Get();
  void Put(const CommandMessage& message);
  void Clear();

 private:
  Logger* logger_;
  CommandMessageQueue queue_;
  mutable base::Mutex mutex_;
  DISALLOW_COPY_AND_ASSIGN(LockingCommandMessageQueue);
};
375

376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
class DebugFeatureTracker {
 public:
  enum Feature {
    kActive = 1,
    kBreakPoint = 2,
    kStepping = 3,
    kHeapSnapshot = 4,
    kAllocationTracking = 5,
    kProfiler = 6,
    kLiveEdit = 7,
  };

  explicit DebugFeatureTracker(Isolate* isolate)
      : isolate_(isolate), bitfield_(0) {}
  void Track(Feature feature);

 private:
  Isolate* isolate_;
  uint32_t bitfield_;
};


398 399 400 401 402 403 404 405 406
// This class contains the debugger support. The main purpose is to handle
// setting break points in the code.
//
// This class controls the debug info for all functions which currently have
// active breakpoints in them. This debug info is held in the heap root object
// debug_info which is a FixedArray. Each entry in this list is of class
// DebugInfo.
class Debug {
 public:
407
  // Debug event triggers.
408
  void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue);
409

410
  void OnThrow(Handle<Object> exception);
411
  void OnPromiseReject(Handle<Object> promise, Handle<Object> value);
412
  void OnCompileError(Handle<Script> script);
413
  void OnAfterCompile(Handle<Script> script);
414
  void OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id);
415

416
  // API facing.
417
  void SetEventListener(Handle<Object> callback, Handle<Object> data);
418 419 420
  void SetMessageHandler(v8::Debug::MessageHandler handler);
  void EnqueueCommandMessage(Vector<const uint16_t> command,
                             v8::Debug::ClientData* client_data = NULL);
421
  MUST_USE_RESULT MaybeHandle<Object> Call(Handle<Object> fun,
422 423
                                           Handle<Object> data);
  Handle<Context> GetDebugContext();
424
  void HandleDebugBreak();
425
  void ProcessDebugMessages(bool debug_command_only);
426

427
  // Internal logic
428
  bool Load();
429 430
  void Break(JavaScriptFrame* frame);
  void SetAfterBreakTarget(JavaScriptFrame* frame);
431

432 433 434 435
  // Scripts handling.
  Handle<FixedArray> GetLoadedScripts();

  // Break point handling.
436
  bool SetBreakPoint(Handle<JSFunction> function,
437 438
                     Handle<Object> break_point_object,
                     int* source_position);
439 440
  bool SetBreakPointForScript(Handle<Script> script,
                              Handle<Object> break_point_object,
441 442
                              int* source_position,
                              BreakPositionAlignment alignment);
443 444 445
  void ClearBreakPoint(Handle<Object> break_point_object);
  void ChangeBreakOnException(ExceptionBreakType type, bool enable);
  bool IsBreakOnException(ExceptionBreakType type);
446

447 448 449 450 451 452 453
  // The parameter is either a BreakPointInfo object, or a FixedArray of
  // BreakPointInfo objects.
  // Returns an empty handle if no breakpoint is hit, or a FixedArray with all
  // hit breakpoints.
  MaybeHandle<FixedArray> GetHitBreakPointObjects(
      Handle<Object> break_point_objects);

454
  // Stepping handling.
455
  void PrepareStep(StepAction step_action);
456
  void PrepareStepIn(Handle<JSFunction> function);
457
  void PrepareStepInSuspendedGenerator();
458
  void PrepareStepOnThrow();
459
  void ClearStepping();
460
  void ClearStepOut();
461

462
  bool PrepareFunctionForBreakPoints(Handle<SharedFunctionInfo> shared);
463 464
  bool GetPossibleBreakpoints(Handle<Script> script, int start_position,
                              int end_position, std::set<int>* positions);
465

466
  void RecordGenerator(Handle<JSGeneratorObject> generator_object);
467

468 469
  int NextAsyncTaskId(Handle<JSObject> promise);

470
  void SetDebugEventListener(debug::DebugEventListener* listener);
471

472 473 474 475 476
  // Returns whether the operation succeeded. Compilation can only be triggered
  // if a valid closure is passed as the second argument, otherwise the shared
  // function needs to be compiled already.
  bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared,
                       Handle<JSFunction> function);
477
  void CreateDebugInfo(Handle<SharedFunctionInfo> shared);
478
  static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared);
479

480 481 482
  template <typename C>
  bool CompileToRevealInnerFunctions(C* compilable);

483
  // This function is used in FunctionNameUsing* tests.
484 485
  Handle<Object> FindSharedFunctionInfoInScript(Handle<Script> script,
                                                int position);
486

487
  static Handle<Object> GetSourceBreakLocations(
488 489
      Handle<SharedFunctionInfo> shared,
      BreakPositionAlignment position_aligment);
490 491

  // Check whether a global object is the debug global object.
492
  bool IsDebugGlobal(JSGlobalObject* global);
493

494
  // Check whether this frame is just about to return.
495
  bool IsBreakAtReturn(JavaScriptFrame* frame);
496

497
  // Support for LiveEdit
498
  void FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
499
                             LiveEditFrameDropMode mode);
500 501

  // Threading support.
502 503
  char* ArchiveDebug(char* to);
  char* RestoreDebug(char* from);
504
  static int ArchiveSpacePerThread();
505
  void FreeThreadResources() { }
506
  void Iterate(ObjectVisitor* v);
507

508
  bool CheckExecutionState(int id) {
509 510 511 512 513
    return CheckExecutionState() && break_id() == id;
  }

  bool CheckExecutionState() {
    return is_active() && !debug_context().is_null() && break_id() != 0;
514 515
  }

516 517 518
  bool PerformSideEffectCheck(Handle<JSFunction> function);
  bool PerformSideEffectCheckForCallback(Address function);

519
  // Flags and states.
520 521 522 523
  DebugScope* debugger_entry() {
    return reinterpret_cast<DebugScope*>(
        base::NoBarrier_Load(&thread_local_.current_debug_scope_));
  }
524
  inline Handle<Context> debug_context() { return debug_context_; }
525

526 527
  void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; }
  bool live_edit_enabled() const {
528
    return FLAG_enable_liveedit && live_edit_enabled_;
529 530 531 532
  }

  inline bool is_active() const { return is_active_; }
  inline bool is_loaded() const { return !debug_context_.is_null(); }
533
  inline bool in_debug_scope() const {
534
    return !!base::NoBarrier_Load(&thread_local_.current_debug_scope_);
535
  }
536
  void set_break_points_active(bool v) { break_points_active_ = v; }
537
  bool break_points_active() const { return break_points_active_; }
538 539 540 541

  StackFrame::Id break_frame_id() { return thread_local_.break_frame_id_; }
  int break_id() { return thread_local_.break_id_; }

542 543 544 545 546
  Handle<Object> return_value() { return thread_local_.return_value_; }
  void set_return_value(Handle<Object> value) {
    thread_local_.return_value_ = value;
  }

547
  // Support for embedding into generated code.
548 549 550 551
  Address is_active_address() {
    return reinterpret_cast<Address>(&is_active_);
  }

552 553 554 555
  Address hook_on_function_call_address() {
    return reinterpret_cast<Address>(&hook_on_function_call_);
  }

556 557 558 559
  Address after_break_target_address() {
    return reinterpret_cast<Address>(&after_break_target_);
  }

560 561
  Address last_step_action_address() {
    return reinterpret_cast<Address>(&thread_local_.last_step_action_);
562 563
  }

564 565 566 567
  Address suspended_generator_address() {
    return reinterpret_cast<Address>(&thread_local_.suspended_generator_);
  }

568 569
  StepAction last_step_action() { return thread_local_.last_step_action_; }

570 571
  DebugFeatureTracker* feature_tracker() { return &feature_tracker_; }

572
 private:
573 574
  explicit Debug(Isolate* isolate);

575
  void UpdateState();
576
  void UpdateHookOnFunctionCall();
577 578 579 580 581
  void Unload();
  void SetNextBreakId() {
    thread_local_.break_id_ = ++thread_local_.break_count_;
  }

582 583
  // Check whether there are commands in the command queue.
  inline bool has_commands() const { return !command_queue_.IsEmpty(); }
584 585 586
  inline bool ignore_events() const {
    return is_suppressed_ || !is_active_ || isolate_->needs_side_effect_check();
  }
587 588 589
  inline bool break_disabled() const {
    return break_disabled_ || in_debug_event_listener_;
  }
590

591
  void clear_suspended_generator() {
592
    thread_local_.suspended_generator_ = Smi::kZero;
593 594 595
  }

  bool has_suspended_generator() const {
596
    return thread_local_.suspended_generator_ != Smi::kZero;
597 598
  }

599 600 601 602 603 604 605 606
  // There are three types of event listeners: C++ message_handler,
  // JavaScript event listener and C++ event listener.
  // Currently inspector still uses C++ event listener and installs
  // more specific event listeners for part of events. Calling of
  // C++ event listener is redundant when more specific event listener
  // is presented. Other clients can install JavaScript event listener
  // (e.g. some of NodeJS module).
  bool non_inspector_listener_exists() const {
607 608
    return message_handler_ != nullptr ||
           (!event_listener_.is_null() && !event_listener_->IsForeign());
609 610
  }

611
  void OnException(Handle<Object> exception, Handle<Object> promise);
612

613
  // Constructors for debug event objects.
614 615 616 617 618 619 620 621
  MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState();
  MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent(
      Handle<Object> break_points_hit);
  MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent(
      Handle<Object> exception,
      bool uncaught,
      Handle<Object> promise);
  MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent(
622
      Handle<Script> script, v8::DebugEvent type);
623
  MUST_USE_RESULT MaybeHandle<Object> MakeAsyncTaskEvent(Handle<Smi> type,
624
                                                         Handle<Smi> id);
625

626 627 628
  // Mirror cache handling.
  void ClearMirrorCache();

629 630 631 632
  void CallEventCallback(v8::DebugEvent event,
                         Handle<Object> exec_state,
                         Handle<Object> event_data,
                         v8::Debug::ClientData* client_data);
633
  void ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script);
634 635 636 637 638
  void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data,
                         bool auto_continue);
  void NotifyMessageHandler(v8::DebugEvent event, Handle<JSObject> exec_state,
                            Handle<JSObject> event_data, bool auto_continue);
  void InvokeMessageHandler(MessageImpl message);
639

640 641 642 643 644 645 646 647 648 649 650 651 652
  // Find the closest source position for a break point for a given position.
  int FindBreakablePosition(Handle<DebugInfo> debug_info, int source_position,
                            BreakPositionAlignment alignment);
  // Instrument code to break at break points.
  void ApplyBreakPoints(Handle<DebugInfo> debug_info);
  // Clear code from instrumentation.
  void ClearBreakPoints(Handle<DebugInfo> debug_info);
  // Clear all code from instrumentation.
  void ClearAllBreakPoints();
  // Instrument a function with one-shots.
  void FloodWithOneShot(Handle<JSFunction> function,
                        BreakLocatorType type = ALL_BREAK_LOCATIONS);
  // Clear all one-shot instrumentations, but restore break points.
653
  void ClearOneShot();
654

655
  void ActivateStepOut(StackFrame* frame);
656
  void RemoveDebugInfoAndClearFromShared(Handle<DebugInfo> debug_info);
657 658 659
  MaybeHandle<FixedArray> CheckBreakPoints(Handle<DebugInfo> debug_info,
                                           BreakLocation* location,
                                           bool* has_break_points = nullptr);
660
  bool IsMutedAtCurrentLocation(JavaScriptFrame* frame);
661
  bool CheckBreakPoint(Handle<Object> break_point_object);
662 663
  MaybeHandle<Object> CallFunction(const char* name, int argc,
                                   Handle<Object> args[]);
664

665
  inline void AssertDebugContext() {
666 667
    DCHECK(isolate_->context() == *debug_context());
    DCHECK(in_debug_scope());
668 669
  }

670
  void ThreadInit();
671

672 673
  void PrintBreakLocation();

674 675 676 677 678
  // Global handles.
  Handle<Context> debug_context_;
  Handle<Object> event_listener_;
  Handle<Object> event_listener_data_;

679 680
  v8::Debug::MessageHandler message_handler_;

681
  debug::DebugEventListener* debug_event_listener_ = nullptr;
682

683 684 685 686
  static const int kQueueInitialSize = 4;
  base::Semaphore command_received_;  // Signaled for each command received.
  LockingCommandMessageQueue command_queue_;

687
  // Debugger is active, i.e. there is a debug event listener attached.
688
  bool is_active_;
689 690 691 692
  // Debugger needs to be notified on every new function call.
  // Used for stepping and read-only checks
  bool hook_on_function_call_;
  // Suppress debug events.
693
  bool is_suppressed_;
694
  // LiveEdit is enabled.
695
  bool live_edit_enabled_;
696
  // Do not trigger debug break events.
697
  bool break_disabled_;
698
  // Do not break on break points.
699
  bool break_points_active_;
700
  // Nested inside a debug event listener.
701
  bool in_debug_event_listener_;
702
  // Trigger debug break events for all exceptions.
703
  bool break_on_exception_;
704
  // Trigger debug break events for uncaught exceptions.
705
  bool break_on_uncaught_exception_;
706 707
  // Termination exception because side effect check has failed.
  bool side_effect_check_failed_;
708

709 710
  // List of active debug info objects.
  DebugInfoListNode* debug_info_list_;
711

712 713 714 715 716
  // Storage location for jump when exiting debug break calls.
  // Note that this address is not GC safe.  It should be computed immediately
  // before returning to the DebugBreakCallHelper.
  Address after_break_target_;

717 718 719
  // Used to collect histogram data on debugger feature usage.
  DebugFeatureTracker feature_tracker_;

720
  // Per-thread data.
721 722
  class ThreadLocal {
   public:
723
    // Top debugger entry.
724
    base::AtomicWord current_debug_scope_;
725

726 727 728 729 730 731 732 733 734
    // Counter for generating next break id.
    int break_count_;

    // Current break id.
    int break_id_;

    // Frame id for the frame of the current break.
    StackFrame::Id break_frame_id_;

735 736 737 738 739 740
    // Step action for last step performed.
    StepAction last_step_action_;

    // Source statement position from last step next action.
    int last_statement_position_;

741
    // Frame pointer from last step next or step frame action.
742 743
    Address last_fp_;

744 745
    // Frame pointer of the target frame we want to arrive at.
    Address target_fp_;
746

747 748
    // Stores the way how LiveEdit has patched the stack. It is used when
    // debugger returns control back to user script.
749
    LiveEditFrameDropMode frame_drop_mode_;
750 751 752 753

    // Value of accumulator in interpreter frames. In non-interpreter frames
    // this value will be the hole.
    Handle<Object> return_value_;
754 755

    Object* suspended_generator_;
756 757

    int async_task_count_;
758 759 760
  };

  // Storage location for registers when handling debug break calls
761
  ThreadLocal thread_local_;
762

763 764 765
  Isolate* isolate_;

  friend class Isolate;
766
  friend class DebugScope;
767
  friend class DisableBreak;
768
  friend class LiveEdit;
769
  friend class SuppressDebug;
770
  friend class NoSideEffectScope;
771

772 773 774
  friend Handle<FixedArray> GetDebuggedFunctions();  // In test-debug.cc
  friend void CheckDebuggerUnloaded(bool check_functions);  // In test-debug.cc

775
  DISALLOW_COPY_AND_ASSIGN(Debug);
776 777 778
};


779 780 781 782
// This scope is used to load and enter the debug context and create a new
// break state.  Leaving the scope will restore the previous state.
// On failure to load, FailedToEnter returns true.
class DebugScope BASE_EMBEDDED {
783
 public:
784 785
  explicit DebugScope(Debug* debug);
  ~DebugScope();
786

787 788
  // Check whether loading was successful.
  inline bool failed() { return failed_; }
789

790 791 792
  // Get the active context from before entering the debugger.
  inline Handle<Context> GetContext() { return save_.context(); }

793
 private:
794 795 796 797
  Isolate* isolate() { return debug_->isolate_; }

  Debug* debug_;
  DebugScope* prev_;               // Previous scope if entered recursively.
798
  StackFrame::Id break_frame_id_;  // Previous break frame id.
799
  int break_id_;                   // Previous break id.
800
  Handle<Object> return_value_;    // Previous result.
801 802
  bool failed_;                    // Did the debug context fail to load?
  SaveContext save_;               // Saves previous context.
803
  PostponeInterruptsScope no_termination_exceptons_;
804 805 806
};


807 808 809
// Stack allocated class for disabling break.
class DisableBreak BASE_EMBEDDED {
 public:
810
  explicit DisableBreak(Debug* debug)
811 812 813
      : debug_(debug),
        previous_break_disabled_(debug->break_disabled_),
        previous_in_debug_event_listener_(debug->in_debug_event_listener_) {
814 815
    debug_->break_disabled_ = true;
    debug_->in_debug_event_listener_ = true;
816 817 818 819
  }
  ~DisableBreak() {
    debug_->break_disabled_ = previous_break_disabled_;
    debug_->in_debug_event_listener_ = previous_in_debug_event_listener_;
820
  }
821 822 823

 private:
  Debug* debug_;
824 825
  bool previous_break_disabled_;
  bool previous_in_debug_event_listener_;
826 827 828 829 830 831 832 833 834
  DISALLOW_COPY_AND_ASSIGN(DisableBreak);
};


class SuppressDebug BASE_EMBEDDED {
 public:
  explicit SuppressDebug(Debug* debug)
      : debug_(debug), old_state_(debug->is_suppressed_) {
    debug_->is_suppressed_ = true;
835
  }
836
  ~SuppressDebug() { debug_->is_suppressed_ = old_state_; }
837 838

 private:
839 840 841
  Debug* debug_;
  bool old_state_;
  DISALLOW_COPY_AND_ASSIGN(SuppressDebug);
842 843
};

844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860
class NoSideEffectScope {
 public:
  NoSideEffectScope(Isolate* isolate, bool disallow_side_effects)
      : isolate_(isolate),
        old_needs_side_effect_check_(isolate->needs_side_effect_check()) {
    isolate->set_needs_side_effect_check(old_needs_side_effect_check_ ||
                                         disallow_side_effects);
    isolate->debug()->UpdateHookOnFunctionCall();
    isolate->debug()->side_effect_check_failed_ = false;
  }
  ~NoSideEffectScope();

 private:
  Isolate* isolate_;
  bool old_needs_side_effect_check_;
  DISALLOW_COPY_AND_ASSIGN(NoSideEffectScope);
};
861 862 863 864

// Code generator routines.
class DebugCodegen : public AllStatic {
 public:
865 866 867
  enum DebugBreakCallHelperMode {
    SAVE_RESULT_REGISTER,
    IGNORE_RESULT_REGISTER
868 869
  };

870 871 872
  static void GenerateDebugBreakStub(MacroAssembler* masm,
                                     DebugBreakCallHelperMode mode);

873 874 875 876 877
  // FrameDropper is a code replacement for a JavaScript frame with possibly
  // several frames above.
  // There is no calling conventions here, because it never actually gets
  // called, it only gets returned to.
  static void GenerateFrameDropperLiveEdit(MacroAssembler* masm);
878

879

880
  static void GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode);
881

882 883
  static void PatchDebugBreakSlot(Isolate* isolate, Address pc,
                                  Handle<Code> code);
884
  static bool DebugBreakSlotIsPatched(Address pc);
885
  static void ClearDebugBreakSlot(Isolate* isolate, Address pc);
886 887
};

888

889 890
}  // namespace internal
}  // namespace v8
891

892
#endif  // V8_DEBUG_DEBUG_H_