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