LCOV - code coverage report
Current view: top level - src/debug - debug.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1013 1038 97.6 %
Date: 2017-04-26 Functions: 127 136 93.4 %

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

Generated by: LCOV version 1.10