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

Generated by: LCOV version 1.10