1// Copyright 2012 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/debug/debug.h"
6
7#include <memory>
8
9#include "src/api.h"
10#include "src/arguments.h"
11#include "src/bootstrapper.h"
12#include "src/code-stubs.h"
13#include "src/codegen.h"
14#include "src/compilation-cache.h"
15#include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
16#include "src/compiler.h"
17#include "src/debug/liveedit.h"
18#include "src/deoptimizer.h"
19#include "src/execution.h"
20#include "src/frames-inl.h"
21#include "src/full-codegen/full-codegen.h"
22#include "src/global-handles.h"
23#include "src/globals.h"
24#include "src/interpreter/interpreter.h"
25#include "src/isolate-inl.h"
26#include "src/list.h"
27#include "src/log.h"
28#include "src/messages.h"
29#include "src/snapshot/natives.h"
30#include "src/wasm/wasm-module.h"
31
32#include "include/v8-debug.h"
33
34namespace v8 {
35namespace internal {
36
37Debug::Debug(Isolate* isolate)
38    : debug_context_(Handle<Context>()),
39      event_listener_(Handle<Object>()),
40      event_listener_data_(Handle<Object>()),
41      message_handler_(NULL),
42      command_received_(0),
43      command_queue_(isolate->logger(), kQueueInitialSize),
44      is_active_(false),
45      is_suppressed_(false),
46      live_edit_enabled_(true),  // TODO(yangguo): set to false by default.
47      break_disabled_(false),
48      break_points_active_(true),
49      in_debug_event_listener_(false),
50      break_on_exception_(false),
51      break_on_uncaught_exception_(false),
52      debug_info_list_(NULL),
53      feature_tracker_(isolate),
54      isolate_(isolate) {
55  ThreadInit();
56}
57
58BreakLocation BreakLocation::FromFrame(Handle<DebugInfo> debug_info,
59                                       JavaScriptFrame* frame) {
60  FrameSummary summary = FrameSummary::GetFirst(frame);
61  int offset = summary.code_offset();
62  Handle<AbstractCode> abstract_code = summary.abstract_code();
63  if (abstract_code->IsCode()) offset = offset - 1;
64  auto it = BreakIterator::GetIterator(debug_info, abstract_code);
65  it->SkipTo(BreakIndexFromCodeOffset(debug_info, abstract_code, offset));
66  return it->GetBreakLocation();
67}
68
69void BreakLocation::AllAtCurrentStatement(Handle<DebugInfo> debug_info,
70                                          JavaScriptFrame* frame,
71                                          List<BreakLocation>* result_out) {
72  FrameSummary summary = FrameSummary::GetFirst(frame);
73  int offset = summary.code_offset();
74  Handle<AbstractCode> abstract_code = summary.abstract_code();
75  if (abstract_code->IsCode()) offset = offset - 1;
76  int statement_position;
77  {
78    auto it = BreakIterator::GetIterator(debug_info, abstract_code);
79    it->SkipTo(BreakIndexFromCodeOffset(debug_info, abstract_code, offset));
80    statement_position = it->statement_position();
81  }
82  for (auto it = BreakIterator::GetIterator(debug_info, abstract_code);
83       !it->Done(); it->Next()) {
84    if (it->statement_position() == statement_position) {
85      result_out->Add(it->GetBreakLocation());
86    }
87  }
88}
89
90int BreakLocation::BreakIndexFromCodeOffset(Handle<DebugInfo> debug_info,
91                                            Handle<AbstractCode> abstract_code,
92                                            int offset) {
93  // Run through all break points to locate the one closest to the address.
94  int closest_break = 0;
95  int distance = kMaxInt;
96  DCHECK(0 <= offset && offset < abstract_code->Size());
97  for (auto it = BreakIterator::GetIterator(debug_info, abstract_code);
98       !it->Done(); it->Next()) {
99    // Check if this break point is closer that what was previously found.
100    if (it->code_offset() <= offset && offset - it->code_offset() < distance) {
101      closest_break = it->break_index();
102      distance = offset - it->code_offset();
103      // Check whether we can't get any closer.
104      if (distance == 0) break;
105    }
106  }
107  return closest_break;
108}
109
110bool BreakLocation::HasBreakPoint(Handle<DebugInfo> debug_info) const {
111  // First check whether there is a break point with the same source position.
112  if (!debug_info->HasBreakPoint(position_)) return false;
113  // Then check whether a break point at that source position would have
114  // the same code offset. Otherwise it's just a break location that we can
115  // step to, but not actually a location where we can put a break point.
116  if (abstract_code_->IsCode()) {
117    DCHECK_EQ(debug_info->DebugCode(), abstract_code_->GetCode());
118    CodeBreakIterator it(debug_info, ALL_BREAK_LOCATIONS);
119    it.SkipToPosition(position_, BREAK_POSITION_ALIGNED);
120    return it.code_offset() == code_offset_;
121  } else {
122    DCHECK(abstract_code_->IsBytecodeArray());
123    BytecodeArrayBreakIterator it(debug_info, ALL_BREAK_LOCATIONS);
124    it.SkipToPosition(position_, BREAK_POSITION_ALIGNED);
125    return it.code_offset() == code_offset_;
126  }
127}
128
129std::unique_ptr<BreakIterator> BreakIterator::GetIterator(
130    Handle<DebugInfo> debug_info, Handle<AbstractCode> abstract_code,
131    BreakLocatorType type) {
132  if (abstract_code->IsBytecodeArray()) {
133    DCHECK(debug_info->HasDebugBytecodeArray());
134    return std::unique_ptr<BreakIterator>(
135        new BytecodeArrayBreakIterator(debug_info, type));
136  } else {
137    DCHECK(abstract_code->IsCode());
138    DCHECK(debug_info->HasDebugCode());
139    return std::unique_ptr<BreakIterator>(
140        new CodeBreakIterator(debug_info, type));
141  }
142}
143
144BreakIterator::BreakIterator(Handle<DebugInfo> debug_info,
145                             BreakLocatorType type)
146    : debug_info_(debug_info), break_index_(-1), break_locator_type_(type) {
147  position_ = debug_info->shared()->start_position();
148  statement_position_ = position_;
149}
150
151int BreakIterator::BreakIndexFromPosition(int source_position,
152                                          BreakPositionAlignment alignment) {
153  int distance = kMaxInt;
154  int closest_break = break_index();
155  while (!Done()) {
156    int next_position;
157    if (alignment == STATEMENT_ALIGNED) {
158      next_position = statement_position();
159    } else {
160      DCHECK(alignment == BREAK_POSITION_ALIGNED);
161      next_position = position();
162    }
163    if (source_position <= next_position &&
164        next_position - source_position < distance) {
165      closest_break = break_index();
166      distance = next_position - source_position;
167      // Check whether we can't get any closer.
168      if (distance == 0) break;
169    }
170    Next();
171  }
172  return closest_break;
173}
174
175CodeBreakIterator::CodeBreakIterator(Handle<DebugInfo> debug_info,
176                                     BreakLocatorType type)
177    : BreakIterator(debug_info, type),
178      reloc_iterator_(debug_info->DebugCode(), GetModeMask(type)),
179      source_position_iterator_(
180          debug_info->DebugCode()->source_position_table()) {
181  // There is at least one break location.
182  DCHECK(!Done());
183  Next();
184}
185
186int CodeBreakIterator::GetModeMask(BreakLocatorType type) {
187  int mask = 0;
188  mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_RETURN);
189  mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_CALL);
190  if (isolate()->is_tail_call_elimination_enabled()) {
191    mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_TAIL_CALL);
192  }
193  if (type == ALL_BREAK_LOCATIONS) {
194    mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION);
195    mask |= RelocInfo::ModeMask(RelocInfo::DEBUGGER_STATEMENT);
196  }
197  return mask;
198}
199
200void CodeBreakIterator::Next() {
201  DisallowHeapAllocation no_gc;
202  DCHECK(!Done());
203
204  // Iterate through reloc info stopping at each breakable code target.
205  bool first = break_index_ == -1;
206
207  if (!first) reloc_iterator_.next();
208  first = false;
209  if (Done()) return;
210
211  int offset = code_offset();
212  while (!source_position_iterator_.done() &&
213         source_position_iterator_.code_offset() <= offset) {
214    position_ = source_position_iterator_.source_position().ScriptOffset();
215    if (source_position_iterator_.is_statement()) {
216      statement_position_ = position_;
217    }
218    source_position_iterator_.Advance();
219  }
220
221  DCHECK(RelocInfo::IsDebugBreakSlot(rmode()) ||
222         RelocInfo::IsDebuggerStatement(rmode()));
223  break_index_++;
224}
225
226DebugBreakType CodeBreakIterator::GetDebugBreakType() {
227  if (RelocInfo::IsDebugBreakSlotAtReturn(rmode())) {
228    return DEBUG_BREAK_SLOT_AT_RETURN;
229  } else if (RelocInfo::IsDebugBreakSlotAtCall(rmode())) {
230    return DEBUG_BREAK_SLOT_AT_CALL;
231  } else if (RelocInfo::IsDebugBreakSlotAtTailCall(rmode())) {
232    return isolate()->is_tail_call_elimination_enabled()
233               ? DEBUG_BREAK_SLOT_AT_TAIL_CALL
234               : DEBUG_BREAK_SLOT_AT_CALL;
235  } else if (RelocInfo::IsDebuggerStatement(rmode())) {
236    return DEBUGGER_STATEMENT;
237  } else if (RelocInfo::IsDebugBreakSlot(rmode())) {
238    return DEBUG_BREAK_SLOT;
239  } else {
240    return NOT_DEBUG_BREAK;
241  }
242}
243
244void CodeBreakIterator::SkipToPosition(int position,
245                                       BreakPositionAlignment alignment) {
246  CodeBreakIterator it(debug_info_, break_locator_type_);
247  SkipTo(it.BreakIndexFromPosition(position, alignment));
248}
249
250void CodeBreakIterator::SetDebugBreak() {
251  DebugBreakType debug_break_type = GetDebugBreakType();
252  if (debug_break_type == DEBUGGER_STATEMENT) return;
253  DCHECK(debug_break_type >= DEBUG_BREAK_SLOT);
254  Builtins* builtins = isolate()->builtins();
255  Handle<Code> target = debug_break_type == DEBUG_BREAK_SLOT_AT_RETURN
256                            ? builtins->Return_DebugBreak()
257                            : builtins->Slot_DebugBreak();
258  DebugCodegen::PatchDebugBreakSlot(isolate(), rinfo()->pc(), target);
259}
260
261void CodeBreakIterator::ClearDebugBreak() {
262  DebugBreakType debug_break_type = GetDebugBreakType();
263  if (debug_break_type == DEBUGGER_STATEMENT) return;
264  DCHECK(debug_break_type >= DEBUG_BREAK_SLOT);
265  DebugCodegen::ClearDebugBreakSlot(isolate(), rinfo()->pc());
266}
267
268bool CodeBreakIterator::IsDebugBreak() {
269  DebugBreakType debug_break_type = GetDebugBreakType();
270  if (debug_break_type == DEBUGGER_STATEMENT) return false;
271  DCHECK(debug_break_type >= DEBUG_BREAK_SLOT);
272  return DebugCodegen::DebugBreakSlotIsPatched(rinfo()->pc());
273}
274
275BreakLocation CodeBreakIterator::GetBreakLocation() {
276  Handle<AbstractCode> code(AbstractCode::cast(debug_info_->DebugCode()));
277  return BreakLocation(code, GetDebugBreakType(), code_offset(), position_);
278}
279
280BytecodeArrayBreakIterator::BytecodeArrayBreakIterator(
281    Handle<DebugInfo> debug_info, BreakLocatorType type)
282    : BreakIterator(debug_info, type),
283      source_position_iterator_(
284          debug_info->DebugBytecodeArray()->source_position_table()) {
285  // There is at least one break location.
286  DCHECK(!Done());
287  Next();
288}
289
290void BytecodeArrayBreakIterator::Next() {
291  DisallowHeapAllocation no_gc;
292  DCHECK(!Done());
293  bool first = break_index_ == -1;
294  while (!Done()) {
295    if (!first) source_position_iterator_.Advance();
296    first = false;
297    if (Done()) return;
298    position_ = source_position_iterator_.source_position().ScriptOffset();
299    if (source_position_iterator_.is_statement()) {
300      statement_position_ = position_;
301    }
302    DCHECK(position_ >= 0);
303    DCHECK(statement_position_ >= 0);
304
305    DebugBreakType type = GetDebugBreakType();
306    if (type == NOT_DEBUG_BREAK) continue;
307
308    if (break_locator_type_ == ALL_BREAK_LOCATIONS) break;
309
310    DCHECK_EQ(CALLS_AND_RETURNS, break_locator_type_);
311    if (type == DEBUG_BREAK_SLOT_AT_CALL) break;
312    if (type == DEBUG_BREAK_SLOT_AT_RETURN) break;
313  }
314  break_index_++;
315}
316
317DebugBreakType BytecodeArrayBreakIterator::GetDebugBreakType() {
318  BytecodeArray* bytecode_array = debug_info_->OriginalBytecodeArray();
319  interpreter::Bytecode bytecode =
320      interpreter::Bytecodes::FromByte(bytecode_array->get(code_offset()));
321
322  if (bytecode == interpreter::Bytecode::kDebugger) {
323    return DEBUGGER_STATEMENT;
324  } else if (bytecode == interpreter::Bytecode::kReturn) {
325    return DEBUG_BREAK_SLOT_AT_RETURN;
326  } else if (bytecode == interpreter::Bytecode::kTailCall) {
327    return isolate()->is_tail_call_elimination_enabled()
328               ? DEBUG_BREAK_SLOT_AT_TAIL_CALL
329               : DEBUG_BREAK_SLOT_AT_CALL;
330  } else if (interpreter::Bytecodes::IsCallOrNew(bytecode)) {
331    return DEBUG_BREAK_SLOT_AT_CALL;
332  } else if (source_position_iterator_.is_statement()) {
333    return DEBUG_BREAK_SLOT;
334  } else {
335    return NOT_DEBUG_BREAK;
336  }
337}
338
339void BytecodeArrayBreakIterator::SkipToPosition(
340    int position, BreakPositionAlignment alignment) {
341  BytecodeArrayBreakIterator it(debug_info_, break_locator_type_);
342  SkipTo(it.BreakIndexFromPosition(position, alignment));
343}
344
345void BytecodeArrayBreakIterator::SetDebugBreak() {
346  DebugBreakType debug_break_type = GetDebugBreakType();
347  if (debug_break_type == DEBUGGER_STATEMENT) return;
348  DCHECK(debug_break_type >= DEBUG_BREAK_SLOT);
349  BytecodeArray* bytecode_array = debug_info_->DebugBytecodeArray();
350  interpreter::Bytecode bytecode =
351      interpreter::Bytecodes::FromByte(bytecode_array->get(code_offset()));
352  if (interpreter::Bytecodes::IsDebugBreak(bytecode)) return;
353  interpreter::Bytecode debugbreak =
354      interpreter::Bytecodes::GetDebugBreak(bytecode);
355  bytecode_array->set(code_offset(),
356                      interpreter::Bytecodes::ToByte(debugbreak));
357}
358
359void BytecodeArrayBreakIterator::ClearDebugBreak() {
360  DebugBreakType debug_break_type = GetDebugBreakType();
361  if (debug_break_type == DEBUGGER_STATEMENT) return;
362  DCHECK(debug_break_type >= DEBUG_BREAK_SLOT);
363  BytecodeArray* bytecode_array = debug_info_->DebugBytecodeArray();
364  BytecodeArray* original = debug_info_->OriginalBytecodeArray();
365  bytecode_array->set(code_offset(), original->get(code_offset()));
366}
367
368bool BytecodeArrayBreakIterator::IsDebugBreak() {
369  DebugBreakType debug_break_type = GetDebugBreakType();
370  if (debug_break_type == DEBUGGER_STATEMENT) return false;
371  DCHECK(debug_break_type >= DEBUG_BREAK_SLOT);
372  BytecodeArray* bytecode_array = debug_info_->DebugBytecodeArray();
373  interpreter::Bytecode bytecode =
374      interpreter::Bytecodes::FromByte(bytecode_array->get(code_offset()));
375  return interpreter::Bytecodes::IsDebugBreak(bytecode);
376}
377
378BreakLocation BytecodeArrayBreakIterator::GetBreakLocation() {
379  Handle<AbstractCode> code(
380      AbstractCode::cast(debug_info_->DebugBytecodeArray()));
381  return BreakLocation(code, GetDebugBreakType(), code_offset(), position_);
382}
383
384
385void DebugFeatureTracker::Track(DebugFeatureTracker::Feature feature) {
386  uint32_t mask = 1 << feature;
387  // Only count one sample per feature and isolate.
388  if (bitfield_ & mask) return;
389  isolate_->counters()->debug_feature_usage()->AddSample(feature);
390  bitfield_ |= mask;
391}
392
393
394// Threading support.
395void Debug::ThreadInit() {
396  thread_local_.break_count_ = 0;
397  thread_local_.break_id_ = 0;
398  thread_local_.break_frame_id_ = StackFrame::NO_ID;
399  thread_local_.last_step_action_ = StepNone;
400  thread_local_.last_statement_position_ = kNoSourcePosition;
401  thread_local_.last_fp_ = 0;
402  thread_local_.target_fp_ = 0;
403  thread_local_.return_value_ = Handle<Object>();
404  clear_suspended_generator();
405  // TODO(isolates): frames_are_dropped_?
406  base::NoBarrier_Store(&thread_local_.current_debug_scope_,
407                        static_cast<base::AtomicWord>(0));
408}
409
410
411char* Debug::ArchiveDebug(char* storage) {
412  // Simply reset state. Don't archive anything.
413  ThreadInit();
414  return storage + ArchiveSpacePerThread();
415}
416
417
418char* Debug::RestoreDebug(char* storage) {
419  // Simply reset state. Don't restore anything.
420  ThreadInit();
421  return storage + ArchiveSpacePerThread();
422}
423
424int Debug::ArchiveSpacePerThread() { return 0; }
425
426void Debug::Iterate(ObjectVisitor* v) {
427  v->VisitPointer(&thread_local_.suspended_generator_);
428}
429
430DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) {
431  // Globalize the request debug info object and make it weak.
432  GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles();
433  debug_info_ =
434      Handle<DebugInfo>::cast(global_handles->Create(debug_info)).location();
435}
436
437
438DebugInfoListNode::~DebugInfoListNode() {
439  if (debug_info_ == nullptr) return;
440  GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_info_));
441  debug_info_ = nullptr;
442}
443
444
445bool Debug::Load() {
446  // Return if debugger is already loaded.
447  if (is_loaded()) return true;
448
449  // Bail out if we're already in the process of compiling the native
450  // JavaScript source code for the debugger.
451  if (is_suppressed_) return false;
452  SuppressDebug while_loading(this);
453
454  // Disable breakpoints and interrupts while compiling and running the
455  // debugger scripts including the context creation code.
456  DisableBreak disable(this, true);
457  PostponeInterruptsScope postpone(isolate_);
458
459  // Create the debugger context.
460  HandleScope scope(isolate_);
461  ExtensionConfiguration no_extensions;
462  // TODO(yangguo): we rely on the fact that first context snapshot is usable
463  //                as debug context. This dependency is gone once we remove
464  //                debug context completely.
465  static const int kFirstContextSnapshotIndex = 0;
466  Handle<Context> context = isolate_->bootstrapper()->CreateEnvironment(
467      MaybeHandle<JSGlobalProxy>(), v8::Local<ObjectTemplate>(), &no_extensions,
468      kFirstContextSnapshotIndex, DEBUG_CONTEXT);
469
470  // Fail if no context could be created.
471  if (context.is_null()) return false;
472
473  debug_context_ = Handle<Context>::cast(
474      isolate_->global_handles()->Create(*context));
475
476  feature_tracker()->Track(DebugFeatureTracker::kActive);
477
478  return true;
479}
480
481
482void Debug::Unload() {
483  ClearAllBreakPoints();
484  ClearStepping();
485
486  // Return debugger is not loaded.
487  if (!is_loaded()) return;
488
489  // Clear debugger context global handle.
490  GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location());
491  debug_context_ = Handle<Context>();
492}
493
494void Debug::Break(JavaScriptFrame* frame) {
495  HandleScope scope(isolate_);
496
497  // Initialize LiveEdit.
498  LiveEdit::InitializeThreadLocal(this);
499
500  // Just continue if breaks are disabled or debugger cannot be loaded.
501  if (break_disabled()) return;
502
503  // Enter the debugger.
504  DebugScope debug_scope(this);
505  if (debug_scope.failed()) return;
506
507  // Postpone interrupt during breakpoint processing.
508  PostponeInterruptsScope postpone(isolate_);
509
510  // Get the debug info (create it if it does not exist).
511  Handle<JSFunction> function(frame->function());
512  Handle<SharedFunctionInfo> shared(function->shared());
513  if (!EnsureDebugInfo(shared, function)) {
514    // Return if we failed to retrieve the debug info.
515    return;
516  }
517  Handle<DebugInfo> debug_info(shared->GetDebugInfo(), isolate_);
518
519  // Find the break location where execution has stopped.
520  BreakLocation location = BreakLocation::FromFrame(debug_info, frame);
521
522  // Find actual break points, if any, and trigger debug break event.
523  Handle<Object> break_points_hit = CheckBreakPoints(debug_info, &location);
524  if (!break_points_hit->IsUndefined(isolate_)) {
525    // Clear all current stepping setup.
526    ClearStepping();
527    // Notify the debug event listeners.
528    OnDebugBreak(break_points_hit, false);
529    return;
530  }
531
532  // No break point. Check for stepping.
533  StepAction step_action = last_step_action();
534  Address current_fp = frame->UnpaddedFP();
535  Address target_fp = thread_local_.target_fp_;
536  Address last_fp = thread_local_.last_fp_;
537
538  bool step_break = false;
539  switch (step_action) {
540    case StepNone:
541      return;
542    case StepOut:
543      // Step out has not reached the target frame yet.
544      if (current_fp < target_fp) return;
545      step_break = true;
546      break;
547    case StepNext:
548      // Step next should not break in a deeper frame.
549      if (current_fp < target_fp) return;
550      // For step-next, a tail call is like a return and should break.
551      step_break = location.IsTailCall();
552    // Fall through.
553    case StepIn: {
554      FrameSummary summary = FrameSummary::GetFirst(frame);
555      int offset = summary.code_offset();
556      step_break = step_break || location.IsReturn() ||
557                   (current_fp != last_fp) ||
558                   (thread_local_.last_statement_position_ !=
559                    summary.abstract_code()->SourceStatementPosition(offset));
560      break;
561    }
562    case StepFrame:
563      step_break = current_fp != last_fp;
564      break;
565  }
566
567  // Clear all current stepping setup.
568  ClearStepping();
569
570  if (step_break) {
571    // Notify the debug event listeners.
572    OnDebugBreak(isolate_->factory()->undefined_value(), false);
573  } else {
574    // Re-prepare to continue.
575    PrepareStep(step_action);
576  }
577}
578
579
580// Find break point objects for this location, if any, and evaluate them.
581// Return an array of break point objects that evaluated true.
582Handle<Object> Debug::CheckBreakPoints(Handle<DebugInfo> debug_info,
583                                       BreakLocation* location,
584                                       bool* has_break_points) {
585  Factory* factory = isolate_->factory();
586  bool has_break_points_to_check =
587      break_points_active_ && location->HasBreakPoint(debug_info);
588  if (has_break_points) *has_break_points = has_break_points_to_check;
589  if (!has_break_points_to_check) return factory->undefined_value();
590
591  Handle<Object> break_point_objects =
592      debug_info->GetBreakPointObjects(location->position());
593  // Count the number of break points hit. If there are multiple break points
594  // they are in a FixedArray.
595  Handle<FixedArray> break_points_hit;
596  int break_points_hit_count = 0;
597  DCHECK(!break_point_objects->IsUndefined(isolate_));
598  if (break_point_objects->IsFixedArray()) {
599    Handle<FixedArray> array(FixedArray::cast(*break_point_objects));
600    break_points_hit = factory->NewFixedArray(array->length());
601    for (int i = 0; i < array->length(); i++) {
602      Handle<Object> break_point_object(array->get(i), isolate_);
603      if (CheckBreakPoint(break_point_object)) {
604        break_points_hit->set(break_points_hit_count++, *break_point_object);
605      }
606    }
607  } else {
608    break_points_hit = factory->NewFixedArray(1);
609    if (CheckBreakPoint(break_point_objects)) {
610      break_points_hit->set(break_points_hit_count++, *break_point_objects);
611    }
612  }
613  if (break_points_hit_count == 0) return factory->undefined_value();
614  Handle<JSArray> result = factory->NewJSArrayWithElements(break_points_hit);
615  result->set_length(Smi::FromInt(break_points_hit_count));
616  return result;
617}
618
619
620bool Debug::IsMutedAtCurrentLocation(JavaScriptFrame* frame) {
621  // A break location is considered muted if break locations on the current
622  // statement have at least one break point, and all of these break points
623  // evaluate to false. Aside from not triggering a debug break event at the
624  // break location, we also do not trigger one for debugger statements, nor
625  // an exception event on exception at this location.
626  Object* fun = frame->function();
627  if (!fun->IsJSFunction()) return false;
628  JSFunction* function = JSFunction::cast(fun);
629  if (!function->shared()->HasDebugInfo()) return false;
630  HandleScope scope(isolate_);
631  Handle<DebugInfo> debug_info(function->shared()->GetDebugInfo());
632  // Enter the debugger.
633  DebugScope debug_scope(this);
634  if (debug_scope.failed()) return false;
635  List<BreakLocation> break_locations;
636  BreakLocation::AllAtCurrentStatement(debug_info, frame, &break_locations);
637  bool has_break_points_at_all = false;
638  for (int i = 0; i < break_locations.length(); i++) {
639    bool has_break_points;
640    Handle<Object> check_result =
641        CheckBreakPoints(debug_info, &break_locations[i], &has_break_points);
642    has_break_points_at_all |= has_break_points;
643    if (has_break_points && !check_result->IsUndefined(isolate_)) return false;
644  }
645  return has_break_points_at_all;
646}
647
648
649MaybeHandle<Object> Debug::CallFunction(const char* name, int argc,
650                                        Handle<Object> args[]) {
651  PostponeInterruptsScope no_interrupts(isolate_);
652  AssertDebugContext();
653  Handle<JSReceiver> holder =
654      Handle<JSReceiver>::cast(isolate_->natives_utils_object());
655  Handle<JSFunction> fun = Handle<JSFunction>::cast(
656      JSReceiver::GetProperty(isolate_, holder, name).ToHandleChecked());
657  Handle<Object> undefined = isolate_->factory()->undefined_value();
658  return Execution::TryCall(isolate_, fun, undefined, argc, args);
659}
660
661
662// Check whether a single break point object is triggered.
663bool Debug::CheckBreakPoint(Handle<Object> break_point_object) {
664  Factory* factory = isolate_->factory();
665  HandleScope scope(isolate_);
666
667  // Ignore check if break point object is not a JSObject.
668  if (!break_point_object->IsJSObject()) return true;
669
670  // Get the break id as an object.
671  Handle<Object> break_id = factory->NewNumberFromInt(Debug::break_id());
672
673  // Call IsBreakPointTriggered.
674  Handle<Object> argv[] = { break_id, break_point_object };
675  Handle<Object> result;
676  if (!CallFunction("IsBreakPointTriggered", arraysize(argv), argv)
677           .ToHandle(&result)) {
678    return false;
679  }
680
681  // Return whether the break point is triggered.
682  return result->IsTrue(isolate_);
683}
684
685
686bool Debug::SetBreakPoint(Handle<JSFunction> function,
687                          Handle<Object> break_point_object,
688                          int* source_position) {
689  HandleScope scope(isolate_);
690
691  // Make sure the function is compiled and has set up the debug info.
692  Handle<SharedFunctionInfo> shared(function->shared());
693  if (!EnsureDebugInfo(shared, function)) {
694    // Return if retrieving debug info failed.
695    return true;
696  }
697
698  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
699  // Source positions starts with zero.
700  DCHECK(*source_position >= 0);
701
702  // Find the break point and change it.
703  *source_position =
704      FindBreakablePosition(debug_info, *source_position, STATEMENT_ALIGNED);
705  DebugInfo::SetBreakPoint(debug_info, *source_position, break_point_object);
706  // At least one active break point now.
707  DCHECK(debug_info->GetBreakPointCount() > 0);
708
709  ClearBreakPoints(debug_info);
710  ApplyBreakPoints(debug_info);
711
712  feature_tracker()->Track(DebugFeatureTracker::kBreakPoint);
713  return true;
714}
715
716
717bool Debug::SetBreakPointForScript(Handle<Script> script,
718                                   Handle<Object> break_point_object,
719                                   int* source_position,
720                                   BreakPositionAlignment alignment) {
721  if (script->type() == Script::TYPE_WASM) {
722    // TODO(clemensh): set breakpoint for wasm.
723    return false;
724  }
725  HandleScope scope(isolate_);
726
727  // Obtain shared function info for the function.
728  Handle<Object> result =
729      FindSharedFunctionInfoInScript(script, *source_position);
730  if (result->IsUndefined(isolate_)) return false;
731
732  // Make sure the function has set up the debug info.
733  Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(result);
734  if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) {
735    // Return if retrieving debug info failed.
736    return false;
737  }
738
739  // Find position within function. The script position might be before the
740  // source position of the first function.
741  if (shared->start_position() > *source_position) {
742    *source_position = shared->start_position();
743  }
744
745  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
746
747  // Find the break point and change it.
748  *source_position =
749      FindBreakablePosition(debug_info, *source_position, alignment);
750  DebugInfo::SetBreakPoint(debug_info, *source_position, break_point_object);
751  // At least one active break point now.
752  DCHECK(debug_info->GetBreakPointCount() > 0);
753
754  ClearBreakPoints(debug_info);
755  ApplyBreakPoints(debug_info);
756
757  feature_tracker()->Track(DebugFeatureTracker::kBreakPoint);
758  return true;
759}
760
761int Debug::FindBreakablePosition(Handle<DebugInfo> debug_info,
762                                 int source_position,
763                                 BreakPositionAlignment alignment) {
764  int statement_position;
765  int position;
766  if (debug_info->HasDebugCode()) {
767    CodeBreakIterator it(debug_info, ALL_BREAK_LOCATIONS);
768    it.SkipToPosition(source_position, alignment);
769    statement_position = it.statement_position();
770    position = it.position();
771  } else {
772    DCHECK(debug_info->HasDebugBytecodeArray());
773    BytecodeArrayBreakIterator it(debug_info, ALL_BREAK_LOCATIONS);
774    it.SkipToPosition(source_position, alignment);
775    statement_position = it.statement_position();
776    position = it.position();
777  }
778  return alignment == STATEMENT_ALIGNED ? statement_position : position;
779}
780
781void Debug::ApplyBreakPoints(Handle<DebugInfo> debug_info) {
782  DisallowHeapAllocation no_gc;
783  if (debug_info->break_points()->IsUndefined(isolate_)) return;
784  FixedArray* break_points = debug_info->break_points();
785  for (int i = 0; i < break_points->length(); i++) {
786    if (break_points->get(i)->IsUndefined(isolate_)) continue;
787    BreakPointInfo* info = BreakPointInfo::cast(break_points->get(i));
788    if (info->GetBreakPointCount() == 0) continue;
789    if (debug_info->HasDebugCode()) {
790      CodeBreakIterator it(debug_info, ALL_BREAK_LOCATIONS);
791      it.SkipToPosition(info->source_position(), BREAK_POSITION_ALIGNED);
792      it.SetDebugBreak();
793    }
794    if (debug_info->HasDebugBytecodeArray()) {
795      BytecodeArrayBreakIterator it(debug_info, ALL_BREAK_LOCATIONS);
796      it.SkipToPosition(info->source_position(), BREAK_POSITION_ALIGNED);
797      it.SetDebugBreak();
798    }
799  }
800}
801
802void Debug::ClearBreakPoints(Handle<DebugInfo> debug_info) {
803  DisallowHeapAllocation no_gc;
804  if (debug_info->HasDebugCode()) {
805    for (CodeBreakIterator it(debug_info, ALL_BREAK_LOCATIONS); !it.Done();
806         it.Next()) {
807      it.ClearDebugBreak();
808    }
809  }
810  if (debug_info->HasDebugBytecodeArray()) {
811    for (BytecodeArrayBreakIterator it(debug_info, ALL_BREAK_LOCATIONS);
812         !it.Done(); it.Next()) {
813      it.ClearDebugBreak();
814    }
815  }
816}
817
818void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
819  HandleScope scope(isolate_);
820
821  for (DebugInfoListNode* node = debug_info_list_; node != NULL;
822       node = node->next()) {
823    Handle<Object> result =
824        DebugInfo::FindBreakPointInfo(node->debug_info(), break_point_object);
825    if (result->IsUndefined(isolate_)) continue;
826    Handle<DebugInfo> debug_info = node->debug_info();
827    if (DebugInfo::ClearBreakPoint(debug_info, break_point_object)) {
828      ClearBreakPoints(debug_info);
829      if (debug_info->GetBreakPointCount() == 0) {
830        RemoveDebugInfoAndClearFromShared(debug_info);
831      } else {
832        ApplyBreakPoints(debug_info);
833      }
834      return;
835    }
836  }
837}
838
839// Clear out all the debug break code. This is ONLY supposed to be used when
840// shutting down the debugger as it will leave the break point information in
841// DebugInfo even though the code is patched back to the non break point state.
842void Debug::ClearAllBreakPoints() {
843  for (DebugInfoListNode* node = debug_info_list_; node != NULL;
844       node = node->next()) {
845    ClearBreakPoints(node->debug_info());
846  }
847  // Remove all debug info.
848  while (debug_info_list_ != NULL) {
849    RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info());
850  }
851}
852
853void Debug::FloodWithOneShot(Handle<JSFunction> function,
854                             BreakLocatorType type) {
855  // Debug utility functions are not subject to debugging.
856  if (function->native_context() == *debug_context()) return;
857
858  if (!function->shared()->IsSubjectToDebugging()) {
859    // Builtin functions are not subject to stepping, but need to be
860    // deoptimized, because optimized code does not check for debug
861    // step in at call sites.
862    Deoptimizer::DeoptimizeFunction(*function);
863    return;
864  }
865  // Make sure the function is compiled and has set up the debug info.
866  Handle<SharedFunctionInfo> shared(function->shared());
867  if (!EnsureDebugInfo(shared, function)) {
868    // Return if we failed to retrieve the debug info.
869    return;
870  }
871
872  // Flood the function with break points.
873  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
874  if (debug_info->HasDebugCode()) {
875    for (CodeBreakIterator it(debug_info, type); !it.Done(); it.Next()) {
876      it.SetDebugBreak();
877    }
878  }
879  if (debug_info->HasDebugBytecodeArray()) {
880    for (BytecodeArrayBreakIterator it(debug_info, type); !it.Done();
881         it.Next()) {
882      it.SetDebugBreak();
883    }
884  }
885}
886
887void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) {
888  if (type == BreakUncaughtException) {
889    break_on_uncaught_exception_ = enable;
890  } else {
891    break_on_exception_ = enable;
892  }
893}
894
895
896bool Debug::IsBreakOnException(ExceptionBreakType type) {
897  if (type == BreakUncaughtException) {
898    return break_on_uncaught_exception_;
899  } else {
900    return break_on_exception_;
901  }
902}
903
904
905void Debug::PrepareStepIn(Handle<JSFunction> function) {
906  CHECK(last_step_action() >= StepIn);
907  if (!is_active()) return;
908  if (in_debug_scope()) return;
909  FloodWithOneShot(function);
910}
911
912void Debug::PrepareStepInSuspendedGenerator() {
913  CHECK(has_suspended_generator());
914  if (!is_active()) return;
915  if (in_debug_scope()) return;
916  thread_local_.last_step_action_ = StepIn;
917  Handle<JSFunction> function(
918      JSGeneratorObject::cast(thread_local_.suspended_generator_)->function());
919  FloodWithOneShot(function);
920  clear_suspended_generator();
921}
922
923void Debug::PrepareStepOnThrow() {
924  if (!is_active()) return;
925  if (last_step_action() == StepNone) return;
926  if (in_debug_scope()) return;
927
928  ClearOneShot();
929
930  // Iterate through the JavaScript stack looking for handlers.
931  JavaScriptFrameIterator it(isolate_);
932  while (!it.done()) {
933    JavaScriptFrame* frame = it.frame();
934    if (frame->LookupExceptionHandlerInTable(nullptr, nullptr) > 0) break;
935    it.Advance();
936  }
937
938  if (last_step_action() == StepNext || last_step_action() == StepOut) {
939    while (!it.done()) {
940      Address current_fp = it.frame()->UnpaddedFP();
941      if (current_fp >= thread_local_.target_fp_) break;
942      it.Advance();
943    }
944  }
945
946  // Find the closest Javascript frame we can flood with one-shots.
947  while (!it.done() &&
948         !it.frame()->function()->shared()->IsSubjectToDebugging()) {
949    it.Advance();
950  }
951
952  if (it.done()) return;  // No suitable Javascript catch handler.
953
954  FloodWithOneShot(Handle<JSFunction>(it.frame()->function()));
955}
956
957
958void Debug::PrepareStep(StepAction step_action) {
959  HandleScope scope(isolate_);
960
961  DCHECK(in_debug_scope());
962
963  // Get the frame where the execution has stopped and skip the debug frame if
964  // any. The debug frame will only be present if execution was stopped due to
965  // hitting a break point. In other situations (e.g. unhandled exception) the
966  // debug frame is not present.
967  StackFrame::Id frame_id = break_frame_id();
968  // If there is no JavaScript stack don't do anything.
969  if (frame_id == StackFrame::NO_ID) return;
970
971  JavaScriptFrameIterator frames_it(isolate_, frame_id);
972  JavaScriptFrame* frame = frames_it.frame();
973
974  feature_tracker()->Track(DebugFeatureTracker::kStepping);
975
976  thread_local_.last_step_action_ = step_action;
977
978  // If the function on the top frame is unresolved perform step out. This will
979  // be the case when calling unknown function and having the debugger stopped
980  // in an unhandled exception.
981  if (!frame->function()->IsJSFunction()) {
982    // Step out: Find the calling JavaScript frame and flood it with
983    // breakpoints.
984    frames_it.Advance();
985    // Fill the function to return to with one-shot break points.
986    JSFunction* function = frames_it.frame()->function();
987    FloodWithOneShot(Handle<JSFunction>(function));
988    return;
989  }
990
991  // Get the debug info (create it if it does not exist).
992  FrameSummary summary = FrameSummary::GetFirst(frame);
993  Handle<JSFunction> function(summary.function());
994  Handle<SharedFunctionInfo> shared(function->shared());
995  if (!EnsureDebugInfo(shared, function)) {
996    // Return if ensuring debug info failed.
997    return;
998  }
999
1000  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1001  BreakLocation location = BreakLocation::FromFrame(debug_info, frame);
1002
1003  // Any step at a return is a step-out.
1004  if (location.IsReturn()) step_action = StepOut;
1005  // A step-next at a tail call is a step-out.
1006  if (location.IsTailCall() && step_action == StepNext) step_action = StepOut;
1007
1008  thread_local_.last_statement_position_ =
1009      summary.abstract_code()->SourceStatementPosition(summary.code_offset());
1010  thread_local_.last_fp_ = frame->UnpaddedFP();
1011  // No longer perform the current async step.
1012  clear_suspended_generator();
1013
1014  switch (step_action) {
1015    case StepNone:
1016      UNREACHABLE();
1017      break;
1018    case StepOut:
1019      // Advance to caller frame.
1020      frames_it.Advance();
1021      // Skip native and extension functions on the stack.
1022      while (!frames_it.done() &&
1023             !frames_it.frame()->function()->shared()->IsSubjectToDebugging()) {
1024        // Builtin functions are not subject to stepping, but need to be
1025        // deoptimized to include checks for step-in at call sites.
1026        Deoptimizer::DeoptimizeFunction(frames_it.frame()->function());
1027        frames_it.Advance();
1028      }
1029      if (!frames_it.done()) {
1030        // Fill the caller function to return to with one-shot break points.
1031        Handle<JSFunction> caller_function(frames_it.frame()->function());
1032        FloodWithOneShot(caller_function);
1033        thread_local_.target_fp_ = frames_it.frame()->UnpaddedFP();
1034      }
1035      // Clear last position info. For stepping out it does not matter.
1036      thread_local_.last_statement_position_ = kNoSourcePosition;
1037      thread_local_.last_fp_ = 0;
1038      break;
1039    case StepNext:
1040      thread_local_.target_fp_ = frame->UnpaddedFP();
1041      FloodWithOneShot(function);
1042      break;
1043    case StepIn:
1044      FloodWithOneShot(function);
1045      break;
1046    case StepFrame:
1047      // No point in setting one-shot breaks at places where we are not about
1048      // to leave the current frame.
1049      FloodWithOneShot(function, CALLS_AND_RETURNS);
1050      break;
1051  }
1052}
1053
1054// Simple function for returning the source positions for active break points.
1055Handle<Object> Debug::GetSourceBreakLocations(
1056    Handle<SharedFunctionInfo> shared,
1057    BreakPositionAlignment position_alignment) {
1058  Isolate* isolate = shared->GetIsolate();
1059  if (!shared->HasDebugInfo()) {
1060    return isolate->factory()->undefined_value();
1061  }
1062  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1063  if (debug_info->GetBreakPointCount() == 0) {
1064    return isolate->factory()->undefined_value();
1065  }
1066  Handle<FixedArray> locations =
1067      isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount());
1068  int count = 0;
1069  for (int i = 0; i < debug_info->break_points()->length(); ++i) {
1070    if (!debug_info->break_points()->get(i)->IsUndefined(isolate)) {
1071      BreakPointInfo* break_point_info =
1072          BreakPointInfo::cast(debug_info->break_points()->get(i));
1073      int break_points = break_point_info->GetBreakPointCount();
1074      if (break_points == 0) continue;
1075      Smi* position = NULL;
1076      if (position_alignment == STATEMENT_ALIGNED) {
1077        if (debug_info->HasDebugCode()) {
1078          CodeBreakIterator it(debug_info, ALL_BREAK_LOCATIONS);
1079          it.SkipToPosition(break_point_info->source_position(),
1080                            BREAK_POSITION_ALIGNED);
1081          position = Smi::FromInt(it.statement_position());
1082        } else {
1083          DCHECK(debug_info->HasDebugBytecodeArray());
1084          BytecodeArrayBreakIterator it(debug_info, ALL_BREAK_LOCATIONS);
1085          it.SkipToPosition(break_point_info->source_position(),
1086                            BREAK_POSITION_ALIGNED);
1087          position = Smi::FromInt(it.statement_position());
1088        }
1089      } else {
1090        DCHECK_EQ(BREAK_POSITION_ALIGNED, position_alignment);
1091        position = Smi::FromInt(break_point_info->source_position());
1092      }
1093      for (int j = 0; j < break_points; ++j) locations->set(count++, position);
1094    }
1095  }
1096  return locations;
1097}
1098
1099void Debug::ClearStepping() {
1100  // Clear the various stepping setup.
1101  ClearOneShot();
1102
1103  thread_local_.last_step_action_ = StepNone;
1104  thread_local_.last_statement_position_ = kNoSourcePosition;
1105  thread_local_.last_fp_ = 0;
1106  thread_local_.target_fp_ = 0;
1107}
1108
1109
1110// Clears all the one-shot break points that are currently set. Normally this
1111// function is called each time a break point is hit as one shot break points
1112// are used to support stepping.
1113void Debug::ClearOneShot() {
1114  // The current implementation just runs through all the breakpoints. When the
1115  // last break point for a function is removed that function is automatically
1116  // removed from the list.
1117  for (DebugInfoListNode* node = debug_info_list_; node != NULL;
1118       node = node->next()) {
1119    Handle<DebugInfo> debug_info = node->debug_info();
1120    ClearBreakPoints(debug_info);
1121    ApplyBreakPoints(debug_info);
1122  }
1123}
1124
1125
1126bool MatchingCodeTargets(Code* target1, Code* target2) {
1127  if (target1 == target2) return true;
1128  if (target1->kind() != target2->kind()) return false;
1129  return target1->is_handler() || target1->is_inline_cache_stub();
1130}
1131
1132
1133// Count the number of calls before the current frame PC to find the
1134// corresponding PC in the newly recompiled code.
1135static Address ComputeNewPcForRedirect(Code* new_code, Code* old_code,
1136                                       Address old_pc) {
1137  DCHECK_EQ(old_code->kind(), Code::FUNCTION);
1138  DCHECK_EQ(new_code->kind(), Code::FUNCTION);
1139  DCHECK(new_code->has_debug_break_slots());
1140  static const int mask = RelocInfo::kCodeTargetMask;
1141
1142  // Find the target of the current call.
1143  Code* target = NULL;
1144  intptr_t delta = 0;
1145  for (RelocIterator it(old_code, mask); !it.done(); it.next()) {
1146    RelocInfo* rinfo = it.rinfo();
1147    Address current_pc = rinfo->pc();
1148    // The frame PC is behind the call instruction by the call instruction size.
1149    if (current_pc > old_pc) break;
1150    delta = old_pc - current_pc;
1151    target = Code::GetCodeFromTargetAddress(rinfo->target_address());
1152  }
1153
1154  // Count the number of calls to the same target before the current call.
1155  int index = 0;
1156  for (RelocIterator it(old_code, mask); !it.done(); it.next()) {
1157    RelocInfo* rinfo = it.rinfo();
1158    Address current_pc = rinfo->pc();
1159    if (current_pc > old_pc) break;
1160    Code* current = Code::GetCodeFromTargetAddress(rinfo->target_address());
1161    if (MatchingCodeTargets(target, current)) index++;
1162  }
1163
1164  DCHECK(index > 0);
1165
1166  // Repeat the count on the new code to find corresponding call.
1167  for (RelocIterator it(new_code, mask); !it.done(); it.next()) {
1168    RelocInfo* rinfo = it.rinfo();
1169    Code* current = Code::GetCodeFromTargetAddress(rinfo->target_address());
1170    if (MatchingCodeTargets(target, current)) index--;
1171    if (index == 0) return rinfo->pc() + delta;
1172  }
1173
1174  UNREACHABLE();
1175  return NULL;
1176}
1177
1178
1179// Count the number of continuations at which the current pc offset is at.
1180static int ComputeContinuationIndexFromPcOffset(Code* code, int pc_offset) {
1181  DCHECK_EQ(code->kind(), Code::FUNCTION);
1182  Address pc = code->instruction_start() + pc_offset;
1183  int mask = RelocInfo::ModeMask(RelocInfo::GENERATOR_CONTINUATION);
1184  int index = 0;
1185  for (RelocIterator it(code, mask); !it.done(); it.next()) {
1186    index++;
1187    RelocInfo* rinfo = it.rinfo();
1188    Address current_pc = rinfo->pc();
1189    if (current_pc == pc) break;
1190    DCHECK(current_pc < pc);
1191  }
1192  return index;
1193}
1194
1195
1196// Find the pc offset for the given continuation index.
1197static int ComputePcOffsetFromContinuationIndex(Code* code, int index) {
1198  DCHECK_EQ(code->kind(), Code::FUNCTION);
1199  DCHECK(code->has_debug_break_slots());
1200  int mask = RelocInfo::ModeMask(RelocInfo::GENERATOR_CONTINUATION);
1201  RelocIterator it(code, mask);
1202  for (int i = 1; i < index; i++) it.next();
1203  return static_cast<int>(it.rinfo()->pc() - code->instruction_start());
1204}
1205
1206
1207class RedirectActiveFunctions : public ThreadVisitor {
1208 public:
1209  explicit RedirectActiveFunctions(SharedFunctionInfo* shared)
1210      : shared_(shared) {
1211    DCHECK(shared->HasDebugCode());
1212  }
1213
1214  void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
1215    for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) {
1216      JavaScriptFrame* frame = it.frame();
1217      JSFunction* function = frame->function();
1218      if (frame->is_optimized()) continue;
1219      if (!function->Inlines(shared_)) continue;
1220
1221      if (frame->is_interpreted()) {
1222        InterpretedFrame* interpreted_frame =
1223            reinterpret_cast<InterpretedFrame*>(frame);
1224        BytecodeArray* debug_copy =
1225            shared_->GetDebugInfo()->DebugBytecodeArray();
1226        interpreted_frame->PatchBytecodeArray(debug_copy);
1227        continue;
1228      }
1229
1230      Code* frame_code = frame->LookupCode();
1231      DCHECK(frame_code->kind() == Code::FUNCTION);
1232      if (frame_code->has_debug_break_slots()) continue;
1233
1234      Code* new_code = function->shared()->code();
1235      Address old_pc = frame->pc();
1236      Address new_pc = ComputeNewPcForRedirect(new_code, frame_code, old_pc);
1237
1238      if (FLAG_trace_deopt) {
1239        PrintF("Replacing pc for debugging: %08" V8PRIxPTR " => %08" V8PRIxPTR
1240               "\n",
1241               reinterpret_cast<intptr_t>(old_pc),
1242               reinterpret_cast<intptr_t>(new_pc));
1243      }
1244
1245      if (FLAG_enable_embedded_constant_pool) {
1246        // Update constant pool pointer for new code.
1247        frame->set_constant_pool(new_code->constant_pool());
1248      }
1249
1250      // Patch the return address to return into the code with
1251      // debug break slots.
1252      frame->set_pc(new_pc);
1253    }
1254  }
1255
1256 private:
1257  SharedFunctionInfo* shared_;
1258  DisallowHeapAllocation no_gc_;
1259};
1260
1261
1262bool Debug::PrepareFunctionForBreakPoints(Handle<SharedFunctionInfo> shared) {
1263  DCHECK(shared->is_compiled());
1264
1265  if (isolate_->concurrent_recompilation_enabled()) {
1266    isolate_->optimizing_compile_dispatcher()->Flush(
1267        OptimizingCompileDispatcher::BlockingBehavior::kBlock);
1268  }
1269
1270  List<Handle<JSFunction> > functions;
1271  List<Handle<JSGeneratorObject> > suspended_generators;
1272
1273  // Flush all optimized code maps. Note that the below heap iteration does not
1274  // cover this, because the given function might have been inlined into code
1275  // for which no JSFunction exists.
1276  {
1277    SharedFunctionInfo::Iterator iterator(isolate_);
1278    while (SharedFunctionInfo* shared = iterator.Next()) {
1279      shared->ClearCodeFromOptimizedCodeMap();
1280    }
1281  }
1282
1283  // Make sure we abort incremental marking.
1284  isolate_->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask,
1285                                      GarbageCollectionReason::kDebugger);
1286
1287  DCHECK(shared->is_compiled());
1288  bool baseline_exists = shared->HasBaselineCode();
1289
1290  {
1291    // TODO(yangguo): with bytecode, we still walk the heap to find all
1292    // optimized code for the function to deoptimize. We can probably be
1293    // smarter here and avoid the heap walk.
1294    HeapIterator iterator(isolate_->heap());
1295    HeapObject* obj;
1296    // Continuation from old-style generators need to be recomputed.
1297    bool find_resumables =
1298        baseline_exists && IsResumableFunction(shared->kind());
1299
1300    while ((obj = iterator.next())) {
1301      if (obj->IsJSFunction()) {
1302        JSFunction* function = JSFunction::cast(obj);
1303        if (!function->Inlines(*shared)) continue;
1304        if (function->code()->kind() == Code::OPTIMIZED_FUNCTION) {
1305          Deoptimizer::DeoptimizeFunction(function);
1306        }
1307        if (baseline_exists && function->shared() == *shared) {
1308          functions.Add(handle(function));
1309        }
1310      } else if (find_resumables && obj->IsJSGeneratorObject()) {
1311        // This case handles async functions as well, as they use generator
1312        // objects for in-progress async function execution.
1313        JSGeneratorObject* generator_obj = JSGeneratorObject::cast(obj);
1314        if (!generator_obj->is_suspended()) continue;
1315        JSFunction* function = generator_obj->function();
1316        if (!function->Inlines(*shared)) continue;
1317        int pc_offset = generator_obj->continuation();
1318        int index =
1319            ComputeContinuationIndexFromPcOffset(function->code(), pc_offset);
1320        generator_obj->set_continuation(index);
1321        suspended_generators.Add(handle(generator_obj));
1322      }
1323    }
1324  }
1325
1326  // We do not need to replace code to debug bytecode.
1327  DCHECK(baseline_exists || functions.is_empty());
1328  DCHECK(baseline_exists || suspended_generators.is_empty());
1329
1330  // We do not need to recompile to debug bytecode.
1331  if (baseline_exists && !shared->code()->has_debug_break_slots()) {
1332    if (!Compiler::CompileDebugCode(shared)) return false;
1333  }
1334
1335  for (Handle<JSFunction> const function : functions) {
1336    function->ReplaceCode(shared->code());
1337    JSFunction::EnsureLiterals(function);
1338  }
1339
1340  for (Handle<JSGeneratorObject> const generator_obj : suspended_generators) {
1341    int index = generator_obj->continuation();
1342    int pc_offset = ComputePcOffsetFromContinuationIndex(shared->code(), index);
1343    generator_obj->set_continuation(pc_offset);
1344  }
1345
1346  // Update PCs on the stack to point to recompiled code.
1347  RedirectActiveFunctions redirect_visitor(*shared);
1348  redirect_visitor.VisitThread(isolate_, isolate_->thread_local_top());
1349  isolate_->thread_manager()->IterateArchivedThreads(&redirect_visitor);
1350
1351  return true;
1352}
1353
1354namespace {
1355template <typename Iterator>
1356void GetBreakablePositions(Iterator* it, int start_position, int end_position,
1357                           BreakPositionAlignment alignment,
1358                           std::set<int>* positions) {
1359  it->SkipToPosition(start_position, alignment);
1360  while (!it->Done() && it->position() < end_position &&
1361         it->position() >= start_position) {
1362    positions->insert(alignment == STATEMENT_ALIGNED ? it->statement_position()
1363                                                     : it->position());
1364    it->Next();
1365  }
1366}
1367
1368void FindBreakablePositions(Handle<DebugInfo> debug_info, int start_position,
1369                            int end_position, BreakPositionAlignment alignment,
1370                            std::set<int>* positions) {
1371  if (debug_info->HasDebugCode()) {
1372    CodeBreakIterator it(debug_info, ALL_BREAK_LOCATIONS);
1373    GetBreakablePositions(&it, start_position, end_position, alignment,
1374                          positions);
1375  } else {
1376    DCHECK(debug_info->HasDebugBytecodeArray());
1377    BytecodeArrayBreakIterator it(debug_info, ALL_BREAK_LOCATIONS);
1378    GetBreakablePositions(&it, start_position, end_position, alignment,
1379                          positions);
1380  }
1381}
1382}  // namespace
1383
1384bool Debug::GetPossibleBreakpoints(Handle<Script> script, int start_position,
1385                                   int end_position, std::set<int>* positions) {
1386  while (true) {
1387    if (!script->shared_function_infos()->IsWeakFixedArray()) return false;
1388
1389    WeakFixedArray* infos =
1390        WeakFixedArray::cast(script->shared_function_infos());
1391    HandleScope scope(isolate_);
1392    List<Handle<SharedFunctionInfo>> candidates;
1393    {
1394      WeakFixedArray::Iterator iterator(infos);
1395      SharedFunctionInfo* info;
1396      while ((info = iterator.Next<SharedFunctionInfo>())) {
1397        if (info->end_position() < start_position ||
1398            info->start_position() >= end_position) {
1399          continue;
1400        }
1401        if (!info->IsSubjectToDebugging()) continue;
1402        if (!info->HasDebugCode() && !info->allows_lazy_compilation()) continue;
1403        candidates.Add(i::handle(info));
1404      }
1405    }
1406
1407    bool was_compiled = false;
1408    for (int i = 0; i < candidates.length(); ++i) {
1409      // Code that cannot be compiled lazily are internal and not debuggable.
1410      DCHECK(candidates[i]->allows_lazy_compilation());
1411      if (!candidates[i]->HasDebugCode()) {
1412        if (!Compiler::CompileDebugCode(candidates[i])) {
1413          return false;
1414        } else {
1415          was_compiled = true;
1416        }
1417      }
1418      if (!EnsureDebugInfo(candidates[i], Handle<JSFunction>::null()))
1419        return false;
1420    }
1421    if (was_compiled) continue;
1422
1423    for (int i = 0; i < candidates.length(); ++i) {
1424      CHECK(candidates[i]->HasDebugInfo());
1425      Handle<DebugInfo> debug_info(candidates[i]->GetDebugInfo());
1426      FindBreakablePositions(debug_info, start_position, end_position,
1427                             STATEMENT_ALIGNED, positions);
1428    }
1429    return true;
1430  }
1431  UNREACHABLE();
1432  return false;
1433}
1434
1435void Debug::RecordAsyncFunction(Handle<JSGeneratorObject> generator_object) {
1436  if (last_step_action() <= StepOut) return;
1437  if (!IsAsyncFunction(generator_object->function()->shared()->kind())) return;
1438  DCHECK(!has_suspended_generator());
1439  thread_local_.suspended_generator_ = *generator_object;
1440  ClearStepping();
1441}
1442
1443class SharedFunctionInfoFinder {
1444 public:
1445  explicit SharedFunctionInfoFinder(int target_position)
1446      : current_candidate_(NULL),
1447        current_candidate_closure_(NULL),
1448        current_start_position_(kNoSourcePosition),
1449        target_position_(target_position) {}
1450
1451  void NewCandidate(SharedFunctionInfo* shared, JSFunction* closure = NULL) {
1452    if (!shared->IsSubjectToDebugging()) return;
1453    int start_position = shared->function_token_position();
1454    if (start_position == kNoSourcePosition) {
1455      start_position = shared->start_position();
1456    }
1457
1458    if (start_position > target_position_) return;
1459    if (target_position_ > shared->end_position()) return;
1460
1461    if (current_candidate_ != NULL) {
1462      if (current_start_position_ == start_position &&
1463          shared->end_position() == current_candidate_->end_position()) {
1464        // If we already have a matching closure, do not throw it away.
1465        if (current_candidate_closure_ != NULL && closure == NULL) return;
1466        // If a top-level function contains only one function
1467        // declaration the source for the top-level and the function
1468        // is the same. In that case prefer the non top-level function.
1469        if (!current_candidate_->is_toplevel() && shared->is_toplevel()) return;
1470      } else if (start_position < current_start_position_ ||
1471                 current_candidate_->end_position() < shared->end_position()) {
1472        return;
1473      }
1474    }
1475
1476    current_start_position_ = start_position;
1477    current_candidate_ = shared;
1478    current_candidate_closure_ = closure;
1479  }
1480
1481  SharedFunctionInfo* Result() { return current_candidate_; }
1482
1483  JSFunction* ResultClosure() { return current_candidate_closure_; }
1484
1485 private:
1486  SharedFunctionInfo* current_candidate_;
1487  JSFunction* current_candidate_closure_;
1488  int current_start_position_;
1489  int target_position_;
1490  DisallowHeapAllocation no_gc_;
1491};
1492
1493
1494// We need to find a SFI for a literal that may not yet have been compiled yet,
1495// and there may not be a JSFunction referencing it. Find the SFI closest to
1496// the given position, compile it to reveal possible inner SFIs and repeat.
1497// While we are at this, also ensure code with debug break slots so that we do
1498// not have to compile a SFI without JSFunction, which is paifu for those that
1499// cannot be compiled without context (need to find outer compilable SFI etc.)
1500Handle<Object> Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
1501                                                     int position) {
1502  for (int iteration = 0;; iteration++) {
1503    // Go through all shared function infos associated with this script to
1504    // find the inner most function containing this position.
1505    // If there is no shared function info for this script at all, there is
1506    // no point in looking for it by walking the heap.
1507    if (!script->shared_function_infos()->IsWeakFixedArray()) break;
1508
1509    SharedFunctionInfo* shared;
1510    {
1511      SharedFunctionInfoFinder finder(position);
1512      WeakFixedArray::Iterator iterator(script->shared_function_infos());
1513      SharedFunctionInfo* candidate;
1514      while ((candidate = iterator.Next<SharedFunctionInfo>())) {
1515        finder.NewCandidate(candidate);
1516      }
1517      shared = finder.Result();
1518      if (shared == NULL) break;
1519      // We found it if it's already compiled and has debug code.
1520      if (shared->HasDebugCode()) {
1521        Handle<SharedFunctionInfo> shared_handle(shared);
1522        // If the iteration count is larger than 1, we had to compile the outer
1523        // function in order to create this shared function info. So there can
1524        // be no JSFunction referencing it. We can anticipate creating a debug
1525        // info while bypassing PrepareFunctionForBreakpoints.
1526        if (iteration > 1) {
1527          AllowHeapAllocation allow_before_return;
1528          CreateDebugInfo(shared_handle);
1529        }
1530        return shared_handle;
1531      }
1532    }
1533    // If not, compile to reveal inner functions.
1534    HandleScope scope(isolate_);
1535    // Code that cannot be compiled lazily are internal and not debuggable.
1536    DCHECK(shared->allows_lazy_compilation());
1537    if (!Compiler::CompileDebugCode(handle(shared))) break;
1538  }
1539  return isolate_->factory()->undefined_value();
1540}
1541
1542
1543// Ensures the debug information is present for shared.
1544bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared,
1545                            Handle<JSFunction> function) {
1546  if (!shared->IsSubjectToDebugging()) return false;
1547
1548  // Return if we already have the debug info for shared.
1549  if (shared->HasDebugInfo()) return true;
1550
1551  if (function.is_null()) {
1552    DCHECK(shared->HasDebugCode());
1553  } else if (!Compiler::Compile(function, Compiler::CLEAR_EXCEPTION)) {
1554    return false;
1555  }
1556
1557  // To prepare bytecode for debugging, we already need to have the debug
1558  // info (containing the debug copy) upfront, but since we do not recompile,
1559  // preparing for break points cannot fail.
1560  CreateDebugInfo(shared);
1561  CHECK(PrepareFunctionForBreakPoints(shared));
1562  return true;
1563}
1564
1565
1566void Debug::CreateDebugInfo(Handle<SharedFunctionInfo> shared) {
1567  // Create the debug info object.
1568  Handle<DebugInfo> debug_info = isolate_->factory()->NewDebugInfo(shared);
1569
1570  // Add debug info to the list.
1571  DebugInfoListNode* node = new DebugInfoListNode(*debug_info);
1572  node->set_next(debug_info_list_);
1573  debug_info_list_ = node;
1574}
1575
1576
1577void Debug::RemoveDebugInfoAndClearFromShared(Handle<DebugInfo> debug_info) {
1578  HandleScope scope(isolate_);
1579  Handle<SharedFunctionInfo> shared(debug_info->shared());
1580
1581  DCHECK_NOT_NULL(debug_info_list_);
1582  // Run through the debug info objects to find this one and remove it.
1583  DebugInfoListNode* prev = NULL;
1584  DebugInfoListNode* current = debug_info_list_;
1585  while (current != NULL) {
1586    if (current->debug_info().is_identical_to(debug_info)) {
1587      // Unlink from list. If prev is NULL we are looking at the first element.
1588      if (prev == NULL) {
1589        debug_info_list_ = current->next();
1590      } else {
1591        prev->set_next(current->next());
1592      }
1593      delete current;
1594      shared->set_debug_info(DebugInfo::uninitialized());
1595      return;
1596    }
1597    // Move to next in list.
1598    prev = current;
1599    current = current->next();
1600  }
1601
1602  UNREACHABLE();
1603}
1604
1605void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
1606  after_break_target_ = NULL;
1607  if (!LiveEdit::SetAfterBreakTarget(this)) {
1608    // Continue just after the slot.
1609    after_break_target_ = frame->pc();
1610  }
1611}
1612
1613bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
1614  HandleScope scope(isolate_);
1615
1616  // Get the executing function in which the debug break occurred.
1617  Handle<SharedFunctionInfo> shared(frame->function()->shared());
1618
1619  // With no debug info there are no break points, so we can't be at a return.
1620  if (!shared->HasDebugInfo()) return false;
1621
1622  DCHECK(!frame->is_optimized());
1623  Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1624  BreakLocation location = BreakLocation::FromFrame(debug_info, frame);
1625  return location.IsReturn() || location.IsTailCall();
1626}
1627
1628void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
1629                                  LiveEditFrameDropMode mode) {
1630  if (mode != LIVE_EDIT_CURRENTLY_SET_MODE) {
1631    thread_local_.frame_drop_mode_ = mode;
1632  }
1633  thread_local_.break_frame_id_ = new_break_frame_id;
1634}
1635
1636
1637bool Debug::IsDebugGlobal(JSGlobalObject* global) {
1638  return is_loaded() && global == debug_context()->global_object();
1639}
1640
1641
1642void Debug::ClearMirrorCache() {
1643  PostponeInterruptsScope postpone(isolate_);
1644  HandleScope scope(isolate_);
1645  CallFunction("ClearMirrorCache", 0, NULL);
1646}
1647
1648
1649Handle<FixedArray> Debug::GetLoadedScripts() {
1650  isolate_->heap()->CollectAllGarbage(Heap::kFinalizeIncrementalMarkingMask,
1651                                      GarbageCollectionReason::kDebugger);
1652  Factory* factory = isolate_->factory();
1653  if (!factory->script_list()->IsWeakFixedArray()) {
1654    return factory->empty_fixed_array();
1655  }
1656  Handle<WeakFixedArray> array =
1657      Handle<WeakFixedArray>::cast(factory->script_list());
1658  Handle<FixedArray> results = factory->NewFixedArray(array->Length());
1659  int length = 0;
1660  {
1661    Script::Iterator iterator(isolate_);
1662    Script* script;
1663    while ((script = iterator.Next())) {
1664      if (script->HasValidSource()) results->set(length++, script);
1665    }
1666  }
1667  results->Shrink(length);
1668  return results;
1669}
1670
1671
1672MaybeHandle<Object> Debug::MakeExecutionState() {
1673  // Create the execution state object.
1674  Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()) };
1675  return CallFunction("MakeExecutionState", arraysize(argv), argv);
1676}
1677
1678
1679MaybeHandle<Object> Debug::MakeBreakEvent(Handle<Object> break_points_hit) {
1680  // Create the new break event object.
1681  Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()),
1682                            break_points_hit };
1683  return CallFunction("MakeBreakEvent", arraysize(argv), argv);
1684}
1685
1686
1687MaybeHandle<Object> Debug::MakeExceptionEvent(Handle<Object> exception,
1688                                              bool uncaught,
1689                                              Handle<Object> promise) {
1690  // Create the new exception event object.
1691  Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()),
1692                            exception,
1693                            isolate_->factory()->ToBoolean(uncaught),
1694                            promise };
1695  return CallFunction("MakeExceptionEvent", arraysize(argv), argv);
1696}
1697
1698
1699MaybeHandle<Object> Debug::MakeCompileEvent(Handle<Script> script,
1700                                            v8::DebugEvent type) {
1701  // Create the compile event object.
1702  Handle<Object> script_wrapper = Script::GetWrapper(script);
1703  Handle<Object> argv[] = { script_wrapper,
1704                            isolate_->factory()->NewNumberFromInt(type) };
1705  return CallFunction("MakeCompileEvent", arraysize(argv), argv);
1706}
1707
1708MaybeHandle<Object> Debug::MakeAsyncTaskEvent(Handle<String> type,
1709                                              Handle<Object> id,
1710                                              Handle<String> name) {
1711  DCHECK(id->IsNumber());
1712  // Create the async task event object.
1713  Handle<Object> argv[] = {type, id, name};
1714  return CallFunction("MakeAsyncTaskEvent", arraysize(argv), argv);
1715}
1716
1717
1718void Debug::OnThrow(Handle<Object> exception) {
1719  if (in_debug_scope() || ignore_events()) return;
1720  PrepareStepOnThrow();
1721  // Temporarily clear any scheduled_exception to allow evaluating
1722  // JavaScript from the debug event handler.
1723  HandleScope scope(isolate_);
1724  Handle<Object> scheduled_exception;
1725  if (isolate_->has_scheduled_exception()) {
1726    scheduled_exception = handle(isolate_->scheduled_exception(), isolate_);
1727    isolate_->clear_scheduled_exception();
1728  }
1729  OnException(exception, isolate_->GetPromiseOnStackOnThrow());
1730  if (!scheduled_exception.is_null()) {
1731    isolate_->thread_local_top()->scheduled_exception_ = *scheduled_exception;
1732  }
1733}
1734
1735void Debug::OnPromiseReject(Handle<Object> promise, Handle<Object> value) {
1736  if (in_debug_scope() || ignore_events()) return;
1737  HandleScope scope(isolate_);
1738  // Check whether the promise has been marked as having triggered a message.
1739  Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol();
1740  if (!promise->IsJSObject() ||
1741      JSReceiver::GetDataProperty(Handle<JSObject>::cast(promise), key)
1742          ->IsUndefined(isolate_)) {
1743    OnException(value, promise);
1744  }
1745}
1746
1747
1748void Debug::OnException(Handle<Object> exception, Handle<Object> promise) {
1749  // We cannot generate debug events when JS execution is disallowed.
1750  // TODO(5530): Reenable debug events within DisallowJSScopes once relevant
1751  // code (MakeExceptionEvent and ProcessDebugEvent) have been moved to C++.
1752  if (!AllowJavascriptExecution::IsAllowed(isolate_)) return;
1753
1754  Isolate::CatchType catch_type = isolate_->PredictExceptionCatcher();
1755
1756  // Don't notify listener of exceptions that are internal to a desugaring.
1757  if (catch_type == Isolate::CAUGHT_BY_DESUGARING) return;
1758
1759  bool uncaught = catch_type == Isolate::NOT_CAUGHT;
1760  if (promise->IsJSObject()) {
1761    Handle<JSObject> jspromise = Handle<JSObject>::cast(promise);
1762    // Mark the promise as already having triggered a message.
1763    Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol();
1764    JSObject::SetProperty(jspromise, key, key, STRICT).Assert();
1765    // Check whether the promise reject is considered an uncaught exception.
1766    uncaught = !isolate_->PromiseHasUserDefinedRejectHandler(jspromise);
1767  }
1768  // Bail out if exception breaks are not active
1769  if (uncaught) {
1770    // Uncaught exceptions are reported by either flags.
1771    if (!(break_on_uncaught_exception_ || break_on_exception_)) return;
1772  } else {
1773    // Caught exceptions are reported is activated.
1774    if (!break_on_exception_) return;
1775  }
1776
1777  {
1778    // Check whether the break location is muted.
1779    JavaScriptFrameIterator it(isolate_);
1780    if (!it.done() && IsMutedAtCurrentLocation(it.frame())) return;
1781  }
1782
1783  DebugScope debug_scope(this);
1784  if (debug_scope.failed()) return;
1785
1786  // Create the event data object.
1787  Handle<Object> event_data;
1788  // Bail out and don't call debugger if exception.
1789  if (!MakeExceptionEvent(
1790          exception, uncaught, promise).ToHandle(&event_data)) {
1791    return;
1792  }
1793
1794  // Process debug event.
1795  ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false);
1796  // Return to continue execution from where the exception was thrown.
1797}
1798
1799
1800void Debug::OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue) {
1801  // The caller provided for DebugScope.
1802  AssertDebugContext();
1803  // Bail out if there is no listener for this event
1804  if (ignore_events()) return;
1805
1806#ifdef DEBUG
1807  PrintBreakLocation();
1808#endif  // DEBUG
1809
1810  HandleScope scope(isolate_);
1811  // Create the event data object.
1812  Handle<Object> event_data;
1813  // Bail out and don't call debugger if exception.
1814  if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return;
1815
1816  // Process debug event.
1817  ProcessDebugEvent(v8::Break,
1818                    Handle<JSObject>::cast(event_data),
1819                    auto_continue);
1820}
1821
1822
1823void Debug::OnCompileError(Handle<Script> script) {
1824  ProcessCompileEvent(v8::CompileError, script);
1825}
1826
1827
1828void Debug::OnBeforeCompile(Handle<Script> script) {
1829  ProcessCompileEvent(v8::BeforeCompile, script);
1830}
1831
1832
1833// Handle debugger actions when a new script is compiled.
1834void Debug::OnAfterCompile(Handle<Script> script) {
1835  ProcessCompileEvent(v8::AfterCompile, script);
1836}
1837
1838void Debug::OnAsyncTaskEvent(Handle<String> type, Handle<Object> id,
1839                             Handle<String> name) {
1840  DCHECK(id->IsNumber());
1841  if (in_debug_scope() || ignore_events()) return;
1842
1843  HandleScope scope(isolate_);
1844  DebugScope debug_scope(this);
1845  if (debug_scope.failed()) return;
1846
1847  // Create the script collected state object.
1848  Handle<Object> event_data;
1849  // Bail out and don't call debugger if exception.
1850  if (!MakeAsyncTaskEvent(type, id, name).ToHandle(&event_data)) return;
1851
1852  // Process debug event.
1853  ProcessDebugEvent(v8::AsyncTaskEvent,
1854                    Handle<JSObject>::cast(event_data),
1855                    true);
1856}
1857
1858
1859void Debug::ProcessDebugEvent(v8::DebugEvent event,
1860                              Handle<JSObject> event_data,
1861                              bool auto_continue) {
1862  HandleScope scope(isolate_);
1863
1864  // Create the execution state.
1865  Handle<Object> exec_state;
1866  // Bail out and don't call debugger if exception.
1867  if (!MakeExecutionState().ToHandle(&exec_state)) return;
1868
1869  // First notify the message handler if any.
1870  if (message_handler_ != NULL) {
1871    NotifyMessageHandler(event,
1872                         Handle<JSObject>::cast(exec_state),
1873                         event_data,
1874                         auto_continue);
1875  }
1876  // Notify registered debug event listener. This can be either a C or
1877  // a JavaScript function. Don't call event listener for v8::Break
1878  // here, if it's only a debug command -- they will be processed later.
1879  if ((event != v8::Break || !auto_continue) && !event_listener_.is_null()) {
1880    CallEventCallback(event, exec_state, event_data, NULL);
1881  }
1882}
1883
1884
1885void Debug::CallEventCallback(v8::DebugEvent event,
1886                              Handle<Object> exec_state,
1887                              Handle<Object> event_data,
1888                              v8::Debug::ClientData* client_data) {
1889  // Prevent other interrupts from triggering, for example API callbacks,
1890  // while dispatching event listners.
1891  PostponeInterruptsScope postpone(isolate_);
1892  bool previous = in_debug_event_listener_;
1893  in_debug_event_listener_ = true;
1894  if (event_listener_->IsForeign()) {
1895    // Invoke the C debug event listener.
1896    v8::DebugInterface::EventCallback callback =
1897        FUNCTION_CAST<v8::DebugInterface::EventCallback>(
1898            Handle<Foreign>::cast(event_listener_)->foreign_address());
1899    EventDetailsImpl event_details(event,
1900                                   Handle<JSObject>::cast(exec_state),
1901                                   Handle<JSObject>::cast(event_data),
1902                                   event_listener_data_,
1903                                   client_data);
1904    callback(event_details);
1905    CHECK(!isolate_->has_scheduled_exception());
1906  } else {
1907    // Invoke the JavaScript debug event listener.
1908    DCHECK(event_listener_->IsJSFunction());
1909    Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event), isolate_),
1910                              exec_state,
1911                              event_data,
1912                              event_listener_data_ };
1913    Handle<JSReceiver> global = isolate_->global_proxy();
1914    MaybeHandle<Object> result =
1915        Execution::Call(isolate_, Handle<JSFunction>::cast(event_listener_),
1916                        global, arraysize(argv), argv);
1917    CHECK(!result.is_null());  // Listeners must not throw.
1918  }
1919  in_debug_event_listener_ = previous;
1920}
1921
1922
1923void Debug::ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script) {
1924  if (ignore_events()) return;
1925  SuppressDebug while_processing(this);
1926
1927  bool in_nested_debug_scope = in_debug_scope();
1928  HandleScope scope(isolate_);
1929  DebugScope debug_scope(this);
1930  if (debug_scope.failed()) return;
1931
1932  if (event == v8::AfterCompile) {
1933    // If debugging there might be script break points registered for this
1934    // script. Make sure that these break points are set.
1935    Handle<Object> argv[] = {Script::GetWrapper(script)};
1936    if (CallFunction("UpdateScriptBreakPoints", arraysize(argv), argv)
1937            .is_null()) {
1938      return;
1939    }
1940  }
1941
1942  // Create the compile state object.
1943  Handle<Object> event_data;
1944  // Bail out and don't call debugger if exception.
1945  if (!MakeCompileEvent(script, event).ToHandle(&event_data)) return;
1946
1947  // Don't call NotifyMessageHandler if already in debug scope to avoid running
1948  // nested command loop.
1949  if (in_nested_debug_scope) {
1950    if (event_listener_.is_null()) return;
1951    // Create the execution state.
1952    Handle<Object> exec_state;
1953    // Bail out and don't call debugger if exception.
1954    if (!MakeExecutionState().ToHandle(&exec_state)) return;
1955
1956    CallEventCallback(event, exec_state, event_data, NULL);
1957  } else {
1958    // Process debug event.
1959    ProcessDebugEvent(event, Handle<JSObject>::cast(event_data), true);
1960  }
1961}
1962
1963
1964Handle<Context> Debug::GetDebugContext() {
1965  if (!is_loaded()) return Handle<Context>();
1966  DebugScope debug_scope(this);
1967  if (debug_scope.failed()) return Handle<Context>();
1968  // The global handle may be destroyed soon after.  Return it reboxed.
1969  return handle(*debug_context(), isolate_);
1970}
1971
1972
1973void Debug::NotifyMessageHandler(v8::DebugEvent event,
1974                                 Handle<JSObject> exec_state,
1975                                 Handle<JSObject> event_data,
1976                                 bool auto_continue) {
1977  // Prevent other interrupts from triggering, for example API callbacks,
1978  // while dispatching message handler callbacks.
1979  PostponeInterruptsScope no_interrupts(isolate_);
1980  DCHECK(is_active_);
1981  HandleScope scope(isolate_);
1982  // Process the individual events.
1983  bool sendEventMessage = false;
1984  switch (event) {
1985    case v8::Break:
1986      sendEventMessage = !auto_continue;
1987      break;
1988    case v8::NewFunction:
1989    case v8::BeforeCompile:
1990    case v8::CompileError:
1991    case v8::AsyncTaskEvent:
1992      break;
1993    case v8::Exception:
1994    case v8::AfterCompile:
1995      sendEventMessage = true;
1996      break;
1997  }
1998
1999  // The debug command interrupt flag might have been set when the command was
2000  // added. It should be enough to clear the flag only once while we are in the
2001  // debugger.
2002  DCHECK(in_debug_scope());
2003  isolate_->stack_guard()->ClearDebugCommand();
2004
2005  // Notify the debugger that a debug event has occurred unless auto continue is
2006  // active in which case no event is send.
2007  if (sendEventMessage) {
2008    MessageImpl message = MessageImpl::NewEvent(
2009        event,
2010        auto_continue,
2011        Handle<JSObject>::cast(exec_state),
2012        Handle<JSObject>::cast(event_data));
2013    InvokeMessageHandler(message);
2014  }
2015
2016  // If auto continue don't make the event cause a break, but process messages
2017  // in the queue if any. For script collected events don't even process
2018  // messages in the queue as the execution state might not be what is expected
2019  // by the client.
2020  if (auto_continue && !has_commands()) return;
2021
2022  // DebugCommandProcessor goes here.
2023  bool running = auto_continue;
2024
2025  Handle<Object> cmd_processor_ctor =
2026      JSReceiver::GetProperty(isolate_, exec_state, "debugCommandProcessor")
2027          .ToHandleChecked();
2028  Handle<Object> ctor_args[] = { isolate_->factory()->ToBoolean(running) };
2029  Handle<JSReceiver> cmd_processor = Handle<JSReceiver>::cast(
2030      Execution::Call(isolate_, cmd_processor_ctor, exec_state, 1, ctor_args)
2031          .ToHandleChecked());
2032  Handle<JSFunction> process_debug_request = Handle<JSFunction>::cast(
2033      JSReceiver::GetProperty(isolate_, cmd_processor, "processDebugRequest")
2034          .ToHandleChecked());
2035  Handle<Object> is_running =
2036      JSReceiver::GetProperty(isolate_, cmd_processor, "isRunning")
2037          .ToHandleChecked();
2038
2039  // Process requests from the debugger.
2040  do {
2041    // Wait for new command in the queue.
2042    command_received_.Wait();
2043
2044    // Get the command from the queue.
2045    CommandMessage command = command_queue_.Get();
2046    isolate_->logger()->DebugTag(
2047        "Got request from command queue, in interactive loop.");
2048    if (!is_active()) {
2049      // Delete command text and user data.
2050      command.Dispose();
2051      return;
2052    }
2053
2054    Vector<const uc16> command_text(
2055        const_cast<const uc16*>(command.text().start()),
2056        command.text().length());
2057    Handle<String> request_text = isolate_->factory()->NewStringFromTwoByte(
2058        command_text).ToHandleChecked();
2059    Handle<Object> request_args[] = { request_text };
2060    Handle<Object> answer_value;
2061    Handle<String> answer;
2062    MaybeHandle<Object> maybe_exception;
2063    MaybeHandle<Object> maybe_result =
2064        Execution::TryCall(isolate_, process_debug_request, cmd_processor, 1,
2065                           request_args, &maybe_exception);
2066
2067    if (maybe_result.ToHandle(&answer_value)) {
2068      if (answer_value->IsUndefined(isolate_)) {
2069        answer = isolate_->factory()->empty_string();
2070      } else {
2071        answer = Handle<String>::cast(answer_value);
2072      }
2073
2074      // Log the JSON request/response.
2075      if (FLAG_trace_debug_json) {
2076        PrintF("%s\n", request_text->ToCString().get());
2077        PrintF("%s\n", answer->ToCString().get());
2078      }
2079
2080      Handle<Object> is_running_args[] = { answer };
2081      maybe_result = Execution::Call(
2082          isolate_, is_running, cmd_processor, 1, is_running_args);
2083      Handle<Object> result;
2084      if (!maybe_result.ToHandle(&result)) break;
2085      running = result->IsTrue(isolate_);
2086    } else {
2087      Handle<Object> exception;
2088      if (!maybe_exception.ToHandle(&exception)) break;
2089      Handle<Object> result;
2090      if (!Object::ToString(isolate_, exception).ToHandle(&result)) break;
2091      answer = Handle<String>::cast(result);
2092    }
2093
2094    // Return the result.
2095    MessageImpl message = MessageImpl::NewResponse(
2096        event, running, exec_state, event_data, answer, command.client_data());
2097    InvokeMessageHandler(message);
2098    command.Dispose();
2099
2100    // Return from debug event processing if either the VM is put into the
2101    // running state (through a continue command) or auto continue is active
2102    // and there are no more commands queued.
2103  } while (!running || has_commands());
2104  command_queue_.Clear();
2105}
2106
2107
2108void Debug::SetEventListener(Handle<Object> callback,
2109                             Handle<Object> data) {
2110  GlobalHandles* global_handles = isolate_->global_handles();
2111
2112  // Remove existing entry.
2113  GlobalHandles::Destroy(event_listener_.location());
2114  event_listener_ = Handle<Object>();
2115  GlobalHandles::Destroy(event_listener_data_.location());
2116  event_listener_data_ = Handle<Object>();
2117
2118  // Set new entry.
2119  if (!callback->IsUndefined(isolate_) && !callback->IsNull(isolate_)) {
2120    event_listener_ = global_handles->Create(*callback);
2121    if (data.is_null()) data = isolate_->factory()->undefined_value();
2122    event_listener_data_ = global_handles->Create(*data);
2123  }
2124
2125  UpdateState();
2126}
2127
2128
2129void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
2130  message_handler_ = handler;
2131  UpdateState();
2132  if (handler == NULL && in_debug_scope()) {
2133    // Send an empty command to the debugger if in a break to make JavaScript
2134    // run again if the debugger is closed.
2135    EnqueueCommandMessage(Vector<const uint16_t>::empty());
2136  }
2137}
2138
2139
2140
2141void Debug::UpdateState() {
2142  bool is_active = message_handler_ != NULL || !event_listener_.is_null();
2143  if (is_active || in_debug_scope()) {
2144    // Note that the debug context could have already been loaded to
2145    // bootstrap test cases.
2146    isolate_->compilation_cache()->Disable();
2147    is_active = Load();
2148  } else if (is_loaded()) {
2149    isolate_->compilation_cache()->Enable();
2150    Unload();
2151  }
2152  is_active_ = is_active;
2153}
2154
2155
2156// Calls the registered debug message handler. This callback is part of the
2157// public API.
2158void Debug::InvokeMessageHandler(MessageImpl message) {
2159  if (message_handler_ != NULL) message_handler_(message);
2160}
2161
2162
2163// Puts a command coming from the public API on the queue.  Creates
2164// a copy of the command string managed by the debugger.  Up to this
2165// point, the command data was managed by the API client.  Called
2166// by the API client thread.
2167void Debug::EnqueueCommandMessage(Vector<const uint16_t> command,
2168                                  v8::Debug::ClientData* client_data) {
2169  // Need to cast away const.
2170  CommandMessage message = CommandMessage::New(
2171      Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
2172                       command.length()),
2173      client_data);
2174  isolate_->logger()->DebugTag("Put command on command_queue.");
2175  command_queue_.Put(message);
2176  command_received_.Signal();
2177
2178  // Set the debug command break flag to have the command processed.
2179  if (!in_debug_scope()) isolate_->stack_guard()->RequestDebugCommand();
2180}
2181
2182
2183MaybeHandle<Object> Debug::Call(Handle<Object> fun, Handle<Object> data) {
2184  DebugScope debug_scope(this);
2185  if (debug_scope.failed()) return isolate_->factory()->undefined_value();
2186
2187  // Create the execution state.
2188  Handle<Object> exec_state;
2189  if (!MakeExecutionState().ToHandle(&exec_state)) {
2190    return isolate_->factory()->undefined_value();
2191  }
2192
2193  Handle<Object> argv[] = { exec_state, data };
2194  return Execution::Call(
2195      isolate_,
2196      fun,
2197      Handle<Object>(debug_context()->global_proxy(), isolate_),
2198      arraysize(argv),
2199      argv);
2200}
2201
2202
2203void Debug::HandleDebugBreak() {
2204  // Ignore debug break during bootstrapping.
2205  if (isolate_->bootstrapper()->IsActive()) return;
2206  // Just continue if breaks are disabled.
2207  if (break_disabled()) return;
2208  // Ignore debug break if debugger is not active.
2209  if (!is_active()) return;
2210
2211  StackLimitCheck check(isolate_);
2212  if (check.HasOverflowed()) return;
2213
2214  { JavaScriptFrameIterator it(isolate_);
2215    DCHECK(!it.done());
2216    Object* fun = it.frame()->function();
2217    if (fun && fun->IsJSFunction()) {
2218      // Don't stop in builtin functions.
2219      if (!JSFunction::cast(fun)->shared()->IsSubjectToDebugging()) return;
2220      JSGlobalObject* global =
2221          JSFunction::cast(fun)->context()->global_object();
2222      // Don't stop in debugger functions.
2223      if (IsDebugGlobal(global)) return;
2224      // Don't stop if the break location is muted.
2225      if (IsMutedAtCurrentLocation(it.frame())) return;
2226    }
2227  }
2228
2229  // Collect the break state before clearing the flags.
2230  bool debug_command_only = isolate_->stack_guard()->CheckDebugCommand() &&
2231                            !isolate_->stack_guard()->CheckDebugBreak();
2232
2233  isolate_->stack_guard()->ClearDebugBreak();
2234
2235  // Clear stepping to avoid duplicate breaks.
2236  ClearStepping();
2237
2238  ProcessDebugMessages(debug_command_only);
2239}
2240
2241
2242void Debug::ProcessDebugMessages(bool debug_command_only) {
2243  isolate_->stack_guard()->ClearDebugCommand();
2244
2245  StackLimitCheck check(isolate_);
2246  if (check.HasOverflowed()) return;
2247
2248  HandleScope scope(isolate_);
2249  DebugScope debug_scope(this);
2250  if (debug_scope.failed()) return;
2251
2252  // Notify the debug event listeners. Indicate auto continue if the break was
2253  // a debug command break.
2254  OnDebugBreak(isolate_->factory()->undefined_value(), debug_command_only);
2255}
2256
2257#ifdef DEBUG
2258void Debug::PrintBreakLocation() {
2259  if (!FLAG_print_break_location) return;
2260  HandleScope scope(isolate_);
2261  JavaScriptFrameIterator iterator(isolate_);
2262  if (iterator.done()) return;
2263  JavaScriptFrame* frame = iterator.frame();
2264  FrameSummary summary = FrameSummary::GetFirst(frame);
2265  int source_position =
2266      summary.abstract_code()->SourcePosition(summary.code_offset());
2267  Handle<Object> script_obj(summary.function()->shared()->script(), isolate_);
2268  PrintF("[debug] break in function '");
2269  summary.function()->PrintName();
2270  PrintF("'.\n");
2271  if (script_obj->IsScript()) {
2272    Handle<Script> script = Handle<Script>::cast(script_obj);
2273    Handle<String> source(String::cast(script->source()));
2274    Script::InitLineEnds(script);
2275    int line =
2276        Script::GetLineNumber(script, source_position) - script->line_offset();
2277    int column = Script::GetColumnNumber(script, source_position) -
2278                 (line == 0 ? script->column_offset() : 0);
2279    Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
2280    int line_start =
2281        line == 0 ? 0 : Smi::cast(line_ends->get(line - 1))->value() + 1;
2282    int line_end = Smi::cast(line_ends->get(line))->value();
2283    DisallowHeapAllocation no_gc;
2284    String::FlatContent content = source->GetFlatContent();
2285    if (content.IsOneByte()) {
2286      PrintF("[debug] %.*s\n", line_end - line_start,
2287             content.ToOneByteVector().start() + line_start);
2288      PrintF("[debug] ");
2289      for (int i = 0; i < column; i++) PrintF(" ");
2290      PrintF("^\n");
2291    } else {
2292      PrintF("[debug] at line %d column %d\n", line, column);
2293    }
2294  }
2295}
2296#endif  // DEBUG
2297
2298DebugScope::DebugScope(Debug* debug)
2299    : debug_(debug),
2300      prev_(debug->debugger_entry()),
2301      save_(debug_->isolate_),
2302      no_termination_exceptons_(debug_->isolate_,
2303                                StackGuard::TERMINATE_EXECUTION) {
2304  // Link recursive debugger entry.
2305  base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_,
2306                        reinterpret_cast<base::AtomicWord>(this));
2307
2308  // Store the previous break id, frame id and return value.
2309  break_id_ = debug_->break_id();
2310  break_frame_id_ = debug_->break_frame_id();
2311  return_value_ = debug_->return_value();
2312
2313  // Create the new break info. If there is no proper frames there is no break
2314  // frame id.
2315  StackTraceFrameIterator it(isolate());
2316  bool has_frames = !it.done();
2317  // We don't currently support breaking inside wasm framess.
2318  DCHECK(!has_frames || !it.is_wasm());
2319  debug_->thread_local_.break_frame_id_ =
2320      has_frames ? it.frame()->id() : StackFrame::NO_ID;
2321  debug_->SetNextBreakId();
2322
2323  debug_->UpdateState();
2324  // Make sure that debugger is loaded and enter the debugger context.
2325  // The previous context is kept in save_.
2326  failed_ = !debug_->is_loaded();
2327  if (!failed_) isolate()->set_context(*debug->debug_context());
2328}
2329
2330
2331DebugScope::~DebugScope() {
2332  if (!failed_ && prev_ == NULL) {
2333    // Clear mirror cache when leaving the debugger. Skip this if there is a
2334    // pending exception as clearing the mirror cache calls back into
2335    // JavaScript. This can happen if the v8::Debug::Call is used in which
2336    // case the exception should end up in the calling code.
2337    if (!isolate()->has_pending_exception()) debug_->ClearMirrorCache();
2338
2339    // If there are commands in the queue when leaving the debugger request
2340    // that these commands are processed.
2341    if (debug_->has_commands()) isolate()->stack_guard()->RequestDebugCommand();
2342  }
2343
2344  // Leaving this debugger entry.
2345  base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_,
2346                        reinterpret_cast<base::AtomicWord>(prev_));
2347
2348  // Restore to the previous break state.
2349  debug_->thread_local_.break_frame_id_ = break_frame_id_;
2350  debug_->thread_local_.break_id_ = break_id_;
2351  debug_->thread_local_.return_value_ = return_value_;
2352
2353  debug_->UpdateState();
2354}
2355
2356
2357MessageImpl MessageImpl::NewEvent(DebugEvent event,
2358                                  bool running,
2359                                  Handle<JSObject> exec_state,
2360                                  Handle<JSObject> event_data) {
2361  MessageImpl message(true, event, running,
2362                      exec_state, event_data, Handle<String>(), NULL);
2363  return message;
2364}
2365
2366
2367MessageImpl MessageImpl::NewResponse(DebugEvent event,
2368                                     bool running,
2369                                     Handle<JSObject> exec_state,
2370                                     Handle<JSObject> event_data,
2371                                     Handle<String> response_json,
2372                                     v8::Debug::ClientData* client_data) {
2373  MessageImpl message(false, event, running,
2374                      exec_state, event_data, response_json, client_data);
2375  return message;
2376}
2377
2378
2379MessageImpl::MessageImpl(bool is_event,
2380                         DebugEvent event,
2381                         bool running,
2382                         Handle<JSObject> exec_state,
2383                         Handle<JSObject> event_data,
2384                         Handle<String> response_json,
2385                         v8::Debug::ClientData* client_data)
2386    : is_event_(is_event),
2387      event_(event),
2388      running_(running),
2389      exec_state_(exec_state),
2390      event_data_(event_data),
2391      response_json_(response_json),
2392      client_data_(client_data) {}
2393
2394
2395bool MessageImpl::IsEvent() const {
2396  return is_event_;
2397}
2398
2399
2400bool MessageImpl::IsResponse() const {
2401  return !is_event_;
2402}
2403
2404
2405DebugEvent MessageImpl::GetEvent() const {
2406  return event_;
2407}
2408
2409
2410bool MessageImpl::WillStartRunning() const {
2411  return running_;
2412}
2413
2414
2415v8::Local<v8::Object> MessageImpl::GetExecutionState() const {
2416  return v8::Utils::ToLocal(exec_state_);
2417}
2418
2419
2420v8::Isolate* MessageImpl::GetIsolate() const {
2421  return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate());
2422}
2423
2424
2425v8::Local<v8::Object> MessageImpl::GetEventData() const {
2426  return v8::Utils::ToLocal(event_data_);
2427}
2428
2429
2430v8::Local<v8::String> MessageImpl::GetJSON() const {
2431  Isolate* isolate = event_data_->GetIsolate();
2432  v8::EscapableHandleScope scope(reinterpret_cast<v8::Isolate*>(isolate));
2433
2434  if (IsEvent()) {
2435    // Call toJSONProtocol on the debug event object.
2436    Handle<Object> fun =
2437        JSReceiver::GetProperty(isolate, event_data_, "toJSONProtocol")
2438            .ToHandleChecked();
2439    if (!fun->IsJSFunction()) {
2440      return v8::Local<v8::String>();
2441    }
2442
2443    MaybeHandle<Object> maybe_json =
2444        Execution::TryCall(isolate, fun, event_data_, 0, NULL);
2445    Handle<Object> json;
2446    if (!maybe_json.ToHandle(&json) || !json->IsString()) {
2447      return v8::Local<v8::String>();
2448    }
2449    return scope.Escape(v8::Utils::ToLocal(Handle<String>::cast(json)));
2450  } else {
2451    return v8::Utils::ToLocal(response_json_);
2452  }
2453}
2454
2455namespace {
2456v8::Local<v8::Context> GetDebugEventContext(Isolate* isolate) {
2457  Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
2458  // Isolate::context() may have been NULL when "script collected" event
2459  // occured.
2460  if (context.is_null()) return v8::Local<v8::Context>();
2461  Handle<Context> native_context(context->native_context());
2462  return v8::Utils::ToLocal(native_context);
2463}
2464}  // anonymous namespace
2465
2466v8::Local<v8::Context> MessageImpl::GetEventContext() const {
2467  Isolate* isolate = event_data_->GetIsolate();
2468  v8::Local<v8::Context> context = GetDebugEventContext(isolate);
2469  // Isolate::context() may be NULL when "script collected" event occurs.
2470  DCHECK(!context.IsEmpty());
2471  return context;
2472}
2473
2474
2475v8::Debug::ClientData* MessageImpl::GetClientData() const {
2476  return client_data_;
2477}
2478
2479
2480EventDetailsImpl::EventDetailsImpl(DebugEvent event,
2481                                   Handle<JSObject> exec_state,
2482                                   Handle<JSObject> event_data,
2483                                   Handle<Object> callback_data,
2484                                   v8::Debug::ClientData* client_data)
2485    : event_(event),
2486      exec_state_(exec_state),
2487      event_data_(event_data),
2488      callback_data_(callback_data),
2489      client_data_(client_data) {}
2490
2491
2492DebugEvent EventDetailsImpl::GetEvent() const {
2493  return event_;
2494}
2495
2496
2497v8::Local<v8::Object> EventDetailsImpl::GetExecutionState() const {
2498  return v8::Utils::ToLocal(exec_state_);
2499}
2500
2501
2502v8::Local<v8::Object> EventDetailsImpl::GetEventData() const {
2503  return v8::Utils::ToLocal(event_data_);
2504}
2505
2506
2507v8::Local<v8::Context> EventDetailsImpl::GetEventContext() const {
2508  return GetDebugEventContext(exec_state_->GetIsolate());
2509}
2510
2511
2512v8::Local<v8::Value> EventDetailsImpl::GetCallbackData() const {
2513  return v8::Utils::ToLocal(callback_data_);
2514}
2515
2516
2517v8::Debug::ClientData* EventDetailsImpl::GetClientData() const {
2518  return client_data_;
2519}
2520
2521v8::Isolate* EventDetailsImpl::GetIsolate() const {
2522  return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate());
2523}
2524
2525CommandMessage::CommandMessage() : text_(Vector<uint16_t>::empty()),
2526                                   client_data_(NULL) {
2527}
2528
2529
2530CommandMessage::CommandMessage(const Vector<uint16_t>& text,
2531                               v8::Debug::ClientData* data)
2532    : text_(text),
2533      client_data_(data) {
2534}
2535
2536
2537void CommandMessage::Dispose() {
2538  text_.Dispose();
2539  delete client_data_;
2540  client_data_ = NULL;
2541}
2542
2543
2544CommandMessage CommandMessage::New(const Vector<uint16_t>& command,
2545                                   v8::Debug::ClientData* data) {
2546  return CommandMessage(command.Clone(), data);
2547}
2548
2549
2550CommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0),
2551                                                     size_(size) {
2552  messages_ = NewArray<CommandMessage>(size);
2553}
2554
2555
2556CommandMessageQueue::~CommandMessageQueue() {
2557  while (!IsEmpty()) Get().Dispose();
2558  DeleteArray(messages_);
2559}
2560
2561
2562CommandMessage CommandMessageQueue::Get() {
2563  DCHECK(!IsEmpty());
2564  int result = start_;
2565  start_ = (start_ + 1) % size_;
2566  return messages_[result];
2567}
2568
2569
2570void CommandMessageQueue::Put(const CommandMessage& message) {
2571  if ((end_ + 1) % size_ == start_) {
2572    Expand();
2573  }
2574  messages_[end_] = message;
2575  end_ = (end_ + 1) % size_;
2576}
2577
2578
2579void CommandMessageQueue::Expand() {
2580  CommandMessageQueue new_queue(size_ * 2);
2581  while (!IsEmpty()) {
2582    new_queue.Put(Get());
2583  }
2584  CommandMessage* array_to_free = messages_;
2585  *this = new_queue;
2586  new_queue.messages_ = array_to_free;
2587  // Make the new_queue empty so that it doesn't call Dispose on any messages.
2588  new_queue.start_ = new_queue.end_;
2589  // Automatic destructor called on new_queue, freeing array_to_free.
2590}
2591
2592
2593LockingCommandMessageQueue::LockingCommandMessageQueue(Logger* logger, int size)
2594    : logger_(logger), queue_(size) {}
2595
2596
2597bool LockingCommandMessageQueue::IsEmpty() const {
2598  base::LockGuard<base::Mutex> lock_guard(&mutex_);
2599  return queue_.IsEmpty();
2600}
2601
2602
2603CommandMessage LockingCommandMessageQueue::Get() {
2604  base::LockGuard<base::Mutex> lock_guard(&mutex_);
2605  CommandMessage result = queue_.Get();
2606  logger_->DebugEvent("Get", result.text());
2607  return result;
2608}
2609
2610
2611void LockingCommandMessageQueue::Put(const CommandMessage& message) {
2612  base::LockGuard<base::Mutex> lock_guard(&mutex_);
2613  queue_.Put(message);
2614  logger_->DebugEvent("Put", message.text());
2615}
2616
2617
2618void LockingCommandMessageQueue::Clear() {
2619  base::LockGuard<base::Mutex> lock_guard(&mutex_);
2620  queue_.Clear();
2621}
2622
2623}  // namespace internal
2624}  // namespace v8
2625