LCOV - code coverage report
Current view: top level - src/debug - debug.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1009 1032 97.8 %
Date: 2019-01-20 Functions: 116 120 96.7 %

          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             : #include <unordered_set>
       9             : 
      10             : #include "src/api-inl.h"
      11             : #include "src/arguments.h"
      12             : #include "src/assembler-inl.h"
      13             : #include "src/base/platform/mutex.h"
      14             : #include "src/bootstrapper.h"
      15             : #include "src/builtins/builtins.h"
      16             : #include "src/compilation-cache.h"
      17             : #include "src/compiler.h"
      18             : #include "src/counters.h"
      19             : #include "src/debug/debug-evaluate.h"
      20             : #include "src/debug/liveedit.h"
      21             : #include "src/deoptimizer.h"
      22             : #include "src/execution.h"
      23             : #include "src/frames-inl.h"
      24             : #include "src/global-handles.h"
      25             : #include "src/globals.h"
      26             : #include "src/interpreter/bytecode-array-accessor.h"
      27             : #include "src/interpreter/bytecode-array-iterator.h"
      28             : #include "src/interpreter/interpreter.h"
      29             : #include "src/isolate-inl.h"
      30             : #include "src/log.h"
      31             : #include "src/message-template.h"
      32             : #include "src/objects/api-callbacks-inl.h"
      33             : #include "src/objects/debug-objects-inl.h"
      34             : #include "src/objects/js-generator-inl.h"
      35             : #include "src/objects/js-promise-inl.h"
      36             : #include "src/objects/slots.h"
      37             : #include "src/snapshot/natives.h"
      38             : #include "src/snapshot/snapshot.h"
      39             : #include "src/wasm/wasm-objects-inl.h"
      40             : 
      41             : namespace v8 {
      42             : namespace internal {
      43             : 
      44             : class Debug::TemporaryObjectsTracker : public HeapObjectAllocationTracker {
      45             :  public:
      46       24294 :   TemporaryObjectsTracker() = default;
      47       24294 :   ~TemporaryObjectsTracker() override = default;
      48             : 
      49      127722 :   void AllocationEvent(Address addr, int) override { objects_.insert(addr); }
      50             : 
      51      123074 :   void MoveEvent(Address from, Address to, int) override {
      52      123074 :     if (from == to) return;
      53      123078 :     base::MutexGuard guard(&mutex_);
      54             :     auto it = objects_.find(from);
      55      123113 :     if (it == objects_.end()) {
      56             :       // If temporary object was collected we can get MoveEvent which moves
      57             :       // existing non temporary object to the address where we had temporary
      58             :       // object. So we should mark new address as non temporary.
      59             :       objects_.erase(to);
      60             :       return;
      61             :     }
      62             :     objects_.erase(it);
      63             :     objects_.insert(to);
      64             :   }
      65             : 
      66        3319 :   bool HasObject(Handle<HeapObject> obj) const {
      67       13227 :     if (obj->IsJSObject() &&
      68        9859 :         Handle<JSObject>::cast(obj)->GetEmbedderFieldCount()) {
      69             :       // Embedder may store any pointers using embedder fields and implements
      70             :       // non trivial logic, e.g. create wrappers lazily and store pointer to
      71             :       // native object inside embedder field. We should consider all objects
      72             :       // with embedder fields as non temporary.
      73             :       return false;
      74             :     }
      75        6638 :     return objects_.find(obj->address()) != objects_.end();
      76             :   }
      77             : 
      78             :  private:
      79             :   std::unordered_set<Address> objects_;
      80             :   base::Mutex mutex_;
      81             :   DISALLOW_COPY_AND_ASSIGN(TemporaryObjectsTracker);
      82             : };
      83             : 
      84       62883 : Debug::Debug(Isolate* isolate)
      85             :     : is_active_(false),
      86             :       hook_on_function_call_(false),
      87             :       is_suppressed_(false),
      88             :       break_disabled_(false),
      89             :       break_points_active_(true),
      90             :       break_on_exception_(false),
      91             :       break_on_uncaught_exception_(false),
      92             :       side_effect_check_failed_(false),
      93             :       debug_info_list_(nullptr),
      94             :       feature_tracker_(isolate),
      95      125766 :       isolate_(isolate) {
      96       62883 :   ThreadInit();
      97       62883 : }
      98             : 
      99      125734 : Debug::~Debug() { DCHECK_NULL(debug_delegate_); }
     100             : 
     101      306954 : BreakLocation BreakLocation::FromFrame(Handle<DebugInfo> debug_info,
     102             :                                        JavaScriptFrame* frame) {
     103      306954 :   if (debug_info->CanBreakAtEntry()) {
     104             :     return BreakLocation(Debug::kBreakAtEntryPosition, DEBUG_BREAK_AT_ENTRY);
     105             :   }
     106      306484 :   auto summary = FrameSummary::GetTop(frame).AsJavaScript();
     107             :   int offset = summary.code_offset();
     108      306484 :   Handle<AbstractCode> abstract_code = summary.abstract_code();
     109      306484 :   BreakIterator it(debug_info);
     110      306484 :   it.SkipTo(BreakIndexFromCodeOffset(debug_info, abstract_code, offset));
     111      306484 :   return it.GetBreakLocation();
     112             : }
     113             : 
     114       62198 : void BreakLocation::AllAtCurrentStatement(
     115             :     Handle<DebugInfo> debug_info, JavaScriptFrame* frame,
     116             :     std::vector<BreakLocation>* result_out) {
     117             :   DCHECK(!debug_info->CanBreakAtEntry());
     118       62198 :   auto summary = FrameSummary::GetTop(frame).AsJavaScript();
     119             :   int offset = summary.code_offset();
     120             :   Handle<AbstractCode> abstract_code = summary.abstract_code();
     121      124396 :   if (abstract_code->IsCode()) offset = offset - 1;
     122             :   int statement_position;
     123             :   {
     124       62198 :     BreakIterator it(debug_info);
     125       62198 :     it.SkipTo(BreakIndexFromCodeOffset(debug_info, abstract_code, offset));
     126       62198 :     statement_position = it.statement_position();
     127             :   }
     128      503486 :   for (BreakIterator it(debug_info); !it.Done(); it.Next()) {
     129      189545 :     if (it.statement_position() == statement_position) {
     130      244336 :       result_out->push_back(it.GetBreakLocation());
     131             :     }
     132             :   }
     133       62198 : }
     134             : 
     135         276 : JSGeneratorObject BreakLocation::GetGeneratorObjectForSuspendedFrame(
     136             :     JavaScriptFrame* frame) const {
     137             :   DCHECK(IsSuspend());
     138             :   DCHECK_GE(generator_obj_reg_index_, 0);
     139             : 
     140             :   Object generator_obj = InterpretedFrame::cast(frame)->ReadInterpreterRegister(
     141         276 :       generator_obj_reg_index_);
     142             : 
     143         276 :   return JSGeneratorObject::cast(generator_obj);
     144             : }
     145             : 
     146      368682 : int BreakLocation::BreakIndexFromCodeOffset(Handle<DebugInfo> debug_info,
     147             :                                             Handle<AbstractCode> abstract_code,
     148             :                                             int offset) {
     149             :   // Run through all break points to locate the one closest to the address.
     150             :   int closest_break = 0;
     151             :   int distance = kMaxInt;
     152             :   DCHECK(0 <= offset && offset < abstract_code->Size());
     153    24438246 :   for (BreakIterator it(debug_info); !it.Done(); it.Next()) {
     154             :     // Check if this break point is closer that what was previously found.
     155    12218252 :     if (it.code_offset() <= offset && offset - it.code_offset() < distance) {
     156    12215870 :       closest_break = it.break_index();
     157    12215870 :       distance = offset - it.code_offset();
     158             :       // Check whether we can't get any closer.
     159    12215870 :       if (distance == 0) break;
     160             :     }
     161             :   }
     162      368682 :   return closest_break;
     163             : }
     164             : 
     165      186885 : bool BreakLocation::HasBreakPoint(Isolate* isolate,
     166             :                                   Handle<DebugInfo> debug_info) const {
     167             :   // First check whether there is a break point with the same source position.
     168      373770 :   if (!debug_info->HasBreakPoint(isolate, position_)) return false;
     169        4265 :   if (debug_info->CanBreakAtEntry()) {
     170             :     DCHECK_EQ(Debug::kBreakAtEntryPosition, position_);
     171         470 :     return debug_info->BreakAtEntry();
     172             :   } else {
     173             :     // Then check whether a break point at that source position would have
     174             :     // the same code offset. Otherwise it's just a break location that we can
     175             :     // step to, but not actually a location where we can put a break point.
     176             :     DCHECK(abstract_code_->IsBytecodeArray());
     177        3795 :     BreakIterator it(debug_info);
     178        3795 :     it.SkipToPosition(position_);
     179        3795 :     return it.code_offset() == code_offset_;
     180             :   }
     181             : }
     182             : 
     183        5050 : debug::BreakLocationType BreakLocation::type() const {
     184        5050 :   switch (type_) {
     185             :     case DEBUGGER_STATEMENT:
     186             :       return debug::kDebuggerStatementBreakLocation;
     187             :     case DEBUG_BREAK_SLOT_AT_CALL:
     188             :       return debug::kCallBreakLocation;
     189             :     case DEBUG_BREAK_SLOT_AT_RETURN:
     190             :       return debug::kReturnBreakLocation;
     191             : 
     192             :     // Externally, suspend breaks should look like normal breaks.
     193             :     case DEBUG_BREAK_SLOT_AT_SUSPEND:
     194             :     default:
     195             :       return debug::kCommonBreakLocation;
     196             :   }
     197             : }
     198             : 
     199     2136848 : BreakIterator::BreakIterator(Handle<DebugInfo> debug_info)
     200             :     : debug_info_(debug_info),
     201             :       break_index_(-1),
     202             :       source_position_iterator_(
     203     4273696 :           debug_info->DebugBytecodeArray()->SourcePositionTable()) {
     204     2136848 :   position_ = debug_info->shared()->StartPosition();
     205     2136848 :   statement_position_ = position_;
     206             :   // There is at least one break location.
     207             :   DCHECK(!Done());
     208     2136848 :   Next();
     209     2136848 : }
     210             : 
     211      258705 : int BreakIterator::BreakIndexFromPosition(int source_position) {
     212             :   int distance = kMaxInt;
     213             :   int closest_break = break_index();
     214      186137 :   while (!Done()) {
     215             :     int next_position = position();
     216      195247 :     if (source_position <= next_position &&
     217       84366 :         next_position - source_position < distance) {
     218             :       closest_break = break_index();
     219             :       distance = next_position - source_position;
     220             :       // Check whether we can't get any closer.
     221       74239 :       if (distance == 0) break;
     222             :     }
     223       38967 :     Next();
     224             :   }
     225       73585 :   return closest_break;
     226             : }
     227             : 
     228    40810069 : void BreakIterator::Next() {
     229             :   DisallowHeapAllocation no_gc;
     230             :   DCHECK(!Done());
     231    40810069 :   bool first = break_index_ == -1;
     232   100931266 :   while (!Done()) {
     233   177853879 :     if (!first) source_position_iterator_.Advance();
     234             :     first = false;
     235   100931266 :     if (Done()) return;
     236    58866341 :     position_ = source_position_iterator_.source_position().ScriptOffset();
     237    58866341 :     if (source_position_iterator_.is_statement()) {
     238    38029574 :       statement_position_ = position_;
     239             :     }
     240             :     DCHECK_LE(0, position_);
     241             :     DCHECK_LE(0, statement_position_);
     242             : 
     243    58866341 :     DebugBreakType type = GetDebugBreakType();
     244    58866341 :     if (type != NOT_DEBUG_BREAK) break;
     245             :   }
     246    39555213 :   break_index_++;
     247             : }
     248             : 
     249    74082767 : DebugBreakType BreakIterator::GetDebugBreakType() {
     250    74082767 :   BytecodeArray bytecode_array = debug_info_->OriginalBytecodeArray();
     251             :   interpreter::Bytecode bytecode =
     252             :       interpreter::Bytecodes::FromByte(bytecode_array->get(code_offset()));
     253             : 
     254             :   // Make sure we read the actual bytecode, not a prefix scaling bytecode.
     255    74082767 :   if (interpreter::Bytecodes::IsPrefixScalingBytecode(bytecode)) {
     256             :     bytecode = interpreter::Bytecodes::FromByte(
     257    19892016 :         bytecode_array->get(code_offset() + 1));
     258             :   }
     259             : 
     260    74082767 :   if (bytecode == interpreter::Bytecode::kDebugger) {
     261             :     return DEBUGGER_STATEMENT;
     262    72718338 :   } else if (bytecode == interpreter::Bytecode::kReturn) {
     263             :     return DEBUG_BREAK_SLOT_AT_RETURN;
     264    70092203 :   } else if (bytecode == interpreter::Bytecode::kSuspendGenerator) {
     265             :     return DEBUG_BREAK_SLOT_AT_SUSPEND;
     266    70017433 :   } else if (interpreter::Bytecodes::IsCallOrConstruct(bytecode)) {
     267             :     return DEBUG_BREAK_SLOT_AT_CALL;
     268    67519161 :   } else if (source_position_iterator_.is_statement()) {
     269             :     return DEBUG_BREAK_SLOT;
     270             :   } else {
     271    19311128 :     return NOT_DEBUG_BREAK;
     272             :   }
     273             : }
     274             : 
     275       73585 : void BreakIterator::SkipToPosition(int position) {
     276       73585 :   BreakIterator it(debug_info_);
     277       73585 :   SkipTo(it.BreakIndexFromPosition(position));
     278       73585 : }
     279             : 
     280     3817765 : void BreakIterator::SetDebugBreak() {
     281     3817765 :   DebugBreakType debug_break_type = GetDebugBreakType();
     282     3837669 :   if (debug_break_type == DEBUGGER_STATEMENT) return;
     283     3797861 :   HandleScope scope(isolate());
     284             :   DCHECK(debug_break_type >= DEBUG_BREAK_SLOT);
     285             :   Handle<BytecodeArray> bytecode_array(debug_info_->DebugBytecodeArray(),
     286    11393583 :                                        isolate());
     287             :   interpreter::BytecodeArrayAccessor(bytecode_array, code_offset())
     288     3797861 :       .ApplyDebugBreak();
     289             : }
     290             : 
     291    10962616 : void BreakIterator::ClearDebugBreak() {
     292    10962616 :   DebugBreakType debug_break_type = GetDebugBreakType();
     293    11540319 :   if (debug_break_type == DEBUGGER_STATEMENT) return;
     294             :   DCHECK(debug_break_type >= DEBUG_BREAK_SLOT);
     295    10384913 :   BytecodeArray bytecode_array = debug_info_->DebugBytecodeArray();
     296    10384913 :   BytecodeArray original = debug_info_->OriginalBytecodeArray();
     297             :   bytecode_array->set(code_offset(), original->get(code_offset()));
     298             : }
     299             : 
     300      436045 : BreakLocation BreakIterator::GetBreakLocation() {
     301             :   Handle<AbstractCode> code(
     302     1308135 :       AbstractCode::cast(debug_info_->DebugBytecodeArray()), isolate());
     303      436045 :   DebugBreakType type = GetDebugBreakType();
     304             :   int generator_object_reg_index = -1;
     305      436045 :   if (type == DEBUG_BREAK_SLOT_AT_SUSPEND) {
     306             :     // For suspend break, we'll need the generator object to be able to step
     307             :     // over the suspend as if it didn't return. We get the interpreter register
     308             :     // index that holds the generator object by reading it directly off the
     309             :     // bytecode array, and we'll read the actual generator object off the
     310             :     // interpreter stack frame in GetGeneratorObjectForSuspendedFrame.
     311         717 :     BytecodeArray bytecode_array = debug_info_->OriginalBytecodeArray();
     312             :     interpreter::BytecodeArrayAccessor accessor(
     313        1434 :         handle(bytecode_array, isolate()), code_offset());
     314             : 
     315             :     DCHECK_EQ(accessor.current_bytecode(),
     316             :               interpreter::Bytecode::kSuspendGenerator);
     317         717 :     interpreter::Register generator_obj_reg = accessor.GetRegisterOperand(0);
     318             :     generator_object_reg_index = generator_obj_reg.index();
     319             :   }
     320             :   return BreakLocation(code, type, code_offset(), position_,
     321      872090 :                        generator_object_reg_index);
     322             : }
     323             : 
     324    16064968 : Isolate* BreakIterator::isolate() { return debug_info_->GetIsolate(); }
     325             : 
     326       69449 : void DebugFeatureTracker::Track(DebugFeatureTracker::Feature feature) {
     327       69449 :   uint32_t mask = 1 << feature;
     328             :   // Only count one sample per feature and isolate.
     329      138898 :   if (bitfield_ & mask) return;
     330        9536 :   isolate_->counters()->debug_feature_usage()->AddSample(feature);
     331        4768 :   bitfield_ |= mask;
     332             : }
     333             : 
     334             : 
     335             : // Threading support.
     336       74719 : void Debug::ThreadInit() {
     337       74719 :   thread_local_.break_frame_id_ = StackFrame::NO_ID;
     338       74719 :   thread_local_.last_step_action_ = StepNone;
     339       74719 :   thread_local_.last_statement_position_ = kNoSourcePosition;
     340       74719 :   thread_local_.last_frame_count_ = -1;
     341       74719 :   thread_local_.fast_forward_to_return_ = false;
     342       74719 :   thread_local_.ignore_step_into_function_ = Smi::kZero;
     343       74719 :   thread_local_.target_frame_count_ = -1;
     344       74719 :   thread_local_.return_value_ = Smi::kZero;
     345       74719 :   thread_local_.last_breakpoint_id_ = 0;
     346             :   clear_suspended_generator();
     347       74719 :   thread_local_.restart_fp_ = kNullAddress;
     348             :   base::Relaxed_Store(&thread_local_.current_debug_scope_,
     349       74719 :                       static_cast<base::AtomicWord>(0));
     350       74719 :   thread_local_.break_on_next_function_call_ = false;
     351             :   UpdateHookOnFunctionCall();
     352       74719 : }
     353             : 
     354             : 
     355       24256 : char* Debug::ArchiveDebug(char* storage) {
     356             :   MemCopy(storage, reinterpret_cast<char*>(&thread_local_),
     357       24256 :           ArchiveSpacePerThread());
     358       24256 :   return storage + ArchiveSpacePerThread();
     359             : }
     360             : 
     361       24256 : char* Debug::RestoreDebug(char* storage) {
     362             :   MemCopy(reinterpret_cast<char*>(&thread_local_), storage,
     363       24256 :           ArchiveSpacePerThread());
     364             : 
     365             :   // Enter the debugger.
     366       24256 :   DebugScope debug_scope(this);
     367             : 
     368             :   // Clear any one-shot breakpoints that may have been set by the other
     369             :   // thread, and reapply breakpoints for this thread.
     370       24256 :   ClearOneShot();
     371             : 
     372       24256 :   if (thread_local_.last_step_action_ != StepNone) {
     373             :     // Reset the previous step action for this thread.
     374          20 :     PrepareStep(thread_local_.last_step_action_);
     375             :   }
     376             : 
     377       24256 :   return storage + ArchiveSpacePerThread();
     378             : }
     379             : 
     380        1111 : int Debug::ArchiveSpacePerThread() { return sizeof(ThreadLocal); }
     381             : 
     382      307250 : void Debug::Iterate(RootVisitor* v) {
     383             :   v->VisitRootPointer(Root::kDebug, nullptr,
     384      614500 :                       FullObjectSlot(&thread_local_.return_value_));
     385             :   v->VisitRootPointer(Root::kDebug, nullptr,
     386      614500 :                       FullObjectSlot(&thread_local_.suspended_generator_));
     387             :   v->VisitRootPointer(
     388             :       Root::kDebug, nullptr,
     389      614500 :       FullObjectSlot(&thread_local_.ignore_step_into_function_));
     390      307250 : }
     391             : 
     392       57528 : DebugInfoListNode::DebugInfoListNode(Isolate* isolate, DebugInfo debug_info)
     393       28764 :     : next_(nullptr) {
     394             :   // Globalize the request debug info object and make it weak.
     395             :   GlobalHandles* global_handles = isolate->global_handles();
     396       28764 :   debug_info_ = global_handles->Create(debug_info).location();
     397       28764 : }
     398             : 
     399           0 : DebugInfoListNode::~DebugInfoListNode() {
     400       28764 :   if (debug_info_ == nullptr) return;
     401       28764 :   GlobalHandles::Destroy(debug_info_);
     402       28764 :   debug_info_ = nullptr;
     403           0 : }
     404             : 
     405       66774 : void Debug::Unload() {
     406       66774 :   ClearAllBreakPoints();
     407       66773 :   ClearStepping();
     408       66774 :   RemoveAllCoverageInfos();
     409       66774 :   ClearAllDebuggerHints();
     410       66773 :   debug_delegate_ = nullptr;
     411       66773 : }
     412             : 
     413      250556 : void Debug::Break(JavaScriptFrame* frame, Handle<JSFunction> break_target) {
     414             :   // Initialize LiveEdit.
     415       64848 :   LiveEdit::InitializeThreadLocal(this);
     416             : 
     417             :   // Just continue if breaks are disabled or debugger cannot be loaded.
     418       71220 :   if (break_disabled()) return;
     419             : 
     420             :   // Enter the debugger.
     421       64830 :   DebugScope debug_scope(this);
     422             :   DisableBreak no_recursive_break(this);
     423             : 
     424             :   // Return if we fail to retrieve debug info.
     425      194490 :   Handle<SharedFunctionInfo> shared(break_target->shared(), isolate_);
     426       64830 :   if (!EnsureBreakInfo(shared)) return;
     427       64830 :   PrepareFunctionForDebugExecution(shared);
     428             : 
     429      194490 :   Handle<DebugInfo> debug_info(shared->GetDebugInfo(), isolate_);
     430             : 
     431             :   // Find the break location where execution has stopped.
     432       64830 :   BreakLocation location = BreakLocation::FromFrame(debug_info, frame);
     433             : 
     434             :   // Find actual break points, if any, and trigger debug break event.
     435             :   MaybeHandle<FixedArray> break_points_hit =
     436       64830 :       CheckBreakPoints(debug_info, &location);
     437      126055 :   if (!break_points_hit.is_null() || break_on_next_function_call()) {
     438             :     // Clear all current stepping setup.
     439        5160 :     ClearStepping();
     440             :     // Notify the debug event listeners.
     441             :     OnDebugBreak(!break_points_hit.is_null()
     442             :                      ? break_points_hit.ToHandleChecked()
     443       11875 :                      : isolate_->factory()->empty_fixed_array());
     444        5160 :     return;
     445             :   }
     446             : 
     447             :   // Debug break at function entry, do not worry about stepping.
     448       59670 :   if (location.IsDebugBreakAtEntry()) {
     449             :     DCHECK(debug_info->BreakAtEntry());
     450             :     return;
     451             :   }
     452             : 
     453             :   DCHECK_NOT_NULL(frame);
     454             : 
     455             :   // No break point. Check for stepping.
     456             :   StepAction step_action = last_step_action();
     457       59635 :   int current_frame_count = CurrentFrameCount();
     458       59635 :   int target_frame_count = thread_local_.target_frame_count_;
     459       59635 :   int last_frame_count = thread_local_.last_frame_count_;
     460             : 
     461             :   // StepOut at not return position was requested and return break locations
     462             :   // were flooded with one shots.
     463       59635 :   if (thread_local_.fast_forward_to_return_) {
     464             :     DCHECK(location.IsReturnOrSuspend());
     465             :     // We have to ignore recursive calls to function.
     466         433 :     if (current_frame_count > target_frame_count) return;
     467         386 :     ClearStepping();
     468         386 :     PrepareStep(StepOut);
     469         386 :     return;
     470             :   }
     471             : 
     472             :   bool step_break = false;
     473       59202 :   switch (step_action) {
     474             :     case StepNone:
     475             :       return;
     476             :     case StepOut:
     477             :       // Step out should not break in a deeper frame than target frame.
     478           5 :       if (current_frame_count > target_frame_count) return;
     479             :       step_break = true;
     480             :       break;
     481             :     case StepNext:
     482             :       // Step next should not break in a deeper frame than target frame.
     483        8789 :       if (current_frame_count > target_frame_count) return;
     484             :       V8_FALLTHROUGH;
     485             :     case StepIn: {
     486             :       // Special case "next" and "in" for generators that are about to suspend.
     487       58747 :       if (location.IsSuspend()) {
     488             :         DCHECK(!has_suspended_generator());
     489             :         thread_local_.suspended_generator_ =
     490         276 :             location.GetGeneratorObjectForSuspendedFrame(frame);
     491         276 :         ClearStepping();
     492         276 :         return;
     493             :       }
     494             : 
     495       58471 :       FrameSummary summary = FrameSummary::GetTop(frame);
     496       58471 :       step_break = step_break || location.IsReturn() ||
     497       46395 :                    current_frame_count != last_frame_count ||
     498       46395 :                    thread_local_.last_statement_position_ !=
     499       46395 :                        summary.SourceStatementPosition();
     500       58471 :       break;
     501             :     }
     502             :   }
     503             : 
     504             :   // Clear all current stepping setup.
     505       58476 :   ClearStepping();
     506             : 
     507       58476 :   if (step_break) {
     508             :     // Notify the debug event listeners.
     509      107500 :     OnDebugBreak(isolate_->factory()->empty_fixed_array());
     510             :   } else {
     511             :     // Re-prepare to continue.
     512        4726 :     PrepareStep(step_action);
     513       58476 :   }
     514             : }
     515             : 
     516             : 
     517             : // Find break point objects for this location, if any, and evaluate them.
     518             : // Return an array of break point objects that evaluated true, or an empty
     519             : // handle if none evaluated true.
     520      186998 : MaybeHandle<FixedArray> Debug::CheckBreakPoints(Handle<DebugInfo> debug_info,
     521        4179 :                                                 BreakLocation* location,
     522             :                                                 bool* has_break_points) {
     523             :   bool has_break_points_to_check =
     524      186998 :       break_points_active_ && location->HasBreakPoint(isolate_, debug_info);
     525      186998 :   if (has_break_points) *has_break_points = has_break_points_to_check;
     526      186998 :   if (!has_break_points_to_check) return {};
     527             : 
     528        4179 :   return Debug::GetHitBreakPoints(debug_info, location->position());
     529             : }
     530             : 
     531             : 
     532       70515 : bool Debug::IsMutedAtCurrentLocation(JavaScriptFrame* frame) {
     533       70515 :   HandleScope scope(isolate_);
     534             :   // A break location is considered muted if break locations on the current
     535             :   // statement have at least one break point, and all of these break points
     536             :   // evaluate to false. Aside from not triggering a debug break event at the
     537             :   // break location, we also do not trigger one for debugger statements, nor
     538             :   // an exception event on exception at this location.
     539      141030 :   FrameSummary summary = FrameSummary::GetTop(frame);
     540             :   DCHECK(!summary.IsWasm());
     541             :   Handle<JSFunction> function = summary.AsJavaScript().function();
     542       70515 :   if (!function->shared()->HasBreakInfo()) return false;
     543      186594 :   Handle<DebugInfo> debug_info(function->shared()->GetDebugInfo(), isolate_);
     544             :   // Enter the debugger.
     545      124396 :   DebugScope debug_scope(this);
     546             :   std::vector<BreakLocation> break_locations;
     547       62198 :   BreakLocation::AllAtCurrentStatement(debug_info, frame, &break_locations);
     548             :   bool has_break_points_at_all = false;
     549      368590 :   for (size_t i = 0; i < break_locations.size(); i++) {
     550             :     bool has_break_points;
     551             :     MaybeHandle<FixedArray> check_result =
     552      122168 :         CheckBreakPoints(debug_info, &break_locations[i], &has_break_points);
     553      122168 :     has_break_points_at_all |= has_break_points;
     554      122320 :     if (has_break_points && !check_result.is_null()) return false;
     555             :   }
     556             :   return has_break_points_at_all;
     557             : }
     558             : 
     559             : // Check whether a single break point object is triggered.
     560        4274 : bool Debug::CheckBreakPoint(Handle<BreakPoint> break_point,
     561         813 :                             bool is_break_at_entry) {
     562        4274 :   HandleScope scope(isolate_);
     563             : 
     564        8548 :   if (!break_point->condition()->length()) return true;
     565        2694 :   Handle<String> condition(break_point->condition(), isolate_);
     566             :   MaybeHandle<Object> maybe_result;
     567             :   Handle<Object> result;
     568             : 
     569         898 :   if (is_break_at_entry) {
     570          85 :     maybe_result = DebugEvaluate::WithTopmostArguments(isolate_, condition);
     571             :   } else {
     572             :     // Since we call CheckBreakpoint only for deoptimized frame on top of stack,
     573             :     // we can use 0 as index of inlined frame.
     574             :     const int inlined_jsframe_index = 0;
     575             :     const bool throw_on_side_effect = false;
     576             :     maybe_result =
     577             :         DebugEvaluate::Local(isolate_, break_frame_id(), inlined_jsframe_index,
     578         813 :                              condition, throw_on_side_effect);
     579             :   }
     580             : 
     581         898 :   if (!maybe_result.ToHandle(&result)) {
     582          18 :     if (isolate_->has_pending_exception()) {
     583          18 :       isolate_->clear_pending_exception();
     584             :     }
     585             :     return false;
     586             :   }
     587        1760 :   return result->BooleanValue(isolate_);
     588             : }
     589             : 
     590         445 : bool Debug::SetBreakPoint(Handle<JSFunction> function,
     591             :                           Handle<BreakPoint> break_point,
     592             :                           int* source_position) {
     593         445 :   HandleScope scope(isolate_);
     594             : 
     595             :   // Make sure the function is compiled and has set up the debug info.
     596        1335 :   Handle<SharedFunctionInfo> shared(function->shared(), isolate_);
     597         445 :   if (!EnsureBreakInfo(shared)) return false;
     598         445 :   PrepareFunctionForDebugExecution(shared);
     599             : 
     600        1335 :   Handle<DebugInfo> debug_info(shared->GetDebugInfo(), isolate_);
     601             :   // Source positions starts with zero.
     602             :   DCHECK_LE(0, *source_position);
     603             : 
     604             :   // Find the break point and change it.
     605         445 :   *source_position = FindBreakablePosition(debug_info, *source_position);
     606         445 :   DebugInfo::SetBreakPoint(isolate_, debug_info, *source_position, break_point);
     607             :   // At least one active break point now.
     608             :   DCHECK_LT(0, debug_info->GetBreakPointCount(isolate_));
     609             : 
     610         445 :   ClearBreakPoints(debug_info);
     611         445 :   ApplyBreakPoints(debug_info);
     612             : 
     613         445 :   feature_tracker()->Track(DebugFeatureTracker::kBreakPoint);
     614         445 :   return true;
     615             : }
     616             : 
     617        2195 : bool Debug::SetBreakPointForScript(Handle<Script> script,
     618             :                                    Handle<String> condition,
     619             :                                    int* source_position, int* id) {
     620        2195 :   *id = ++thread_local_.last_breakpoint_id_;
     621             :   Handle<BreakPoint> break_point =
     622        2195 :       isolate_->factory()->NewBreakPoint(*id, condition);
     623        2195 :   if (script->type() == Script::TYPE_WASM) {
     624             :     Handle<WasmModuleObject> module_object(
     625         300 :         WasmModuleObject::cast(script->wasm_module_object()), isolate_);
     626             :     return WasmModuleObject::SetBreakPoint(module_object, source_position,
     627         100 :                                            break_point);
     628             :   }
     629             : 
     630        2095 :   HandleScope scope(isolate_);
     631             : 
     632             :   // Obtain shared function info for the function.
     633             :   Handle<Object> result =
     634        2095 :       FindSharedFunctionInfoInScript(script, *source_position);
     635        6285 :   if (result->IsUndefined(isolate_)) return false;
     636             : 
     637             :   // Make sure the function has set up the debug info.
     638        2065 :   Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(result);
     639        2065 :   if (!EnsureBreakInfo(shared)) return false;
     640        2065 :   PrepareFunctionForDebugExecution(shared);
     641             : 
     642             :   // Find position within function. The script position might be before the
     643             :   // source position of the first function.
     644        2065 :   if (shared->StartPosition() > *source_position) {
     645          15 :     *source_position = shared->StartPosition();
     646             :   }
     647             : 
     648        6195 :   Handle<DebugInfo> debug_info(shared->GetDebugInfo(), isolate_);
     649             : 
     650             :   // Find breakable position returns first breakable position after
     651             :   // *source_position, it can return 0 if no break location is found after
     652             :   // *source_position.
     653        2065 :   int breakable_position = FindBreakablePosition(debug_info, *source_position);
     654        2065 :   if (breakable_position < *source_position) return false;
     655        2065 :   *source_position = breakable_position;
     656             : 
     657        2065 :   DebugInfo::SetBreakPoint(isolate_, debug_info, *source_position, break_point);
     658             :   // At least one active break point now.
     659             :   DCHECK_LT(0, debug_info->GetBreakPointCount(isolate_));
     660             : 
     661        2065 :   ClearBreakPoints(debug_info);
     662        2065 :   ApplyBreakPoints(debug_info);
     663             : 
     664        2065 :   feature_tracker()->Track(DebugFeatureTracker::kBreakPoint);
     665        2065 :   return true;
     666             : }
     667             : 
     668        2510 : int Debug::FindBreakablePosition(Handle<DebugInfo> debug_info,
     669             :                                  int source_position) {
     670        2510 :   if (debug_info->CanBreakAtEntry()) {
     671             :     return kBreakAtEntryPosition;
     672             :   } else {
     673             :     DCHECK(debug_info->HasInstrumentedBytecodeArray());
     674        2360 :     BreakIterator it(debug_info);
     675        2360 :     it.SkipToPosition(source_position);
     676        2360 :     return it.position();
     677             :   }
     678             : }
     679             : 
     680     1317593 : void Debug::ApplyBreakPoints(Handle<DebugInfo> debug_info) {
     681             :   DisallowHeapAllocation no_gc;
     682     1317593 :   if (debug_info->CanBreakAtEntry()) {
     683         585 :     debug_info->SetBreakAtEntry();
     684             :   } else {
     685     2634601 :     if (!debug_info->HasInstrumentedBytecodeArray()) return;
     686     1131327 :     FixedArray break_points = debug_info->break_points();
     687    11148358 :     for (int i = 0; i < break_points->length(); i++) {
     688    17703978 :       if (break_points->get(i)->IsUndefined(isolate_)) continue;
     689       68249 :       BreakPointInfo info = BreakPointInfo::cast(break_points->get(i));
     690       68249 :       if (info->GetBreakPointCount(isolate_) == 0) continue;
     691             :       DCHECK(debug_info->HasInstrumentedBytecodeArray());
     692       67430 :       BreakIterator it(debug_info);
     693       67430 :       it.SkipToPosition(info->source_position());
     694       67430 :       it.SetDebugBreak();
     695             :     }
     696             :   }
     697     1131912 :   debug_info->SetDebugExecutionMode(DebugInfo::kBreakpoints);
     698             : }
     699             : 
     700     1345537 : void Debug::ClearBreakPoints(Handle<DebugInfo> debug_info) {
     701     1345537 :   if (debug_info->CanBreakAtEntry()) {
     702         735 :     debug_info->ClearBreakAtEntry();
     703             :   } else {
     704             :     // If we attempt to clear breakpoints but none exist, simply return. This
     705             :     // can happen e.g. CoverageInfos exist but no breakpoints are set.
     706     3831102 :     if (!debug_info->HasInstrumentedBytecodeArray() ||
     707     2486300 :         !debug_info->HasBreakInfo()) {
     708     1345537 :       return;
     709             :     }
     710             : 
     711             :     DisallowHeapAllocation no_gc;
     712    24166080 :     for (BreakIterator it(debug_info); !it.Done(); it.Next()) {
     713    10962616 :       it.ClearDebugBreak();
     714             :     }
     715             :   }
     716             : }
     717             : 
     718        2425 : void Debug::ClearBreakPoint(Handle<BreakPoint> break_point) {
     719        2425 :   HandleScope scope(isolate_);
     720             : 
     721       17033 :   for (DebugInfoListNode* node = debug_info_list_; node != nullptr;
     722             :        node = node->next()) {
     723       12530 :     if (!node->debug_info()->HasBreakInfo()) continue;
     724             :     Handle<Object> result = DebugInfo::FindBreakPointInfo(
     725        7183 :         isolate_, node->debug_info(), break_point);
     726       21549 :     if (result->IsUndefined(isolate_)) continue;
     727             :     Handle<DebugInfo> debug_info = node->debug_info();
     728        2320 :     if (DebugInfo::ClearBreakPoint(isolate_, debug_info, break_point)) {
     729        2320 :       ClearBreakPoints(debug_info);
     730        4640 :       if (debug_info->GetBreakPointCount(isolate_) == 0) {
     731        1791 :         RemoveBreakInfoAndMaybeFree(debug_info);
     732             :       } else {
     733         529 :         ApplyBreakPoints(debug_info);
     734             :       }
     735        4745 :       return;
     736             :     }
     737             :   }
     738             : }
     739             : 
     740         170 : int Debug::GetFunctionDebuggingId(Handle<JSFunction> function) {
     741         510 :   Handle<SharedFunctionInfo> shared = handle(function->shared(), isolate_);
     742         170 :   Handle<DebugInfo> debug_info = GetOrCreateDebugInfo(shared);
     743         170 :   int id = debug_info->debugging_id();
     744         170 :   if (id == DebugInfo::kNoDebuggingId) {
     745          55 :     id = isolate_->heap()->NextDebuggingId();
     746          55 :     debug_info->set_debugging_id(id);
     747             :   }
     748         170 :   return id;
     749             : }
     750             : 
     751          95 : bool Debug::SetBreakpointForFunction(Handle<JSFunction> function,
     752             :                                      Handle<String> condition, int* id) {
     753          95 :   *id = ++thread_local_.last_breakpoint_id_;
     754             :   Handle<BreakPoint> breakpoint =
     755          95 :       isolate_->factory()->NewBreakPoint(*id, condition);
     756          95 :   int source_position = 0;
     757          95 :   return SetBreakPoint(function, breakpoint, &source_position);
     758             : }
     759             : 
     760        2250 : void Debug::RemoveBreakpoint(int id) {
     761             :   Handle<BreakPoint> breakpoint = isolate_->factory()->NewBreakPoint(
     762        4500 :       id, isolate_->factory()->empty_string());
     763        2250 :   ClearBreakPoint(breakpoint);
     764        2250 : }
     765             : 
     766             : // Clear out all the debug break code.
     767       66774 : void Debug::ClearAllBreakPoints() {
     768       26502 :   ClearAllDebugInfos([=](Handle<DebugInfo> info) {
     769       26502 :     ClearBreakPoints(info);
     770       53004 :     info->ClearBreakInfo(isolate_);
     771      160049 :   });
     772       66773 : }
     773             : 
     774       68287 : void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared,
     775             :                              bool returns_only) {
     776       68292 :   if (IsBlackboxed(shared)) return;
     777             :   // Make sure the function is compiled and has set up the debug info.
     778       68282 :   if (!EnsureBreakInfo(shared)) return;
     779       68282 :   PrepareFunctionForDebugExecution(shared);
     780             : 
     781      204846 :   Handle<DebugInfo> debug_info(shared->GetDebugInfo(), isolate_);
     782             :   // Flood the function with break points.
     783             :   DCHECK(debug_info->HasInstrumentedBytecodeArray());
     784     7639988 :   for (BreakIterator it(debug_info); !it.Done(); it.Next()) {
     785     3754005 :     if (returns_only && !it.GetBreakLocation().IsReturnOrSuspend()) continue;
     786     3750335 :     it.SetDebugBreak();
     787             :   }
     788             : }
     789             : 
     790       14974 : void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) {
     791       14974 :   if (type == BreakUncaughtException) {
     792        7487 :     break_on_uncaught_exception_ = enable;
     793             :   } else {
     794        7487 :     break_on_exception_ = enable;
     795             :   }
     796       14974 : }
     797             : 
     798             : 
     799        3321 : bool Debug::IsBreakOnException(ExceptionBreakType type) {
     800        3321 :   if (type == BreakUncaughtException) {
     801        1080 :     return break_on_uncaught_exception_;
     802             :   } else {
     803        2241 :     return break_on_exception_;
     804             :   }
     805             : }
     806             : 
     807        4179 : MaybeHandle<FixedArray> Debug::GetHitBreakPoints(Handle<DebugInfo> debug_info,
     808             :                                                  int position) {
     809        8358 :   Handle<Object> break_points = debug_info->GetBreakPoints(isolate_, position);
     810        4179 :   bool is_break_at_entry = debug_info->BreakAtEntry();
     811             :   DCHECK(!break_points->IsUndefined(isolate_));
     812        8358 :   if (!break_points->IsFixedArray()) {
     813        4129 :     if (!CheckBreakPoint(Handle<BreakPoint>::cast(break_points),
     814        4129 :                          is_break_at_entry)) {
     815         498 :       return {};
     816             :     }
     817        3631 :     Handle<FixedArray> break_points_hit = isolate_->factory()->NewFixedArray(1);
     818        3631 :     break_points_hit->set(0, *break_points);
     819        3631 :     return break_points_hit;
     820             :   }
     821             : 
     822          50 :   Handle<FixedArray> array(FixedArray::cast(*break_points), isolate_);
     823             :   int num_objects = array->length();
     824             :   Handle<FixedArray> break_points_hit =
     825          50 :       isolate_->factory()->NewFixedArray(num_objects);
     826             :   int break_points_hit_count = 0;
     827         195 :   for (int i = 0; i < num_objects; ++i) {
     828         145 :     Handle<Object> break_point(array->get(i), isolate_);
     829         145 :     if (CheckBreakPoint(Handle<BreakPoint>::cast(break_point),
     830         145 :                         is_break_at_entry)) {
     831         270 :       break_points_hit->set(break_points_hit_count++, *break_point);
     832             :     }
     833             :   }
     834          50 :   if (break_points_hit_count == 0) return {};
     835          90 :   break_points_hit->Shrink(isolate_, break_points_hit_count);
     836          45 :   return break_points_hit;
     837             : }
     838             : 
     839        6615 : void Debug::SetBreakOnNextFunctionCall() {
     840             :   // This method forces V8 to break on next function call regardless current
     841             :   // last_step_action_. If any break happens between SetBreakOnNextFunctionCall
     842             :   // and ClearBreakOnNextFunctionCall, we will clear this flag and stepping. If
     843             :   // break does not happen, e.g. all called functions are blackboxed or no
     844             :   // function is called, then we will clear this flag and let stepping continue
     845             :   // its normal business.
     846        6615 :   thread_local_.break_on_next_function_call_ = true;
     847             :   UpdateHookOnFunctionCall();
     848        6615 : }
     849             : 
     850          30 : void Debug::ClearBreakOnNextFunctionCall() {
     851          30 :   thread_local_.break_on_next_function_call_ = false;
     852             :   UpdateHookOnFunctionCall();
     853          30 : }
     854             : 
     855     1074521 : void Debug::PrepareStepIn(Handle<JSFunction> function) {
     856      533040 :   CHECK(last_step_action() >= StepIn || break_on_next_function_call());
     857     1047259 :   if (ignore_events()) return;
     858      514930 :   if (in_debug_scope()) return;
     859       14332 :   if (break_disabled()) return;
     860       42966 :   Handle<SharedFunctionInfo> shared(function->shared(), isolate_);
     861       14322 :   if (IsBlackboxed(shared)) return;
     862        7064 :   if (*function == thread_local_.ignore_step_into_function_) return;
     863        7039 :   thread_local_.ignore_step_into_function_ = Smi::kZero;
     864       21117 :   FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared(), isolate_));
     865             : }
     866             : 
     867         786 : void Debug::PrepareStepInSuspendedGenerator() {
     868         262 :   CHECK(has_suspended_generator());
     869         262 :   if (ignore_events()) return;
     870         262 :   if (in_debug_scope()) return;
     871         262 :   if (break_disabled()) return;
     872         262 :   thread_local_.last_step_action_ = StepIn;
     873             :   UpdateHookOnFunctionCall();
     874             :   Handle<JSFunction> function(
     875             :       JSGeneratorObject::cast(thread_local_.suspended_generator_)->function(),
     876         786 :       isolate_);
     877         786 :   FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared(), isolate_));
     878             :   clear_suspended_generator();
     879             : }
     880             : 
     881       11090 : void Debug::PrepareStepOnThrow() {
     882       17796 :   if (last_step_action() == StepNone) return;
     883         564 :   if (ignore_events()) return;
     884         564 :   if (in_debug_scope()) return;
     885         564 :   if (break_disabled()) return;
     886             : 
     887         564 :   ClearOneShot();
     888             : 
     889         564 :   int current_frame_count = CurrentFrameCount();
     890             : 
     891             :   // Iterate through the JavaScript stack looking for handlers.
     892         564 :   JavaScriptFrameIterator it(isolate_);
     893        1222 :   while (!it.done()) {
     894             :     JavaScriptFrame* frame = it.frame();
     895         616 :     if (frame->LookupExceptionHandlerInTable(nullptr, nullptr) > 0) break;
     896             :     std::vector<SharedFunctionInfo> infos;
     897          94 :     frame->GetFunctions(&infos);
     898         188 :     current_frame_count -= infos.size();
     899          94 :     it.Advance();
     900             :   }
     901             : 
     902             :   // No handler found. Nothing to instrument.
     903         564 :   if (it.done()) return;
     904             : 
     905             :   bool found_handler = false;
     906             :   // Iterate frames, including inlined frames. First, find the handler frame.
     907             :   // Then skip to the frame we want to break in, then instrument for stepping.
     908         542 :   for (; !it.done(); it.Advance()) {
     909             :     JavaScriptFrame* frame = JavaScriptFrame::cast(it.frame());
     910         532 :     if (last_step_action() == StepIn) {
     911             :       // Deoptimize frame to ensure calls are checked for step-in.
     912         489 :       Deoptimizer::DeoptimizeFunction(frame->function());
     913             :     }
     914             :     std::vector<FrameSummary> summaries;
     915         532 :     frame->Summarize(&summaries);
     916        1081 :     for (size_t i = summaries.size(); i != 0; i--, current_frame_count--) {
     917         539 :       const FrameSummary& summary = summaries[i - 1];
     918         539 :       if (!found_handler) {
     919             :         // We have yet to find the handler. If the frame inlines multiple
     920             :         // functions, we have to check each one for the handler.
     921             :         // If it only contains one function, we already found the handler.
     922        1058 :         if (summaries.size() > 1) {
     923             :           Handle<AbstractCode> code = summary.AsJavaScript().abstract_code();
     924          14 :           CHECK_EQ(AbstractCode::INTERPRETED_FUNCTION, code->kind());
     925          14 :           HandlerTable table(code->GetBytecodeArray());
     926          14 :           int code_offset = summary.code_offset();
     927             :           HandlerTable::CatchPrediction prediction;
     928          14 :           int index = table.LookupRange(code_offset, nullptr, &prediction);
     929          14 :           if (index > 0) found_handler = true;
     930             :         } else {
     931             :           found_handler = true;
     932             :         }
     933             :       }
     934             : 
     935         539 :       if (found_handler) {
     936             :         // We found the handler. If we are stepping next or out, we need to
     937             :         // iterate until we found the suitable target frame to break in.
     938         575 :         if ((last_step_action() == StepNext || last_step_action() == StepOut) &&
     939          43 :             current_frame_count > thread_local_.target_frame_count_) {
     940          10 :           continue;
     941             :         }
     942             :         Handle<SharedFunctionInfo> info(
     943        1566 :             summary.AsJavaScript().function()->shared(), isolate_);
     944         522 :         if (IsBlackboxed(info)) continue;
     945         522 :         FloodWithOneShot(info);
     946         522 :         return;
     947             :       }
     948             :     }
     949          10 :   }
     950             : }
     951             : 
     952             : 
     953      138888 : void Debug::PrepareStep(StepAction step_action) {
     954       61816 :   HandleScope scope(isolate_);
     955             : 
     956             :   DCHECK(in_debug_scope());
     957             : 
     958             :   // Get the frame where the execution has stopped and skip the debug frame if
     959             :   // any. The debug frame will only be present if execution was stopped due to
     960             :   // hitting a break point. In other situations (e.g. unhandled exception) the
     961             :   // debug frame is not present.
     962             :   StackFrame::Id frame_id = break_frame_id();
     963             :   // If there is no JavaScript stack don't do anything.
     964       61816 :   if (frame_id == StackFrame::NO_ID) return;
     965             : 
     966       61816 :   feature_tracker()->Track(DebugFeatureTracker::kStepping);
     967             : 
     968       61816 :   thread_local_.last_step_action_ = step_action;
     969             : 
     970       61816 :   StackTraceFrameIterator frames_it(isolate_, frame_id);
     971             :   StandardFrame* frame = frames_it.frame();
     972             : 
     973             :   // Handle stepping in wasm functions via the wasm interpreter.
     974      123632 :   if (frame->is_wasm()) {
     975             :     // If the top frame is compiled, we cannot step.
     976         455 :     if (frame->is_wasm_compiled()) return;
     977             :     WasmInterpreterEntryFrame* wasm_frame =
     978             :         WasmInterpreterEntryFrame::cast(frame);
     979         455 :     wasm_frame->debug_info()->PrepareStep(step_action);
     980         455 :     return;
     981             :   }
     982             : 
     983             :   JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame);
     984             :   DCHECK(js_frame->function()->IsJSFunction());
     985             : 
     986             :   // Get the debug info (create it if it does not exist).
     987       61361 :   auto summary = FrameSummary::GetTop(frame).AsJavaScript();
     988             :   Handle<JSFunction> function(summary.function());
     989      184083 :   Handle<SharedFunctionInfo> shared(function->shared(), isolate_);
     990       61361 :   if (!EnsureBreakInfo(shared)) return;
     991       61361 :   PrepareFunctionForDebugExecution(shared);
     992             : 
     993      184083 :   Handle<DebugInfo> debug_info(shared->GetDebugInfo(), isolate_);
     994             : 
     995       61361 :   BreakLocation location = BreakLocation::FromFrame(debug_info, js_frame);
     996             : 
     997             :   // Any step at a return is a step-out, and a step-out at a suspend behaves
     998             :   // like a return.
     999       61361 :   if (location.IsReturn() || (location.IsSuspend() && step_action == StepOut)) {
    1000             :     // On StepOut we'll ignore our further calls to current function in
    1001             :     // PrepareStepIn callback.
    1002        5271 :     if (last_step_action() == StepOut) {
    1003         490 :       thread_local_.ignore_step_into_function_ = *function;
    1004             :     }
    1005             :     step_action = StepOut;
    1006        5271 :     thread_local_.last_step_action_ = StepIn;
    1007             :   }
    1008             : 
    1009             :   // We need to schedule DebugOnFunction call callback
    1010             :   UpdateHookOnFunctionCall();
    1011             : 
    1012             :   // A step-next in blackboxed function is a step-out.
    1013       61361 :   if (step_action == StepNext && IsBlackboxed(shared)) step_action = StepOut;
    1014             : 
    1015             :   thread_local_.last_statement_position_ =
    1016       61361 :       summary.abstract_code()->SourceStatementPosition(summary.code_offset());
    1017       61361 :   int current_frame_count = CurrentFrameCount();
    1018       61361 :   thread_local_.last_frame_count_ = current_frame_count;
    1019             :   // No longer perform the current async step.
    1020             :   clear_suspended_generator();
    1021             : 
    1022       61361 :   switch (step_action) {
    1023             :     case StepNone:
    1024           0 :       UNREACHABLE();
    1025             :       break;
    1026             :     case StepOut: {
    1027             :       // Clear last position info. For stepping out it does not matter.
    1028        5676 :       thread_local_.last_statement_position_ = kNoSourcePosition;
    1029        5676 :       thread_local_.last_frame_count_ = -1;
    1030        5676 :       if (!location.IsReturnOrSuspend() && !IsBlackboxed(shared)) {
    1031             :         // At not return position we flood return positions with one shots and
    1032             :         // will repeat StepOut automatically at next break.
    1033         395 :         thread_local_.target_frame_count_ = current_frame_count;
    1034         395 :         thread_local_.fast_forward_to_return_ = true;
    1035         395 :         FloodWithOneShot(shared, true);
    1036         395 :         return;
    1037             :       }
    1038             :       // Skip the current frame, find the first frame we want to step out to
    1039             :       // and deoptimize every frame along the way.
    1040             :       bool in_current_frame = true;
    1041       16483 :       for (; !frames_it.done(); frames_it.Advance()) {
    1042             :         // TODO(clemensh): Implement stepping out from JS to wasm.
    1043       19970 :         if (frames_it.frame()->is_wasm()) continue;
    1044             :         JavaScriptFrame* frame = JavaScriptFrame::cast(frames_it.frame());
    1045        9985 :         if (last_step_action() == StepIn) {
    1046             :           // Deoptimize frame to ensure calls are checked for step-in.
    1047        9965 :           Deoptimizer::DeoptimizeFunction(frame->function());
    1048             :         }
    1049        9985 :         HandleScope scope(isolate_);
    1050             :         std::vector<Handle<SharedFunctionInfo>> infos;
    1051        9985 :         frame->GetFunctions(&infos);
    1052       31172 :         for (; !infos.empty(); current_frame_count--) {
    1053        9985 :           Handle<SharedFunctionInfo> info = infos.back();
    1054             :           infos.pop_back();
    1055        9985 :           if (in_current_frame) {
    1056             :             // We want to skip out, so skip the current frame.
    1057             :             in_current_frame = false;
    1058        5601 :             continue;
    1059             :           }
    1060        4704 :           if (IsBlackboxed(info)) continue;
    1061        4384 :           FloodWithOneShot(info);
    1062        4384 :           thread_local_.target_frame_count_ = current_frame_count;
    1063        4384 :           return;
    1064             :         }
    1065             :       }
    1066             :       break;
    1067             :     }
    1068             :     case StepNext:
    1069        8788 :       thread_local_.target_frame_count_ = current_frame_count;
    1070             :       V8_FALLTHROUGH;
    1071             :     case StepIn:
    1072             :       // TODO(clemensh): Implement stepping from JS into wasm.
    1073       55685 :       FloodWithOneShot(shared);
    1074       55685 :       break;
    1075             :   }
    1076             : }
    1077             : 
    1078             : // Simple function for returning the source positions for active break points.
    1079         567 : Handle<Object> Debug::GetSourceBreakLocations(
    1080             :     Isolate* isolate, Handle<SharedFunctionInfo> shared) {
    1081         567 :   if (!shared->HasBreakInfo()) {
    1082         153 :     return isolate->factory()->undefined_value();
    1083             :   }
    1084             : 
    1085         828 :   Handle<DebugInfo> debug_info(shared->GetDebugInfo(), isolate);
    1086         414 :   if (debug_info->GetBreakPointCount(isolate) == 0) {
    1087           0 :     return isolate->factory()->undefined_value();
    1088             :   }
    1089             :   Handle<FixedArray> locations = isolate->factory()->NewFixedArray(
    1090         414 :       debug_info->GetBreakPointCount(isolate));
    1091             :   int count = 0;
    1092        6210 :   for (int i = 0; i < debug_info->break_points()->length(); ++i) {
    1093        4968 :     if (!debug_info->break_points()->get(i)->IsUndefined(isolate)) {
    1094             :       BreakPointInfo break_point_info =
    1095        1602 :           BreakPointInfo::cast(debug_info->break_points()->get(i));
    1096         801 :       int break_points = break_point_info->GetBreakPointCount(isolate);
    1097         945 :       if (break_points == 0) continue;
    1098         657 :       for (int j = 0; j < break_points; ++j) {
    1099             :         locations->set(count++,
    1100         657 :                        Smi::FromInt(break_point_info->source_position()));
    1101             :       }
    1102             :     }
    1103             :   }
    1104         414 :   return locations;
    1105             : }
    1106             : 
    1107      244105 : void Debug::ClearStepping() {
    1108             :   // Clear the various stepping setup.
    1109      244105 :   ClearOneShot();
    1110             : 
    1111      244106 :   thread_local_.last_step_action_ = StepNone;
    1112      244106 :   thread_local_.last_statement_position_ = kNoSourcePosition;
    1113      244106 :   thread_local_.ignore_step_into_function_ = Smi::kZero;
    1114      244106 :   thread_local_.fast_forward_to_return_ = false;
    1115      244106 :   thread_local_.last_frame_count_ = -1;
    1116      244106 :   thread_local_.target_frame_count_ = -1;
    1117      244106 :   thread_local_.break_on_next_function_call_ = false;
    1118             :   UpdateHookOnFunctionCall();
    1119      244106 : }
    1120             : 
    1121             : 
    1122             : // Clears all the one-shot break points that are currently set. Normally this
    1123             : // function is called each time a break point is hit as one shot break points
    1124             : // are used to support stepping.
    1125      268925 : void Debug::ClearOneShot() {
    1126             :   // The current implementation just runs through all the breakpoints. When the
    1127             :   // last break point for a function is removed that function is automatically
    1128             :   // removed from the list.
    1129     1576745 :   for (DebugInfoListNode* node = debug_info_list_; node != nullptr;
    1130             :        node = node->next()) {
    1131     1307820 :     Handle<DebugInfo> debug_info = node->debug_info();
    1132     1307820 :     ClearBreakPoints(debug_info);
    1133     1307820 :     ApplyBreakPoints(debug_info);
    1134             :   }
    1135      268925 : }
    1136             : 
    1137       10538 : class RedirectActiveFunctions : public ThreadVisitor {
    1138             :  public:
    1139             :   explicit RedirectActiveFunctions(SharedFunctionInfo shared)
    1140       10538 :       : shared_(shared) {
    1141             :     DCHECK(shared->HasBytecodeArray());
    1142             :   }
    1143             : 
    1144       10598 :   void VisitThread(Isolate* isolate, ThreadLocalTop* top) override {
    1145       81060 :     for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) {
    1146             :       JavaScriptFrame* frame = it.frame();
    1147       29932 :       JSFunction function = frame->function();
    1148       88158 :       if (!frame->is_interpreted()) continue;
    1149       54614 :       if (function->shared() != shared_) continue;
    1150             :       InterpretedFrame* interpreted_frame =
    1151             :           reinterpret_cast<InterpretedFrame*>(frame);
    1152        1638 :       BytecodeArray debug_copy = shared_->GetDebugInfo()->DebugBytecodeArray();
    1153        1638 :       interpreted_frame->PatchBytecodeArray(debug_copy);
    1154             :     }
    1155       10598 :   }
    1156             : 
    1157             :  private:
    1158             :   SharedFunctionInfo shared_;
    1159             :   DisallowHeapAllocation no_gc_;
    1160             : };
    1161             : 
    1162       12357 : void Debug::DeoptimizeFunction(Handle<SharedFunctionInfo> shared) {
    1163             :   // Deoptimize all code compiled from this shared function info including
    1164             :   // inlining.
    1165       12357 :   isolate_->AbortConcurrentOptimization(BlockingBehavior::kBlock);
    1166             : 
    1167             :   // TODO(mlippautz): Try to remove this call.
    1168             :   isolate_->heap()->PreciseCollectAllGarbage(
    1169       12357 :       Heap::kNoGCFlags, GarbageCollectionReason::kDebugger);
    1170             : 
    1171             :   bool found_something = false;
    1172       12357 :   Code::OptimizedCodeIterator iterator(isolate_);
    1173             :   do {
    1174       29270 :     Code code = iterator.Next();
    1175       29270 :     if (code.is_null()) break;
    1176       16913 :     if (code->Inlines(*shared)) {
    1177         337 :       code->set_marked_for_deoptimization(true);
    1178             :       found_something = true;
    1179             :     }
    1180             :   } while (true);
    1181             : 
    1182       12357 :   if (found_something) {
    1183             :     // Only go through with the deoptimization if something was found.
    1184         332 :     Deoptimizer::DeoptimizeMarkedCode(isolate_);
    1185       16913 :   }
    1186       12357 : }
    1187             : 
    1188      200939 : void Debug::PrepareFunctionForDebugExecution(
    1189             :     Handle<SharedFunctionInfo> shared) {
    1190             :   // To prepare bytecode for debugging, we already need to have the debug
    1191             :   // info (containing the debug copy) upfront, but since we do not recompile,
    1192             :   // preparing for break points cannot fail.
    1193             :   DCHECK(shared->is_compiled());
    1194             :   DCHECK(shared->HasDebugInfo());
    1195      200939 :   Handle<DebugInfo> debug_info = GetOrCreateDebugInfo(shared);
    1196      401878 :   if (debug_info->flags() & DebugInfo::kPreparedForDebugExecution) return;
    1197             : 
    1198             :   // Make a copy of the bytecode array if available.
    1199             :   Handle<Object> maybe_original_bytecode_array =
    1200       21226 :       isolate_->factory()->undefined_value();
    1201       10688 :   if (shared->HasBytecodeArray()) {
    1202             :     Handle<BytecodeArray> original_bytecode_array =
    1203       31614 :         handle(shared->GetBytecodeArray(), isolate_);
    1204             :     Handle<BytecodeArray> debug_bytecode_array =
    1205       10538 :         isolate_->factory()->CopyBytecodeArray(original_bytecode_array);
    1206       21076 :     debug_info->set_debug_bytecode_array(*debug_bytecode_array);
    1207       10538 :     shared->SetDebugBytecodeArray(*debug_bytecode_array);
    1208             :     maybe_original_bytecode_array = original_bytecode_array;
    1209             :   }
    1210       10688 :   debug_info->set_original_bytecode_array(*maybe_original_bytecode_array);
    1211             : 
    1212       10688 :   if (debug_info->CanBreakAtEntry()) {
    1213             :     // Deopt everything in case the function is inlined anywhere.
    1214         150 :     Deoptimizer::DeoptimizeAll(isolate_);
    1215         150 :     InstallDebugBreakTrampoline();
    1216             :   } else {
    1217       10538 :     DeoptimizeFunction(shared);
    1218             :     // Update PCs on the stack to point to recompiled code.
    1219             :     RedirectActiveFunctions redirect_visitor(*shared);
    1220       10538 :     redirect_visitor.VisitThread(isolate_, isolate_->thread_local_top());
    1221       21076 :     isolate_->thread_manager()->IterateArchivedThreads(&redirect_visitor);
    1222             :   }
    1223             :   debug_info->set_flags(debug_info->flags() |
    1224       10688 :                         DebugInfo::kPreparedForDebugExecution);
    1225             : }
    1226             : 
    1227         295 : void Debug::InstallDebugBreakTrampoline() {
    1228             :   // Check the list of debug infos whether the debug break trampoline needs to
    1229             :   // be installed. If that's the case, iterate the heap for functions to rewire
    1230             :   // to the trampoline.
    1231         295 :   HandleScope scope(isolate_);
    1232             :   // If there is a breakpoint at function entry, we need to install trampoline.
    1233             :   bool needs_to_use_trampoline = false;
    1234             :   // If there we break at entry to an api callback, we need to clear ICs.
    1235             :   bool needs_to_clear_ic = false;
    1236         895 :   for (DebugInfoListNode* current = debug_info_list_; current != nullptr;
    1237             :        current = current->next()) {
    1238         485 :     if (current->debug_info()->CanBreakAtEntry()) {
    1239             :       needs_to_use_trampoline = true;
    1240         155 :       if (current->debug_info()->shared()->IsApiFunction()) {
    1241             :         needs_to_clear_ic = true;
    1242             :         break;
    1243             :       }
    1244             :     }
    1245             :   }
    1246             : 
    1247         590 :   if (!needs_to_use_trampoline) return;
    1248             : 
    1249         155 :   Handle<Code> trampoline = BUILTIN_CODE(isolate_, DebugBreakTrampoline);
    1250             :   std::vector<Handle<JSFunction>> needs_compile;
    1251             :   {
    1252         155 :     HeapIterator iterator(isolate_->heap());
    1253     2258340 :     for (HeapObject obj = iterator.next(); !obj.is_null();
    1254             :          obj = iterator.next()) {
    1255     1420382 :       if (needs_to_clear_ic && obj->IsFeedbackVector()) {
    1256         460 :         FeedbackVector::cast(obj)->ClearSlots(isolate_);
    1257         230 :         continue;
    1258     1128785 :       } else if (obj->IsJSFunction()) {
    1259      104325 :         JSFunction fun = JSFunction::cast(obj);
    1260      104325 :         SharedFunctionInfo shared = fun->shared();
    1261      208490 :         if (!shared->HasDebugInfo()) continue;
    1262         215 :         if (!shared->GetDebugInfo()->CanBreakAtEntry()) continue;
    1263         160 :         if (!fun->is_compiled()) {
    1264           0 :           needs_compile.push_back(handle(fun, isolate_));
    1265             :         } else {
    1266         160 :           fun->set_code(*trampoline);
    1267             :         }
    1268             :       }
    1269         155 :     }
    1270             :   }
    1271             :   // By overwriting the function code with DebugBreakTrampoline, which tailcalls
    1272             :   // to shared code, we bypass CompileLazy. Perform CompileLazy here instead.
    1273         310 :   for (Handle<JSFunction> fun : needs_compile) {
    1274             :     IsCompiledScope is_compiled_scope;
    1275           0 :     Compiler::Compile(fun, Compiler::CLEAR_EXCEPTION, &is_compiled_scope);
    1276             :     DCHECK(is_compiled_scope.is_compiled());
    1277           0 :     fun->set_code(*trampoline);
    1278             :   }
    1279             : }
    1280             : 
    1281             : namespace {
    1282             : template <typename Iterator>
    1283        6610 : void GetBreakablePositions(Iterator* it, int start_position, int end_position,
    1284             :                            std::vector<BreakLocation>* locations) {
    1285        8015 :   while (!it->Done()) {
    1286        5205 :     if (it->position() >= start_position && it->position() < end_position) {
    1287       10100 :       locations->push_back(it->GetBreakLocation());
    1288             :     }
    1289        5205 :     it->Next();
    1290             :   }
    1291        1405 : }
    1292             : 
    1293             : void FindBreakablePositions(Handle<DebugInfo> debug_info, int start_position,
    1294             :                             int end_position,
    1295             :                             std::vector<BreakLocation>* locations) {
    1296             :   DCHECK(debug_info->HasInstrumentedBytecodeArray());
    1297        1405 :   BreakIterator it(debug_info);
    1298        1405 :   GetBreakablePositions(&it, start_position, end_position, locations);
    1299             : }
    1300             : }  // namespace
    1301             : 
    1302         205 : bool Debug::GetPossibleBreakpoints(Handle<Script> script, int start_position,
    1303             :                                    int end_position, bool restrict_to_function,
    1304             :                                    std::vector<BreakLocation>* locations) {
    1305         205 :   if (restrict_to_function) {
    1306             :     Handle<Object> result =
    1307           5 :         FindSharedFunctionInfoInScript(script, start_position);
    1308          15 :     if (result->IsUndefined(isolate_)) return false;
    1309             : 
    1310             :     // Make sure the function has set up the debug info.
    1311             :     Handle<SharedFunctionInfo> shared =
    1312           5 :         Handle<SharedFunctionInfo>::cast(result);
    1313           5 :     if (!EnsureBreakInfo(shared)) return false;
    1314           5 :     PrepareFunctionForDebugExecution(shared);
    1315             : 
    1316          15 :     Handle<DebugInfo> debug_info(shared->GetDebugInfo(), isolate_);
    1317             :     FindBreakablePositions(debug_info, start_position, end_position, locations);
    1318           5 :     return true;
    1319             :   }
    1320             : 
    1321             :   while (true) {
    1322         425 :     HandleScope scope(isolate_);
    1323             :     std::vector<Handle<SharedFunctionInfo>> candidates;
    1324             :     std::vector<IsCompiledScope> compiled_scopes;
    1325         425 :     SharedFunctionInfo::ScriptIterator iterator(isolate_, *script);
    1326        8310 :     for (SharedFunctionInfo info = iterator.Next(); !info.is_null();
    1327             :          info = iterator.Next()) {
    1328        7430 :       if (info->EndPosition() < start_position ||
    1329        3700 :           info->StartPosition() >= end_position) {
    1330             :         continue;
    1331             :       }
    1332        3575 :       if (!info->IsSubjectToDebugging()) continue;
    1333        3575 :       if (!info->is_compiled() && !info->allows_lazy_compilation()) continue;
    1334       10725 :       candidates.push_back(i::handle(info, isolate_));
    1335             :     }
    1336             : 
    1337             :     bool was_compiled = false;
    1338        4420 :     for (const auto& candidate : candidates) {
    1339             :       // Code that cannot be compiled lazily are internal and not debuggable.
    1340             :       DCHECK(candidate->allows_lazy_compilation());
    1341        3575 :       IsCompiledScope is_compiled_scope(candidate->is_compiled_scope());
    1342        3575 :       if (!is_compiled_scope.is_compiled()) {
    1343         850 :         if (!Compiler::Compile(candidate, Compiler::CLEAR_EXCEPTION,
    1344         850 :                                &is_compiled_scope)) {
    1345           5 :           return false;
    1346             :         } else {
    1347             :           was_compiled = true;
    1348             :         }
    1349             :       }
    1350             :       DCHECK(is_compiled_scope.is_compiled());
    1351        3570 :       compiled_scopes.push_back(is_compiled_scope);
    1352        3570 :       if (!EnsureBreakInfo(candidate)) return false;
    1353        3570 :       PrepareFunctionForDebugExecution(candidate);
    1354             :     }
    1355         420 :     if (was_compiled) continue;
    1356             : 
    1357        1790 :     for (const auto& candidate : candidates) {
    1358        1400 :       CHECK(candidate->HasBreakInfo());
    1359        4200 :       Handle<DebugInfo> debug_info(candidate->GetDebugInfo(), isolate_);
    1360             :       FindBreakablePositions(debug_info, start_position, end_position,
    1361             :                              locations);
    1362             :     }
    1363             :     return true;
    1364             :   }
    1365             :   UNREACHABLE();
    1366             : }
    1367             : 
    1368             : class SharedFunctionInfoFinder {
    1369             :  public:
    1370             :   explicit SharedFunctionInfoFinder(int target_position)
    1371             :       : current_start_position_(kNoSourcePosition),
    1372        3328 :         target_position_(target_position) {}
    1373             : 
    1374       15229 :   void NewCandidate(SharedFunctionInfo shared,
    1375             :                     JSFunction closure = JSFunction()) {
    1376       15229 :     if (!shared->IsSubjectToDebugging()) return;
    1377       15024 :     int start_position = shared->function_token_position();
    1378       15024 :     if (start_position == kNoSourcePosition) {
    1379           0 :       start_position = shared->StartPosition();
    1380             :     }
    1381             : 
    1382       15024 :     if (start_position > target_position_) return;
    1383       11328 :     if (target_position_ > shared->EndPosition()) return;
    1384             : 
    1385        6756 :     if (!current_candidate_.is_null()) {
    1386        3943 :       if (current_start_position_ == start_position &&
    1387         485 :           shared->EndPosition() == current_candidate_->EndPosition()) {
    1388             :         // If we already have a matching closure, do not throw it away.
    1389         220 :         if (!current_candidate_closure_.is_null() && closure.is_null()) return;
    1390             :         // If a top-level function contains only one function
    1391             :         // declaration the source for the top-level and the function
    1392             :         // is the same. In that case prefer the non top-level function.
    1393         220 :         if (!current_candidate_->is_toplevel() && shared->is_toplevel()) return;
    1394        6476 :       } else if (start_position < current_start_position_ ||
    1395        3238 :                  current_candidate_->EndPosition() < shared->EndPosition()) {
    1396             :         return;
    1397             :       }
    1398             :     }
    1399             : 
    1400        6756 :     current_start_position_ = start_position;
    1401        6756 :     current_candidate_ = shared;
    1402        6756 :     current_candidate_closure_ = closure;
    1403             :   }
    1404             : 
    1405             :   SharedFunctionInfo Result() { return current_candidate_; }
    1406             : 
    1407             :   JSFunction ResultClosure() { return current_candidate_closure_; }
    1408             : 
    1409             :  private:
    1410             :   SharedFunctionInfo current_candidate_;
    1411             :   JSFunction current_candidate_closure_;
    1412             :   int current_start_position_;
    1413             :   int target_position_;
    1414             :   DisallowHeapAllocation no_gc_;
    1415             : };
    1416             : 
    1417             : 
    1418             : // We need to find a SFI for a literal that may not yet have been compiled yet,
    1419             : // and there may not be a JSFunction referencing it. Find the SFI closest to
    1420             : // the given position, compile it to reveal possible inner SFIs and repeat.
    1421             : // While we are at this, also ensure code with debug break slots so that we do
    1422             : // not have to compile a SFI without JSFunction, which is paifu for those that
    1423             : // cannot be compiled without context (need to find outer compilable SFI etc.)
    1424        2365 : Handle<Object> Debug::FindSharedFunctionInfoInScript(Handle<Script> script,
    1425             :                                                      int position) {
    1426         963 :   for (int iteration = 0;; iteration++) {
    1427             :     // Go through all shared function infos associated with this script to
    1428             :     // find the inner most function containing this position.
    1429             :     // If there is no shared function info for this script at all, there is
    1430             :     // no point in looking for it by walking the heap.
    1431             : 
    1432        3328 :     SharedFunctionInfo shared;
    1433             :     IsCompiledScope is_compiled_scope;
    1434             :     {
    1435             :       SharedFunctionInfoFinder finder(position);
    1436        3328 :       SharedFunctionInfo::ScriptIterator iterator(isolate_, *script);
    1437       37114 :       for (SharedFunctionInfo info = iterator.Next(); !info.is_null();
    1438             :            info = iterator.Next()) {
    1439       15229 :         finder.NewCandidate(info);
    1440             :       }
    1441        3328 :       shared = finder.Result();
    1442        3328 :       if (shared.is_null()) break;
    1443             :       // We found it if it's already compiled.
    1444        3298 :       is_compiled_scope = shared->is_compiled_scope();
    1445        3298 :       if (is_compiled_scope.is_compiled()) {
    1446        2335 :         Handle<SharedFunctionInfo> shared_handle(shared, isolate_);
    1447             :         // If the iteration count is larger than 1, we had to compile the outer
    1448             :         // function in order to create this shared function info. So there can
    1449             :         // be no JSFunction referencing it. We can anticipate creating a debug
    1450             :         // info while bypassing PrepareFunctionForDebugExecution.
    1451        2335 :         if (iteration > 1) {
    1452             :           AllowHeapAllocation allow_before_return;
    1453          55 :           CreateBreakInfo(shared_handle);
    1454             :         }
    1455        2335 :         return shared_handle;
    1456             :       }
    1457             :     }
    1458             :     // If not, compile to reveal inner functions.
    1459         963 :     HandleScope scope(isolate_);
    1460             :     // Code that cannot be compiled lazily are internal and not debuggable.
    1461             :     DCHECK(shared->allows_lazy_compilation());
    1462         963 :     if (!Compiler::Compile(handle(shared, isolate_), Compiler::CLEAR_EXCEPTION,
    1463        1926 :                            &is_compiled_scope)) {
    1464             :       break;
    1465             :     }
    1466         963 :   }
    1467          60 :   return isolate_->factory()->undefined_value();
    1468             : }
    1469             : 
    1470             : 
    1471             : // Ensures the debug information is present for shared.
    1472      200563 : bool Debug::EnsureBreakInfo(Handle<SharedFunctionInfo> shared) {
    1473             :   // Return if we already have the break info for shared.
    1474      200563 :   if (shared->HasBreakInfo()) return true;
    1475       10324 :   if (!shared->IsSubjectToDebugging() && !CanBreakAtEntry(shared)) {
    1476             :     return false;
    1477             :   }
    1478       10324 :   IsCompiledScope is_compiled_scope = shared->is_compiled_scope();
    1479       11871 :   if (!is_compiled_scope.is_compiled() &&
    1480             :       !Compiler::Compile(shared, Compiler::CLEAR_EXCEPTION,
    1481        1547 :                          &is_compiled_scope)) {
    1482             :     return false;
    1483             :   }
    1484       10324 :   CreateBreakInfo(shared);
    1485       10324 :   return true;
    1486             : }
    1487             : 
    1488       10379 : void Debug::CreateBreakInfo(Handle<SharedFunctionInfo> shared) {
    1489       10379 :   HandleScope scope(isolate_);
    1490       10379 :   Handle<DebugInfo> debug_info = GetOrCreateDebugInfo(shared);
    1491             : 
    1492             :   // Initialize with break information.
    1493             : 
    1494             :   DCHECK(!debug_info->HasBreakInfo());
    1495             : 
    1496       10379 :   Factory* factory = isolate_->factory();
    1497             :   Handle<FixedArray> break_points(
    1498       10379 :       factory->NewFixedArray(DebugInfo::kEstimatedNofBreakPointsInFunction));
    1499             : 
    1500             :   int flags = debug_info->flags();
    1501       10379 :   flags |= DebugInfo::kHasBreakInfo;
    1502       10379 :   if (CanBreakAtEntry(shared)) flags |= DebugInfo::kCanBreakAtEntry;
    1503             :   debug_info->set_flags(flags);
    1504       10379 :   debug_info->set_break_points(*break_points);
    1505       10379 : }
    1506             : 
    1507      396118 : Handle<DebugInfo> Debug::GetOrCreateDebugInfo(
    1508             :     Handle<SharedFunctionInfo> shared) {
    1509     1130826 :   if (shared->HasDebugInfo()) return handle(shared->GetDebugInfo(), isolate_);
    1510             : 
    1511             :   // Create debug info and add it to the list.
    1512       28764 :   Handle<DebugInfo> debug_info = isolate_->factory()->NewDebugInfo(shared);
    1513       28764 :   DebugInfoListNode* node = new DebugInfoListNode(isolate_, *debug_info);
    1514       28764 :   node->set_next(debug_info_list_);
    1515       28764 :   debug_info_list_ = node;
    1516             : 
    1517       28764 :   return debug_info;
    1518             : }
    1519             : 
    1520        1080 : void Debug::InstallCoverageInfo(Handle<SharedFunctionInfo> shared,
    1521             :                                 Handle<CoverageInfo> coverage_info) {
    1522             :   DCHECK(!coverage_info.is_null());
    1523             : 
    1524        1080 :   Handle<DebugInfo> debug_info = GetOrCreateDebugInfo(shared);
    1525             : 
    1526             :   DCHECK(!debug_info->HasCoverageInfo());
    1527             : 
    1528        1080 :   debug_info->set_flags(debug_info->flags() | DebugInfo::kHasCoverageInfo);
    1529        2160 :   debug_info->set_coverage_info(*coverage_info);
    1530        1080 : }
    1531             : 
    1532       67064 : void Debug::RemoveAllCoverageInfos() {
    1533             :   ClearAllDebugInfos(
    1534      165768 :       [=](Handle<DebugInfo> info) { info->ClearCoverageInfo(isolate_); });
    1535       67064 : }
    1536             : 
    1537       66774 : void Debug::ClearAllDebuggerHints() {
    1538             :   ClearAllDebugInfos(
    1539      162987 :       [=](Handle<DebugInfo> info) { info->set_debugger_hints(0); });
    1540       66773 : }
    1541             : 
    1542        1417 : void Debug::FindDebugInfo(Handle<DebugInfo> debug_info,
    1543             :                           DebugInfoListNode** prev, DebugInfoListNode** curr) {
    1544        1417 :   HandleScope scope(isolate_);
    1545        1417 :   *prev = nullptr;
    1546        1417 :   *curr = debug_info_list_;
    1547        5042 :   while (*curr != nullptr) {
    1548       10875 :     if ((*curr)->debug_info().is_identical_to(debug_info)) return;
    1549        2208 :     *prev = *curr;
    1550        4416 :     *curr = (*curr)->next();
    1551             :   }
    1552             : 
    1553           0 :   UNREACHABLE();
    1554             : }
    1555             : 
    1556      200612 : void Debug::ClearAllDebugInfos(const DebugInfoClearFunction& clear_function) {
    1557             :   DebugInfoListNode* prev = nullptr;
    1558      257654 :   DebugInfoListNode* current = debug_info_list_;
    1559      458266 :   while (current != nullptr) {
    1560             :     DebugInfoListNode* next = current->next();
    1561             :     Handle<DebugInfo> debug_info = current->debug_info();
    1562       57042 :     clear_function(debug_info);
    1563       57042 :     if (debug_info->IsEmpty()) {
    1564       27347 :       FreeDebugInfoListNode(prev, current);
    1565             :       current = next;
    1566             :     } else {
    1567             :       prev = current;
    1568             :       current = next;
    1569             :     }
    1570             :   }
    1571      200612 : }
    1572             : 
    1573        1874 : void Debug::RemoveBreakInfoAndMaybeFree(Handle<DebugInfo> debug_info) {
    1574        3748 :   debug_info->ClearBreakInfo(isolate_);
    1575        1874 :   if (debug_info->IsEmpty()) {
    1576             :     DebugInfoListNode* prev;
    1577             :     DebugInfoListNode* node;
    1578        1417 :     FindDebugInfo(debug_info, &prev, &node);
    1579        1417 :     FreeDebugInfoListNode(prev, node);
    1580             :   }
    1581        1874 : }
    1582             : 
    1583       28764 : void Debug::FreeDebugInfoListNode(DebugInfoListNode* prev,
    1584       57528 :                                   DebugInfoListNode* node) {
    1585             :   DCHECK(node->debug_info()->IsEmpty());
    1586             : 
    1587             :   // Unlink from list. If prev is nullptr we are looking at the first element.
    1588       28764 :   if (prev == nullptr) {
    1589       26589 :     debug_info_list_ = node->next();
    1590             :   } else {
    1591             :     prev->set_next(node->next());
    1592             :   }
    1593             : 
    1594             :   // Pack script back into the
    1595             :   // SFI::script_or_debug_info field.
    1596             :   Handle<DebugInfo> debug_info(node->debug_info());
    1597       57528 :   debug_info->shared()->set_script_or_debug_info(debug_info->script());
    1598             : 
    1599       57528 :   delete node;
    1600       28764 : }
    1601             : 
    1602       97555 : bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
    1603       97555 :   HandleScope scope(isolate_);
    1604             : 
    1605             :   // Get the executing function in which the debug break occurred.
    1606      195110 :   Handle<SharedFunctionInfo> shared(frame->function()->shared(), isolate_);
    1607             : 
    1608             :   // With no debug info there are no break points, so we can't be at a return.
    1609       97555 :   if (!shared->HasBreakInfo()) return false;
    1610             : 
    1611             :   DCHECK(!frame->is_optimized());
    1612      269595 :   Handle<DebugInfo> debug_info(shared->GetDebugInfo(), isolate_);
    1613       89865 :   BreakLocation location = BreakLocation::FromFrame(debug_info, frame);
    1614      179730 :   return location.IsReturn();
    1615             : }
    1616             : 
    1617         324 : void Debug::ScheduleFrameRestart(StackFrame* frame) {
    1618             :   // Set a target FP for the FrameDropperTrampoline builtin to drop to once
    1619             :   // we return from the debugger.
    1620             :   DCHECK(frame->is_java_script());
    1621             :   // Only reschedule to a frame further below a frame we already scheduled for.
    1622         633 :   if (frame->fp() <= thread_local_.restart_fp_) return;
    1623             :   // If the frame is optimized, trigger a deopt and jump into the
    1624             :   // FrameDropperTrampoline in the deoptimizer.
    1625         312 :   thread_local_.restart_fp_ = frame->fp();
    1626             : 
    1627             :   // Reset break frame ID to the frame below the restarted frame.
    1628         312 :   StackTraceFrameIterator it(isolate_);
    1629         312 :   thread_local_.break_frame_id_ = StackFrame::NO_ID;
    1630        6830 :   for (StackTraceFrameIterator it(isolate_); !it.done(); it.Advance()) {
    1631        3400 :     if (it.frame()->fp() > thread_local_.restart_fp_) {
    1632         594 :       thread_local_.break_frame_id_ = it.frame()->id();
    1633             :       return;
    1634             :     }
    1635             :   }
    1636             : }
    1637             : 
    1638         118 : Handle<FixedArray> Debug::GetLoadedScripts() {
    1639             :   isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags,
    1640         118 :                                       GarbageCollectionReason::kDebugger);
    1641         118 :   Factory* factory = isolate_->factory();
    1642         236 :   if (!factory->script_list()->IsWeakArrayList()) {
    1643             :     return factory->empty_fixed_array();
    1644             :   }
    1645             :   Handle<WeakArrayList> array =
    1646         118 :       Handle<WeakArrayList>::cast(factory->script_list());
    1647         118 :   Handle<FixedArray> results = factory->NewFixedArray(array->length());
    1648             :   int length = 0;
    1649             :   {
    1650         118 :     Script::Iterator iterator(isolate_);
    1651        1492 :     for (Script script = iterator.Next(); !script.is_null();
    1652             :          script = iterator.Next()) {
    1653        1256 :       if (script->HasValidSource()) results->set(length++, script);
    1654             :     }
    1655             :   }
    1656         118 :   return FixedArray::ShrinkOrEmpty(isolate_, results, length);
    1657             : }
    1658             : 
    1659     2818557 : void Debug::OnThrow(Handle<Object> exception) {
    1660     4222351 :   if (in_debug_scope() || ignore_events()) return;
    1661             :   // Temporarily clear any scheduled_exception to allow evaluating
    1662             :   // JavaScript from the debug event handler.
    1663        8898 :   HandleScope scope(isolate_);
    1664             :   Handle<Object> scheduled_exception;
    1665        8898 :   if (isolate_->has_scheduled_exception()) {
    1666           0 :     scheduled_exception = handle(isolate_->scheduled_exception(), isolate_);
    1667           0 :     isolate_->clear_scheduled_exception();
    1668             :   }
    1669        8898 :   Handle<Object> maybe_promise = isolate_->GetPromiseOnStackOnThrow();
    1670             :   OnException(exception, maybe_promise,
    1671       17796 :               maybe_promise->IsJSPromise() ? v8::debug::kPromiseRejection
    1672        8898 :                                            : v8::debug::kException);
    1673        8898 :   if (!scheduled_exception.is_null()) {
    1674           0 :     isolate_->thread_local_top()->scheduled_exception_ = *scheduled_exception;
    1675             :   }
    1676        8898 :   PrepareStepOnThrow();
    1677             : }
    1678             : 
    1679       17678 : void Debug::OnPromiseReject(Handle<Object> promise, Handle<Object> value) {
    1680       26517 :   if (in_debug_scope() || ignore_events()) return;
    1681         889 :   HandleScope scope(isolate_);
    1682             :   // Check whether the promise has been marked as having triggered a message.
    1683         889 :   Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol();
    1684        3427 :   if (!promise->IsJSObject() ||
    1685        1649 :       JSReceiver::GetDataProperty(Handle<JSObject>::cast(promise), key)
    1686        3169 :           ->IsUndefined(isolate_)) {
    1687         816 :     OnException(value, promise, v8::debug::kPromiseRejection);
    1688             :   }
    1689             : }
    1690             : 
    1691        1937 : bool Debug::IsExceptionBlackboxed(bool uncaught) {
    1692             :   // Uncaught exception is blackboxed if all current frames are blackboxed,
    1693             :   // caught exception if top frame is blackboxed.
    1694        1937 :   StackTraceFrameIterator it(isolate_);
    1695        5811 :   while (!it.done() && it.is_wasm()) it.Advance();
    1696             :   bool is_top_frame_blackboxed =
    1697        1937 :       !it.done() ? IsFrameBlackboxed(it.javascript_frame()) : true;
    1698        1937 :   if (!uncaught || !is_top_frame_blackboxed) return is_top_frame_blackboxed;
    1699          10 :   return AllFramesOnStackAreBlackboxed();
    1700             : }
    1701             : 
    1702       62370 : bool Debug::IsFrameBlackboxed(JavaScriptFrame* frame) {
    1703       62370 :   HandleScope scope(isolate_);
    1704             :   std::vector<Handle<SharedFunctionInfo>> infos;
    1705       62370 :   frame->GetFunctions(&infos);
    1706      124910 :   for (const auto& info : infos) {
    1707       62370 :     if (!IsBlackboxed(info)) return false;
    1708             :   }
    1709             :   return true;
    1710             : }
    1711             : 
    1712        9714 : void Debug::OnException(Handle<Object> exception, Handle<Object> promise,
    1713             :                         v8::debug::ExceptionType exception_type) {
    1714             :   // TODO(kozyatinskiy): regress-662674.js test fails on arm without this.
    1715       17531 :   if (!AllowJavascriptExecution::IsAllowed(isolate_)) return;
    1716             : 
    1717        9692 :   Isolate::CatchType catch_type = isolate_->PredictExceptionCatcher();
    1718             : 
    1719             :   // Don't notify listener of exceptions that are internal to a desugaring.
    1720        9692 :   if (catch_type == Isolate::CAUGHT_BY_DESUGARING) return;
    1721             : 
    1722        9692 :   bool uncaught = catch_type == Isolate::NOT_CAUGHT;
    1723       19384 :   if (promise->IsJSObject()) {
    1724        1943 :     Handle<JSObject> jspromise = Handle<JSObject>::cast(promise);
    1725             :     // Mark the promise as already having triggered a message.
    1726        1943 :     Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol();
    1727        1943 :     Object::SetProperty(isolate_, jspromise, key, key, LanguageMode::kStrict)
    1728        1943 :         .Assert();
    1729             :     // Check whether the promise reject is considered an uncaught exception.
    1730        1943 :     uncaught = !isolate_->PromiseHasUserDefinedRejectHandler(jspromise);
    1731             :   }
    1732             : 
    1733        9692 :   if (!debug_delegate_) return;
    1734             : 
    1735             :   // Bail out if exception breaks are not active
    1736        9692 :   if (uncaught) {
    1737             :     // Uncaught exceptions are reported by either flags.
    1738        1283 :     if (!(break_on_uncaught_exception_ || break_on_exception_)) return;
    1739             :   } else {
    1740             :     // Caught exceptions are reported is activated.
    1741        8409 :     if (!break_on_exception_) return;
    1742             :   }
    1743             : 
    1744             :   {
    1745        2020 :     JavaScriptFrameIterator it(isolate_);
    1746             :     // Check whether the top frame is blackboxed or the break location is muted.
    1747        3957 :     if (!it.done() && (IsMutedAtCurrentLocation(it.frame()) ||
    1748        1937 :                        IsExceptionBlackboxed(uncaught))) {
    1749             :       return;
    1750             :     }
    1751        1917 :     if (it.done()) return;  // Do not trigger an event with an empty stack.
    1752             :   }
    1753             : 
    1754        1897 :   DebugScope debug_scope(this);
    1755        1897 :   HandleScope scope(isolate_);
    1756             :   DisableBreak no_recursive_break(this);
    1757             : 
    1758        1897 :   Handle<Context> native_context(isolate_->native_context());
    1759             :   debug_delegate_->ExceptionThrown(
    1760             :       v8::Utils::ToLocal(native_context), v8::Utils::ToLocal(exception),
    1761        3794 :       v8::Utils::ToLocal(promise), uncaught, exception_type);
    1762             : }
    1763             : 
    1764      128092 : void Debug::OnDebugBreak(Handle<FixedArray> break_points_hit) {
    1765             :   DCHECK(!break_points_hit.is_null());
    1766             :   // The caller provided for DebugScope.
    1767             :   AssertDebugContext();
    1768             :   // Bail out if there is no listener for this event
    1769      128092 :   if (ignore_events()) return;
    1770             : 
    1771             : #ifdef DEBUG
    1772             :   PrintBreakLocation();
    1773             : #endif  // DEBUG
    1774             : 
    1775      128092 :   if (!debug_delegate_) return;
    1776             :   DCHECK(in_debug_scope());
    1777      128092 :   HandleScope scope(isolate_);
    1778             :   DisableBreak no_recursive_break(this);
    1779             : 
    1780             :   std::vector<int> inspector_break_points_hit;
    1781             :   int inspector_break_points_count = 0;
    1782             :   // This array contains breakpoints installed using JS debug API.
    1783      264104 :   for (int i = 0; i < break_points_hit->length(); ++i) {
    1784             :     BreakPoint break_point = BreakPoint::cast(break_points_hit->get(i));
    1785        7920 :     inspector_break_points_hit.push_back(break_point->id());
    1786             :     ++inspector_break_points_count;
    1787             :   }
    1788             : 
    1789      128092 :   Handle<Context> native_context(isolate_->native_context());
    1790             :   debug_delegate_->BreakProgramRequested(v8::Utils::ToLocal(native_context),
    1791      128092 :                                          inspector_break_points_hit);
    1792             : }
    1793             : 
    1794             : namespace {
    1795       24774 : debug::Location GetDebugLocation(Handle<Script> script, int source_position) {
    1796             :   Script::PositionInfo info;
    1797       24774 :   Script::GetPositionInfo(script, source_position, &info, Script::WITH_OFFSET);
    1798             :   // V8 provides ScriptCompiler::CompileFunctionInContext method which takes
    1799             :   // expression and compile it as anonymous function like (function() ..
    1800             :   // expression ..). To produce correct locations for stmts inside of this
    1801             :   // expression V8 compile this function with negative offset. Instead of stmt
    1802             :   // position blackboxing use function start position which is negative in
    1803             :   // described case.
    1804       74322 :   return debug::Location(std::max(info.line, 0), std::max(info.column, 0));
    1805             : }
    1806             : }  // namespace
    1807             : 
    1808      169820 : bool Debug::IsBlackboxed(Handle<SharedFunctionInfo> shared) {
    1809      169820 :   if (!debug_delegate_) return !shared->IsSubjectToDebugging();
    1810      169820 :   Handle<DebugInfo> debug_info = GetOrCreateDebugInfo(shared);
    1811      169820 :   if (!debug_info->computed_debug_is_blackboxed()) {
    1812             :     bool is_blackboxed =
    1813       37987 :         !shared->IsSubjectToDebugging() || !shared->script()->IsScript();
    1814       13213 :     if (!is_blackboxed) {
    1815             :       SuppressDebug while_processing(this);
    1816       12387 :       HandleScope handle_scope(isolate_);
    1817       12387 :       PostponeInterruptsScope no_interrupts(isolate_);
    1818             :       DisableBreak no_recursive_break(this);
    1819             :       DCHECK(shared->script()->IsScript());
    1820       37161 :       Handle<Script> script(Script::cast(shared->script()), isolate_);
    1821             :       DCHECK(script->IsUserJavaScript());
    1822       12387 :       debug::Location start = GetDebugLocation(script, shared->StartPosition());
    1823       12387 :       debug::Location end = GetDebugLocation(script, shared->EndPosition());
    1824             :       is_blackboxed = debug_delegate_->IsFunctionBlackboxed(
    1825       12387 :           ToApiHandle<debug::Script>(script), start, end);
    1826             :     }
    1827       26426 :     debug_info->set_debug_is_blackboxed(is_blackboxed);
    1828       13213 :     debug_info->set_computed_debug_is_blackboxed(true);
    1829             :   }
    1830      169820 :   return debug_info->debug_is_blackboxed();
    1831             : }
    1832             : 
    1833       60588 : bool Debug::AllFramesOnStackAreBlackboxed() {
    1834       60588 :   HandleScope scope(isolate_);
    1835      121426 :   for (StackTraceFrameIterator it(isolate_); !it.done(); it.Advance()) {
    1836       60433 :     if (!it.is_javascript()) continue;
    1837       60433 :     if (!IsFrameBlackboxed(it.javascript_frame())) return false;
    1838             :   }
    1839         280 :   return true;
    1840             : }
    1841             : 
    1842       10529 : bool Debug::CanBreakAtEntry(Handle<SharedFunctionInfo> shared) {
    1843             :   // Allow break at entry for builtin functions.
    1844       20838 :   if (shared->native() || shared->IsApiFunction()) {
    1845             :     // Functions that are subject to debugging can have regular breakpoints.
    1846             :     DCHECK(!shared->IsSubjectToDebugging());
    1847             :     return true;
    1848             :   }
    1849       10229 :   return false;
    1850             : }
    1851             : 
    1852          50 : bool Debug::SetScriptSource(Handle<Script> script, Handle<String> source,
    1853             :                             bool preview, debug::LiveEditResult* result) {
    1854          50 :   DebugScope debug_scope(this);
    1855          50 :   running_live_edit_ = true;
    1856          50 :   LiveEdit::PatchScript(isolate_, script, source, preview, result);
    1857          50 :   running_live_edit_ = false;
    1858          50 :   return result->status == debug::LiveEditResult::OK;
    1859             : }
    1860             : 
    1861      372398 : void Debug::OnCompileError(Handle<Script> script) {
    1862      372398 :   ProcessCompileEvent(true, script);
    1863      372398 : }
    1864             : 
    1865     3887482 : void Debug::OnAfterCompile(Handle<Script> script) {
    1866     3887482 :   ProcessCompileEvent(false, script);
    1867     3887493 : }
    1868             : 
    1869     8519759 : void Debug::ProcessCompileEvent(bool has_compile_error, Handle<Script> script) {
    1870             :   // TODO(kozyatinskiy): teach devtools to work with liveedit scripts better
    1871             :   // first and then remove this fast return.
    1872     8489497 :   if (running_live_edit_) return;
    1873             :   // Attach the correct debug id to the script. The debug id is used by the
    1874             :   // inspector to filter scripts by native context.
    1875    12779632 :   script->set_context_data(isolate_->native_context()->debug_context_id());
    1876     4259883 :   if (ignore_events()) return;
    1877       30800 :   if (!script->IsUserJavaScript() && script->type() != i::Script::TYPE_WASM) {
    1878             :     return;
    1879             :   }
    1880       30270 :   if (!debug_delegate_) return;
    1881             :   SuppressDebug while_processing(this);
    1882       60540 :   DebugScope debug_scope(this);
    1883       30270 :   HandleScope scope(isolate_);
    1884             :   DisableBreak no_recursive_break(this);
    1885       60540 :   AllowJavascriptExecution allow_script(isolate_);
    1886             :   debug_delegate_->ScriptCompiled(ToApiHandle<debug::Script>(script),
    1887       30270 :                                   running_live_edit_, has_compile_error);
    1888             : }
    1889             : 
    1890      765407 : int Debug::CurrentFrameCount() {
    1891      121560 :   StackTraceFrameIterator it(isolate_);
    1892      121560 :   if (break_frame_id() != StackFrame::NO_ID) {
    1893             :     // Skip to break frame.
    1894             :     DCHECK(in_debug_scope());
    1895     1445865 :     while (!it.done() && it.frame()->id() != break_frame_id()) it.Advance();
    1896             :   }
    1897             :   int counter = 0;
    1898      336409 :   while (!it.done()) {
    1899      429698 :     if (it.frame()->is_optimized()) {
    1900             :       std::vector<SharedFunctionInfo> infos;
    1901        6069 :       OptimizedFrame::cast(it.frame())->GetFunctions(&infos);
    1902       12138 :       counter += infos.size();
    1903             :     } else {
    1904      208780 :       counter++;
    1905             :     }
    1906      214849 :     it.Advance();
    1907             :   }
    1908      121560 :   return counter;
    1909             : }
    1910             : 
    1911        7892 : void Debug::SetDebugDelegate(debug::DebugDelegate* delegate) {
    1912        7892 :   debug_delegate_ = delegate;
    1913        7892 :   UpdateState();
    1914        7892 : }
    1915             : 
    1916      513504 : void Debug::UpdateState() {
    1917      513504 :   bool is_active = debug_delegate_ != nullptr;
    1918     1027008 :   if (is_active == is_active_) return;
    1919        7852 :   if (is_active) {
    1920             :     // Note that the debug context could have already been loaded to
    1921             :     // bootstrap test cases.
    1922        7852 :     isolate_->compilation_cache()->Disable();
    1923             :     is_active = true;
    1924        3946 :     feature_tracker()->Track(DebugFeatureTracker::kActive);
    1925             :   } else {
    1926        7812 :     isolate_->compilation_cache()->Enable();
    1927        3906 :     Unload();
    1928             :   }
    1929        7852 :   is_active_ = is_active;
    1930        7852 :   isolate_->PromiseHookStateUpdated();
    1931             : }
    1932             : 
    1933           0 : void Debug::UpdateHookOnFunctionCall() {
    1934             :   STATIC_ASSERT(LastStepAction == StepIn);
    1935             :   hook_on_function_call_ =
    1936      496540 :       thread_local_.last_step_action_ == StepIn ||
    1937      413693 :       isolate_->debug_execution_mode() == DebugInfo::kSideEffects ||
    1938      403284 :       thread_local_.break_on_next_function_call_;
    1939           0 : }
    1940             : 
    1941      205923 : void Debug::HandleDebugBreak(IgnoreBreakMode ignore_break_mode) {
    1942             :   // Initialize LiveEdit.
    1943       68644 :   LiveEdit::InitializeThreadLocal(this);
    1944             :   // Ignore debug break during bootstrapping.
    1945       68791 :   if (isolate_->bootstrapper()->IsActive()) return;
    1946             :   // Just continue if breaks are disabled.
    1947       68644 :   if (break_disabled()) return;
    1948             :   // Ignore debug break if debugger is not active.
    1949       68635 :   if (!is_active()) return;
    1950             : 
    1951             :   StackLimitCheck check(isolate_);
    1952       68530 :   if (check.HasOverflowed()) return;
    1953             : 
    1954       68530 :   { JavaScriptFrameIterator it(isolate_);
    1955             :     DCHECK(!it.done());
    1956       68530 :     Object fun = it.frame()->function();
    1957       68530 :     if (fun->IsJSFunction()) {
    1958       68530 :       HandleScope scope(isolate_);
    1959       68530 :       Handle<JSFunction> function(JSFunction::cast(fun), isolate_);
    1960             :       // Don't stop in builtin and blackboxed functions.
    1961      205590 :       Handle<SharedFunctionInfo> shared(function->shared(), isolate_);
    1962             :       bool ignore_break = ignore_break_mode == kIgnoreIfTopFrameBlackboxed
    1963             :                               ? IsBlackboxed(shared)
    1964       68530 :                               : AllFramesOnStackAreBlackboxed();
    1965       68530 :       if (ignore_break) return;
    1966             :       // Don't stop if the break location is muted.
    1967       68515 :       if (IsMutedAtCurrentLocation(it.frame())) return;
    1968             :     }
    1969             :   }
    1970             : 
    1971             :   // Clear stepping to avoid duplicate breaks.
    1972       68497 :   ClearStepping();
    1973             : 
    1974       68497 :   HandleScope scope(isolate_);
    1975      136994 :   DebugScope debug_scope(this);
    1976             : 
    1977      136994 :   OnDebugBreak(isolate_->factory()->empty_fixed_array());
    1978             : }
    1979             : 
    1980             : #ifdef DEBUG
    1981             : void Debug::PrintBreakLocation() {
    1982             :   if (!FLAG_print_break_location) return;
    1983             :   HandleScope scope(isolate_);
    1984             :   StackTraceFrameIterator iterator(isolate_);
    1985             :   if (iterator.done()) return;
    1986             :   StandardFrame* frame = iterator.frame();
    1987             :   FrameSummary summary = FrameSummary::GetTop(frame);
    1988             :   int source_position = summary.SourcePosition();
    1989             :   Handle<Object> script_obj = summary.script();
    1990             :   PrintF("[debug] break in function '");
    1991             :   summary.FunctionName()->PrintOn(stdout);
    1992             :   PrintF("'.\n");
    1993             :   if (script_obj->IsScript()) {
    1994             :     Handle<Script> script = Handle<Script>::cast(script_obj);
    1995             :     Handle<String> source(String::cast(script->source()), isolate_);
    1996             :     Script::InitLineEnds(script);
    1997             :     int line =
    1998             :         Script::GetLineNumber(script, source_position) - script->line_offset();
    1999             :     int column = Script::GetColumnNumber(script, source_position) -
    2000             :                  (line == 0 ? script->column_offset() : 0);
    2001             :     Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()),
    2002             :                                  isolate_);
    2003             :     int line_start = line == 0 ? 0 : Smi::ToInt(line_ends->get(line - 1)) + 1;
    2004             :     int line_end = Smi::ToInt(line_ends->get(line));
    2005             :     DisallowHeapAllocation no_gc;
    2006             :     String::FlatContent content = source->GetFlatContent(no_gc);
    2007             :     if (content.IsOneByte()) {
    2008             :       PrintF("[debug] %.*s\n", line_end - line_start,
    2009             :              content.ToOneByteVector().start() + line_start);
    2010             :       PrintF("[debug] ");
    2011             :       for (int i = 0; i < column; i++) PrintF(" ");
    2012             :       PrintF("^\n");
    2013             :     } else {
    2014             :       PrintF("[debug] at line %d column %d\n", line, column);
    2015             :     }
    2016             :   }
    2017             : }
    2018             : #endif  // DEBUG
    2019             : 
    2020      252806 : DebugScope::DebugScope(Debug* debug)
    2021             :     : debug_(debug),
    2022             :       prev_(reinterpret_cast<DebugScope*>(
    2023      252806 :           base::Relaxed_Load(&debug->thread_local_.current_debug_scope_))),
    2024      758418 :       no_interrupts_(debug_->isolate_) {
    2025             :   // Link recursive debugger entry.
    2026             :   base::Relaxed_Store(&debug_->thread_local_.current_debug_scope_,
    2027      252806 :                       reinterpret_cast<base::AtomicWord>(this));
    2028             : 
    2029             :   // Store the previous frame id and return value.
    2030      505612 :   break_frame_id_ = debug_->break_frame_id();
    2031             : 
    2032             :   // Create the new break info. If there is no proper frames there is no break
    2033             :   // frame id.
    2034      252806 :   StackTraceFrameIterator it(isolate());
    2035             :   bool has_frames = !it.done();
    2036             :   debug_->thread_local_.break_frame_id_ =
    2037      505612 :       has_frames ? it.frame()->id() : StackFrame::NO_ID;
    2038             : 
    2039      252806 :   debug_->UpdateState();
    2040      252806 : }
    2041             : 
    2042             : 
    2043      252806 : DebugScope::~DebugScope() {
    2044             :   // Leaving this debugger entry.
    2045             :   base::Relaxed_Store(&debug_->thread_local_.current_debug_scope_,
    2046      252806 :                       reinterpret_cast<base::AtomicWord>(prev_));
    2047             : 
    2048             :   // Restore to the previous break state.
    2049      252806 :   debug_->thread_local_.break_frame_id_ = break_frame_id_;
    2050             : 
    2051      252806 :   debug_->UpdateState();
    2052      252806 : }
    2053             : 
    2054       66711 : ReturnValueScope::ReturnValueScope(Debug* debug) : debug_(debug) {
    2055       66711 :   return_value_ = debug_->return_value_handle();
    2056       66711 : }
    2057             : 
    2058       66711 : ReturnValueScope::~ReturnValueScope() {
    2059       66711 :   debug_->set_return_value(*return_value_);
    2060       66711 : }
    2061             : 
    2062       16191 : void Debug::UpdateDebugInfosForExecutionMode() {
    2063             :   // Walk all debug infos and update their execution mode if it is different
    2064             :   // from the isolate execution mode.
    2065     6522673 :   DebugInfoListNode* current = debug_info_list_;
    2066     3285623 :   while (current != nullptr) {
    2067             :     Handle<DebugInfo> debug_info = current->debug_info();
    2068     6519601 :     if (debug_info->HasInstrumentedBytecodeArray() &&
    2069     3279479 :         debug_info->DebugExecutionMode() != isolate_->debug_execution_mode()) {
    2070             :       DCHECK(debug_info->shared()->HasBytecodeArray());
    2071       26238 :       if (isolate_->debug_execution_mode() == DebugInfo::kBreakpoints) {
    2072        6734 :         ClearSideEffectChecks(debug_info);
    2073        6734 :         ApplyBreakPoints(debug_info);
    2074             :       } else {
    2075        6385 :         ClearBreakPoints(debug_info);
    2076        6385 :         ApplySideEffectChecks(debug_info);
    2077             :       }
    2078             :     }
    2079             :     current = current->next();
    2080             :   }
    2081       16191 : }
    2082             : 
    2083        8098 : void Debug::StartSideEffectCheckMode() {
    2084             :   DCHECK(isolate_->debug_execution_mode() != DebugInfo::kSideEffects);
    2085        8098 :   isolate_->set_debug_execution_mode(DebugInfo::kSideEffects);
    2086             :   UpdateHookOnFunctionCall();
    2087        8098 :   side_effect_check_failed_ = false;
    2088             : 
    2089             :   DCHECK(!temporary_objects_);
    2090        8098 :   temporary_objects_.reset(new TemporaryObjectsTracker());
    2091        8098 :   isolate_->heap()->AddHeapObjectAllocationTracker(temporary_objects_.get());
    2092       24294 :   Handle<FixedArray> array(isolate_->native_context()->regexp_last_match_info(),
    2093       16196 :                            isolate_);
    2094             :   regexp_match_info_ =
    2095        8098 :       Handle<RegExpMatchInfo>::cast(isolate_->factory()->CopyFixedArray(array));
    2096             : 
    2097             :   // Update debug infos to have correct execution mode.
    2098        8098 :   UpdateDebugInfosForExecutionMode();
    2099        8098 : }
    2100             : 
    2101        8093 : void Debug::StopSideEffectCheckMode() {
    2102             :   DCHECK(isolate_->debug_execution_mode() == DebugInfo::kSideEffects);
    2103        8093 :   if (side_effect_check_failed_) {
    2104             :     DCHECK(isolate_->has_pending_exception());
    2105             :     DCHECK_EQ(ReadOnlyRoots(isolate_).termination_exception(),
    2106             :               isolate_->pending_exception());
    2107             :     // Convert the termination exception into a regular exception.
    2108        2965 :     isolate_->CancelTerminateExecution();
    2109             :     isolate_->Throw(*isolate_->factory()->NewEvalError(
    2110        5930 :         MessageTemplate::kNoSideEffectDebugEvaluate));
    2111             :   }
    2112        8093 :   isolate_->set_debug_execution_mode(DebugInfo::kBreakpoints);
    2113             :   UpdateHookOnFunctionCall();
    2114        8093 :   side_effect_check_failed_ = false;
    2115             : 
    2116             :   DCHECK(temporary_objects_);
    2117        8093 :   isolate_->heap()->RemoveHeapObjectAllocationTracker(temporary_objects_.get());
    2118             :   temporary_objects_.reset();
    2119       16186 :   isolate_->native_context()->set_regexp_last_match_info(*regexp_match_info_);
    2120        8093 :   regexp_match_info_ = Handle<RegExpMatchInfo>::null();
    2121             : 
    2122             :   // Update debug infos to have correct execution mode.
    2123        8093 :   UpdateDebugInfosForExecutionMode();
    2124        8093 : }
    2125             : 
    2126        6761 : void Debug::ApplySideEffectChecks(Handle<DebugInfo> debug_info) {
    2127             :   DCHECK(debug_info->HasInstrumentedBytecodeArray());
    2128             :   Handle<BytecodeArray> debug_bytecode(debug_info->DebugBytecodeArray(),
    2129       20283 :                                        isolate_);
    2130        6761 :   DebugEvaluate::ApplySideEffectChecks(debug_bytecode);
    2131        6761 :   debug_info->SetDebugExecutionMode(DebugInfo::kSideEffects);
    2132        6761 : }
    2133             : 
    2134        6734 : void Debug::ClearSideEffectChecks(Handle<DebugInfo> debug_info) {
    2135             :   DCHECK(debug_info->HasInstrumentedBytecodeArray());
    2136             :   Handle<BytecodeArray> debug_bytecode(debug_info->DebugBytecodeArray(),
    2137       20202 :                                        isolate_);
    2138       20202 :   Handle<BytecodeArray> original(debug_info->OriginalBytecodeArray(), isolate_);
    2139      150537 :   for (interpreter::BytecodeArrayIterator it(debug_bytecode); !it.done();
    2140      137069 :        it.Advance()) {
    2141             :     // Restore from original. This may copy only the scaling prefix, which is
    2142             :     // correct, since we patch scaling prefixes to debug breaks if exists.
    2143             :     debug_bytecode->set(it.current_offset(),
    2144      274138 :                         original->get(it.current_offset()));
    2145             :   }
    2146        6734 : }
    2147             : 
    2148       13730 : bool Debug::PerformSideEffectCheck(Handle<JSFunction> function,
    2149             :                                    Handle<Object> receiver) {
    2150             :   DCHECK_EQ(isolate_->debug_execution_mode(), DebugInfo::kSideEffects);
    2151       13730 :   DisallowJavascriptExecution no_js(isolate_);
    2152       13730 :   IsCompiledScope is_compiled_scope(function->shared()->is_compiled_scope());
    2153       14338 :   if (!function->is_compiled() &&
    2154             :       !Compiler::Compile(function, Compiler::KEEP_EXCEPTION,
    2155         608 :                          &is_compiled_scope)) {
    2156             :     return false;
    2157             :   }
    2158             :   DCHECK(is_compiled_scope.is_compiled());
    2159       41190 :   Handle<SharedFunctionInfo> shared(function->shared(), isolate_);
    2160       13730 :   Handle<DebugInfo> debug_info = GetOrCreateDebugInfo(shared);
    2161             :   DebugInfo::SideEffectState side_effect_state =
    2162       27460 :       debug_info->GetSideEffectState(isolate_);
    2163       13730 :   switch (side_effect_state) {
    2164             :     case DebugInfo::kHasSideEffects:
    2165        2249 :       if (FLAG_trace_side_effect_free_debug_evaluate) {
    2166             :         PrintF("[debug-evaluate] Function %s failed side effect check.\n",
    2167           0 :                function->shared()->DebugName()->ToCString().get());
    2168             :       }
    2169        2249 :       side_effect_check_failed_ = true;
    2170             :       // Throw an uncatchable termination exception.
    2171        2249 :       isolate_->TerminateExecution();
    2172        2249 :       return false;
    2173             :     case DebugInfo::kRequiresRuntimeChecks: {
    2174        1253 :       if (!shared->HasBytecodeArray()) {
    2175         877 :         return PerformSideEffectCheckForObject(receiver);
    2176             :       }
    2177             :       // If function has bytecode array then prepare function for debug
    2178             :       // execution to perform runtime side effect checks.
    2179             :       DCHECK(shared->is_compiled());
    2180         376 :       PrepareFunctionForDebugExecution(shared);
    2181         376 :       ApplySideEffectChecks(debug_info);
    2182         376 :       return true;
    2183             :     }
    2184             :     case DebugInfo::kHasNoSideEffect:
    2185             :       return true;
    2186             :     case DebugInfo::kNotComputed:
    2187           0 :       UNREACHABLE();
    2188             :       return false;
    2189             :   }
    2190           0 :   UNREACHABLE();
    2191       13730 :   return false;
    2192             : }
    2193             : 
    2194       77118 : Handle<Object> Debug::return_value_handle() {
    2195      154236 :   return handle(thread_local_.return_value_, isolate_);
    2196             : }
    2197             : 
    2198         421 : bool Debug::PerformSideEffectCheckForCallback(
    2199             :     Handle<Object> callback_info, Handle<Object> receiver,
    2200             :     Debug::AccessorKind accessor_kind) {
    2201             :   DCHECK_EQ(!receiver.is_null(), callback_info->IsAccessorInfo());
    2202             :   DCHECK_EQ(isolate_->debug_execution_mode(), DebugInfo::kSideEffects);
    2203        1823 :   if (!callback_info.is_null() && callback_info->IsCallHandlerInfo() &&
    2204         560 :       i::CallHandlerInfo::cast(*callback_info)->NextCallHasNoSideEffect()) {
    2205             :     return true;
    2206             :   }
    2207             :   // TODO(7515): always pass a valid callback info object.
    2208         411 :   if (!callback_info.is_null()) {
    2209         822 :     if (callback_info->IsAccessorInfo()) {
    2210             :       // List of whitelisted internal accessors can be found in accessors.h.
    2211         246 :       AccessorInfo info = AccessorInfo::cast(*callback_info);
    2212             :       DCHECK_NE(kNotAccessor, accessor_kind);
    2213         246 :       switch (accessor_kind == kSetter ? info->setter_side_effect_type()
    2214             :                                        : info->getter_side_effect_type()) {
    2215             :         case SideEffectType::kHasNoSideEffect:
    2216             :           // We do not support setter accessors with no side effects, since
    2217             :           // calling set accessors go through a store bytecode. Store bytecodes
    2218             :           // are considered to cause side effects (to non-temporary objects).
    2219             :           DCHECK_NE(kSetter, accessor_kind);
    2220         216 :           return true;
    2221             :         case SideEffectType::kHasSideEffectToReceiver:
    2222             :           DCHECK(!receiver.is_null());
    2223          64 :           if (PerformSideEffectCheckForObject(receiver)) return true;
    2224           9 :           isolate_->OptionalRescheduleException(false);
    2225           9 :           return false;
    2226             :         case SideEffectType::kHasSideEffect:
    2227             :           break;
    2228             :       }
    2229          30 :       if (FLAG_trace_side_effect_free_debug_evaluate) {
    2230           0 :         PrintF("[debug-evaluate] API Callback '");
    2231           0 :         info->name()->ShortPrint();
    2232           0 :         PrintF("' may cause side effect.\n");
    2233             :       }
    2234         330 :     } else if (callback_info->IsInterceptorInfo()) {
    2235          36 :       InterceptorInfo info = InterceptorInfo::cast(*callback_info);
    2236          36 :       if (info->has_no_side_effect()) return true;
    2237          18 :       if (FLAG_trace_side_effect_free_debug_evaluate) {
    2238           0 :         PrintF("[debug-evaluate] API Interceptor may cause side effect.\n");
    2239             :       }
    2240         258 :     } else if (callback_info->IsCallHandlerInfo()) {
    2241         129 :       CallHandlerInfo info = CallHandlerInfo::cast(*callback_info);
    2242         129 :       if (info->IsSideEffectFreeCallHandlerInfo()) return true;
    2243          64 :       if (FLAG_trace_side_effect_free_debug_evaluate) {
    2244           0 :         PrintF("[debug-evaluate] API CallHandlerInfo may cause side effect.\n");
    2245             :       }
    2246             :     }
    2247             :   }
    2248         112 :   side_effect_check_failed_ = true;
    2249             :   // Throw an uncatchable termination exception.
    2250         112 :   isolate_->TerminateExecution();
    2251         112 :   isolate_->OptionalRescheduleException(false);
    2252         112 :   return false;
    2253             : }
    2254             : 
    2255        2333 : bool Debug::PerformSideEffectCheckAtBytecode(InterpretedFrame* frame) {
    2256             :   using interpreter::Bytecode;
    2257             : 
    2258             :   DCHECK_EQ(isolate_->debug_execution_mode(), DebugInfo::kSideEffects);
    2259        2333 :   SharedFunctionInfo shared = frame->function()->shared();
    2260        2333 :   BytecodeArray bytecode_array = shared->GetBytecodeArray();
    2261        2333 :   int offset = frame->GetBytecodeOffset();
    2262             :   interpreter::BytecodeArrayAccessor bytecode_accessor(
    2263        4666 :       handle(bytecode_array, isolate_), offset);
    2264             : 
    2265        2333 :   Bytecode bytecode = bytecode_accessor.current_bytecode();
    2266             :   interpreter::Register reg;
    2267        2333 :   switch (bytecode) {
    2268             :     case Bytecode::kStaCurrentContextSlot:
    2269          49 :       reg = interpreter::Register::current_context();
    2270          49 :       break;
    2271             :     default:
    2272        2284 :       reg = bytecode_accessor.GetRegisterOperand(0);
    2273        2284 :       break;
    2274             :   }
    2275             :   Handle<Object> object =
    2276        4666 :       handle(frame->ReadInterpreterRegister(reg.index()), isolate_);
    2277        2333 :   return PerformSideEffectCheckForObject(object);
    2278             : }
    2279             : 
    2280        3328 : bool Debug::PerformSideEffectCheckForObject(Handle<Object> object) {
    2281             :   DCHECK_EQ(isolate_->debug_execution_mode(), DebugInfo::kSideEffects);
    2282             : 
    2283             :   // We expect no side-effects for primitives.
    2284        6656 :   if (object->IsNumber()) return true;
    2285        6656 :   if (object->IsName()) return true;
    2286             : 
    2287        6638 :   if (temporary_objects_->HasObject(Handle<HeapObject>::cast(object))) {
    2288             :     return true;
    2289             :   }
    2290             : 
    2291         604 :   if (FLAG_trace_side_effect_free_debug_evaluate) {
    2292           0 :     PrintF("[debug-evaluate] failed runtime side effect check.\n");
    2293             :   }
    2294         604 :   side_effect_check_failed_ = true;
    2295             :   // Throw an uncatchable termination exception.
    2296         604 :   isolate_->TerminateExecution();
    2297         604 :   return false;
    2298             : }
    2299             : }  // namespace internal
    2300      183867 : }  // namespace v8

Generated by: LCOV version 1.10