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

Generated by: LCOV version 1.10