Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: src/debug/debug.cc

Issue 2664793002: [debugger] account for inlined functions when stepping. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/debug/debug.h" 5 #include "src/debug/debug.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/arguments.h" 10 #include "src/arguments.h"
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 } 109 }
110 110
111 bool BreakLocation::HasBreakPoint(Handle<DebugInfo> debug_info) const { 111 bool BreakLocation::HasBreakPoint(Handle<DebugInfo> debug_info) const {
112 // First check whether there is a break point with the same source position. 112 // First check whether there is a break point with the same source position.
113 if (!debug_info->HasBreakPoint(position_)) return false; 113 if (!debug_info->HasBreakPoint(position_)) return false;
114 // Then check whether a break point at that source position would have 114 // Then check whether a break point at that source position would have
115 // the same code offset. Otherwise it's just a break location that we can 115 // the same code offset. Otherwise it's just a break location that we can
116 // step to, but not actually a location where we can put a break point. 116 // step to, but not actually a location where we can put a break point.
117 if (abstract_code_->IsCode()) { 117 if (abstract_code_->IsCode()) {
118 DCHECK_EQ(debug_info->DebugCode(), abstract_code_->GetCode()); 118 DCHECK_EQ(debug_info->DebugCode(), abstract_code_->GetCode());
119 CodeBreakIterator it(debug_info, ALL_BREAK_LOCATIONS); 119 CodeBreakIterator it(debug_info);
120 it.SkipToPosition(position_, BREAK_POSITION_ALIGNED); 120 it.SkipToPosition(position_, BREAK_POSITION_ALIGNED);
121 return it.code_offset() == code_offset_; 121 return it.code_offset() == code_offset_;
122 } else { 122 } else {
123 DCHECK(abstract_code_->IsBytecodeArray()); 123 DCHECK(abstract_code_->IsBytecodeArray());
124 BytecodeArrayBreakIterator it(debug_info, ALL_BREAK_LOCATIONS); 124 BytecodeArrayBreakIterator it(debug_info);
125 it.SkipToPosition(position_, BREAK_POSITION_ALIGNED); 125 it.SkipToPosition(position_, BREAK_POSITION_ALIGNED);
126 return it.code_offset() == code_offset_; 126 return it.code_offset() == code_offset_;
127 } 127 }
128 } 128 }
129 129
130 std::unique_ptr<BreakIterator> BreakIterator::GetIterator( 130 std::unique_ptr<BreakIterator> BreakIterator::GetIterator(
131 Handle<DebugInfo> debug_info, Handle<AbstractCode> abstract_code, 131 Handle<DebugInfo> debug_info, Handle<AbstractCode> abstract_code) {
132 BreakLocatorType type) {
133 if (abstract_code->IsBytecodeArray()) { 132 if (abstract_code->IsBytecodeArray()) {
134 DCHECK(debug_info->HasDebugBytecodeArray()); 133 DCHECK(debug_info->HasDebugBytecodeArray());
135 return std::unique_ptr<BreakIterator>( 134 return std::unique_ptr<BreakIterator>(
136 new BytecodeArrayBreakIterator(debug_info, type)); 135 new BytecodeArrayBreakIterator(debug_info));
137 } else { 136 } else {
138 DCHECK(abstract_code->IsCode()); 137 DCHECK(abstract_code->IsCode());
139 DCHECK(debug_info->HasDebugCode()); 138 DCHECK(debug_info->HasDebugCode());
140 return std::unique_ptr<BreakIterator>( 139 return std::unique_ptr<BreakIterator>(new CodeBreakIterator(debug_info));
141 new CodeBreakIterator(debug_info, type));
142 } 140 }
143 } 141 }
144 142
145 BreakIterator::BreakIterator(Handle<DebugInfo> debug_info, 143 BreakIterator::BreakIterator(Handle<DebugInfo> debug_info)
146 BreakLocatorType type) 144 : debug_info_(debug_info), break_index_(-1) {
147 : debug_info_(debug_info), break_index_(-1), break_locator_type_(type) {
148 position_ = debug_info->shared()->start_position(); 145 position_ = debug_info->shared()->start_position();
149 statement_position_ = position_; 146 statement_position_ = position_;
150 } 147 }
151 148
152 int BreakIterator::BreakIndexFromPosition(int source_position, 149 int BreakIterator::BreakIndexFromPosition(int source_position,
153 BreakPositionAlignment alignment) { 150 BreakPositionAlignment alignment) {
154 int distance = kMaxInt; 151 int distance = kMaxInt;
155 int closest_break = break_index(); 152 int closest_break = break_index();
156 while (!Done()) { 153 while (!Done()) {
157 int next_position; 154 int next_position;
158 if (alignment == STATEMENT_ALIGNED) { 155 if (alignment == STATEMENT_ALIGNED) {
159 next_position = statement_position(); 156 next_position = statement_position();
160 } else { 157 } else {
161 DCHECK(alignment == BREAK_POSITION_ALIGNED); 158 DCHECK(alignment == BREAK_POSITION_ALIGNED);
162 next_position = position(); 159 next_position = position();
163 } 160 }
164 if (source_position <= next_position && 161 if (source_position <= next_position &&
165 next_position - source_position < distance) { 162 next_position - source_position < distance) {
166 closest_break = break_index(); 163 closest_break = break_index();
167 distance = next_position - source_position; 164 distance = next_position - source_position;
168 // Check whether we can't get any closer. 165 // Check whether we can't get any closer.
169 if (distance == 0) break; 166 if (distance == 0) break;
170 } 167 }
171 Next(); 168 Next();
172 } 169 }
173 return closest_break; 170 return closest_break;
174 } 171 }
175 172
176 CodeBreakIterator::CodeBreakIterator(Handle<DebugInfo> debug_info, 173 CodeBreakIterator::CodeBreakIterator(Handle<DebugInfo> debug_info)
177 BreakLocatorType type) 174 : BreakIterator(debug_info),
178 : BreakIterator(debug_info, type), 175 reloc_iterator_(debug_info->DebugCode(), GetModeMask()),
179 reloc_iterator_(debug_info->DebugCode(), GetModeMask(type)),
180 source_position_iterator_( 176 source_position_iterator_(
181 debug_info->DebugCode()->source_position_table()) { 177 debug_info->DebugCode()->source_position_table()) {
182 // There is at least one break location. 178 // There is at least one break location.
183 DCHECK(!Done()); 179 DCHECK(!Done());
184 Next(); 180 Next();
185 } 181 }
186 182
187 int CodeBreakIterator::GetModeMask(BreakLocatorType type) { 183 int CodeBreakIterator::GetModeMask() {
188 int mask = 0; 184 int mask = 0;
189 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_RETURN); 185 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_RETURN);
190 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_CALL); 186 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_CALL);
191 if (isolate()->is_tail_call_elimination_enabled()) { 187 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_TAIL_CALL);
jgruber 2017/01/30 15:42:17 Is TCE now enabled by default? Or why is this now
Yang 2017/01/30 19:47:19 If TCE is not enabled, the emitted code will not h
192 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_TAIL_CALL); 188 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION);
193 } 189 mask |= RelocInfo::ModeMask(RelocInfo::DEBUGGER_STATEMENT);
194 if (type == ALL_BREAK_LOCATIONS) {
195 mask |= RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT_AT_POSITION);
196 mask |= RelocInfo::ModeMask(RelocInfo::DEBUGGER_STATEMENT);
197 }
198 return mask; 190 return mask;
199 } 191 }
200 192
201 void CodeBreakIterator::Next() { 193 void CodeBreakIterator::Next() {
202 DisallowHeapAllocation no_gc; 194 DisallowHeapAllocation no_gc;
203 DCHECK(!Done()); 195 DCHECK(!Done());
204 196
205 // Iterate through reloc info stopping at each breakable code target. 197 // Iterate through reloc info stopping at each breakable code target.
206 bool first = break_index_ == -1; 198 bool first = break_index_ == -1;
207 199
(...skipping 29 matching lines...) Expand all
237 return DEBUGGER_STATEMENT; 229 return DEBUGGER_STATEMENT;
238 } else if (RelocInfo::IsDebugBreakSlot(rmode())) { 230 } else if (RelocInfo::IsDebugBreakSlot(rmode())) {
239 return DEBUG_BREAK_SLOT; 231 return DEBUG_BREAK_SLOT;
240 } else { 232 } else {
241 return NOT_DEBUG_BREAK; 233 return NOT_DEBUG_BREAK;
242 } 234 }
243 } 235 }
244 236
245 void CodeBreakIterator::SkipToPosition(int position, 237 void CodeBreakIterator::SkipToPosition(int position,
246 BreakPositionAlignment alignment) { 238 BreakPositionAlignment alignment) {
247 CodeBreakIterator it(debug_info_, break_locator_type_); 239 CodeBreakIterator it(debug_info_);
248 SkipTo(it.BreakIndexFromPosition(position, alignment)); 240 SkipTo(it.BreakIndexFromPosition(position, alignment));
249 } 241 }
250 242
251 void CodeBreakIterator::SetDebugBreak() { 243 void CodeBreakIterator::SetDebugBreak() {
252 DebugBreakType debug_break_type = GetDebugBreakType(); 244 DebugBreakType debug_break_type = GetDebugBreakType();
253 if (debug_break_type == DEBUGGER_STATEMENT) return; 245 if (debug_break_type == DEBUGGER_STATEMENT) return;
254 DCHECK(debug_break_type >= DEBUG_BREAK_SLOT); 246 DCHECK(debug_break_type >= DEBUG_BREAK_SLOT);
255 Builtins* builtins = isolate()->builtins(); 247 Builtins* builtins = isolate()->builtins();
256 Handle<Code> target = debug_break_type == DEBUG_BREAK_SLOT_AT_RETURN 248 Handle<Code> target = debug_break_type == DEBUG_BREAK_SLOT_AT_RETURN
257 ? builtins->Return_DebugBreak() 249 ? builtins->Return_DebugBreak()
(...skipping 14 matching lines...) Expand all
272 DCHECK(debug_break_type >= DEBUG_BREAK_SLOT); 264 DCHECK(debug_break_type >= DEBUG_BREAK_SLOT);
273 return DebugCodegen::DebugBreakSlotIsPatched(rinfo()->pc()); 265 return DebugCodegen::DebugBreakSlotIsPatched(rinfo()->pc());
274 } 266 }
275 267
276 BreakLocation CodeBreakIterator::GetBreakLocation() { 268 BreakLocation CodeBreakIterator::GetBreakLocation() {
277 Handle<AbstractCode> code(AbstractCode::cast(debug_info_->DebugCode())); 269 Handle<AbstractCode> code(AbstractCode::cast(debug_info_->DebugCode()));
278 return BreakLocation(code, GetDebugBreakType(), code_offset(), position_); 270 return BreakLocation(code, GetDebugBreakType(), code_offset(), position_);
279 } 271 }
280 272
281 BytecodeArrayBreakIterator::BytecodeArrayBreakIterator( 273 BytecodeArrayBreakIterator::BytecodeArrayBreakIterator(
282 Handle<DebugInfo> debug_info, BreakLocatorType type) 274 Handle<DebugInfo> debug_info)
283 : BreakIterator(debug_info, type), 275 : BreakIterator(debug_info),
284 source_position_iterator_( 276 source_position_iterator_(
285 debug_info->DebugBytecodeArray()->source_position_table()) { 277 debug_info->DebugBytecodeArray()->source_position_table()) {
286 // There is at least one break location. 278 // There is at least one break location.
287 DCHECK(!Done()); 279 DCHECK(!Done());
288 Next(); 280 Next();
289 } 281 }
290 282
291 void BytecodeArrayBreakIterator::Next() { 283 void BytecodeArrayBreakIterator::Next() {
292 DisallowHeapAllocation no_gc; 284 DisallowHeapAllocation no_gc;
293 DCHECK(!Done()); 285 DCHECK(!Done());
294 bool first = break_index_ == -1; 286 bool first = break_index_ == -1;
295 while (!Done()) { 287 while (!Done()) {
296 if (!first) source_position_iterator_.Advance(); 288 if (!first) source_position_iterator_.Advance();
297 first = false; 289 first = false;
298 if (Done()) return; 290 if (Done()) return;
299 position_ = source_position_iterator_.source_position().ScriptOffset(); 291 position_ = source_position_iterator_.source_position().ScriptOffset();
300 if (source_position_iterator_.is_statement()) { 292 if (source_position_iterator_.is_statement()) {
301 statement_position_ = position_; 293 statement_position_ = position_;
302 } 294 }
303 DCHECK(position_ >= 0); 295 DCHECK(position_ >= 0);
304 DCHECK(statement_position_ >= 0); 296 DCHECK(statement_position_ >= 0);
305 297
306 DebugBreakType type = GetDebugBreakType(); 298 DebugBreakType type = GetDebugBreakType();
307 if (type == NOT_DEBUG_BREAK) continue; 299 if (type != NOT_DEBUG_BREAK) break;
308
309 if (break_locator_type_ == ALL_BREAK_LOCATIONS) break;
310
311 DCHECK_EQ(CALLS_AND_RETURNS, break_locator_type_);
312 if (type == DEBUG_BREAK_SLOT_AT_CALL) break;
313 if (type == DEBUG_BREAK_SLOT_AT_RETURN) break;
314 } 300 }
315 break_index_++; 301 break_index_++;
316 } 302 }
317 303
318 DebugBreakType BytecodeArrayBreakIterator::GetDebugBreakType() { 304 DebugBreakType BytecodeArrayBreakIterator::GetDebugBreakType() {
319 BytecodeArray* bytecode_array = debug_info_->OriginalBytecodeArray(); 305 BytecodeArray* bytecode_array = debug_info_->OriginalBytecodeArray();
320 interpreter::Bytecode bytecode = 306 interpreter::Bytecode bytecode =
321 interpreter::Bytecodes::FromByte(bytecode_array->get(code_offset())); 307 interpreter::Bytecodes::FromByte(bytecode_array->get(code_offset()));
322 308
323 if (bytecode == interpreter::Bytecode::kDebugger) { 309 if (bytecode == interpreter::Bytecode::kDebugger) {
324 return DEBUGGER_STATEMENT; 310 return DEBUGGER_STATEMENT;
325 } else if (bytecode == interpreter::Bytecode::kReturn) { 311 } else if (bytecode == interpreter::Bytecode::kReturn) {
326 return DEBUG_BREAK_SLOT_AT_RETURN; 312 return DEBUG_BREAK_SLOT_AT_RETURN;
327 } else if (bytecode == interpreter::Bytecode::kTailCall) { 313 } else if (bytecode == interpreter::Bytecode::kTailCall) {
328 return isolate()->is_tail_call_elimination_enabled() 314 return isolate()->is_tail_call_elimination_enabled()
329 ? DEBUG_BREAK_SLOT_AT_TAIL_CALL 315 ? DEBUG_BREAK_SLOT_AT_TAIL_CALL
330 : DEBUG_BREAK_SLOT_AT_CALL; 316 : DEBUG_BREAK_SLOT_AT_CALL;
331 } else if (interpreter::Bytecodes::IsCallOrNew(bytecode)) { 317 } else if (interpreter::Bytecodes::IsCallOrNew(bytecode)) {
332 return DEBUG_BREAK_SLOT_AT_CALL; 318 return DEBUG_BREAK_SLOT_AT_CALL;
333 } else if (source_position_iterator_.is_statement()) { 319 } else if (source_position_iterator_.is_statement()) {
334 return DEBUG_BREAK_SLOT; 320 return DEBUG_BREAK_SLOT;
335 } else { 321 } else {
336 return NOT_DEBUG_BREAK; 322 return NOT_DEBUG_BREAK;
337 } 323 }
338 } 324 }
339 325
340 void BytecodeArrayBreakIterator::SkipToPosition( 326 void BytecodeArrayBreakIterator::SkipToPosition(
341 int position, BreakPositionAlignment alignment) { 327 int position, BreakPositionAlignment alignment) {
342 BytecodeArrayBreakIterator it(debug_info_, break_locator_type_); 328 BytecodeArrayBreakIterator it(debug_info_);
343 SkipTo(it.BreakIndexFromPosition(position, alignment)); 329 SkipTo(it.BreakIndexFromPosition(position, alignment));
344 } 330 }
345 331
346 void BytecodeArrayBreakIterator::SetDebugBreak() { 332 void BytecodeArrayBreakIterator::SetDebugBreak() {
347 DebugBreakType debug_break_type = GetDebugBreakType(); 333 DebugBreakType debug_break_type = GetDebugBreakType();
348 if (debug_break_type == DEBUGGER_STATEMENT) return; 334 if (debug_break_type == DEBUGGER_STATEMENT) return;
349 DCHECK(debug_break_type >= DEBUG_BREAK_SLOT); 335 DCHECK(debug_break_type >= DEBUG_BREAK_SLOT);
350 BytecodeArray* bytecode_array = debug_info_->DebugBytecodeArray(); 336 BytecodeArray* bytecode_array = debug_info_->DebugBytecodeArray();
351 interpreter::Bytecode bytecode = 337 interpreter::Bytecode bytecode =
352 interpreter::Bytecodes::FromByte(bytecode_array->get(code_offset())); 338 interpreter::Bytecodes::FromByte(bytecode_array->get(code_offset()));
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 } 378 }
393 379
394 380
395 // Threading support. 381 // Threading support.
396 void Debug::ThreadInit() { 382 void Debug::ThreadInit() {
397 thread_local_.break_count_ = 0; 383 thread_local_.break_count_ = 0;
398 thread_local_.break_id_ = 0; 384 thread_local_.break_id_ = 0;
399 thread_local_.break_frame_id_ = StackFrame::NO_ID; 385 thread_local_.break_frame_id_ = StackFrame::NO_ID;
400 thread_local_.last_step_action_ = StepNone; 386 thread_local_.last_step_action_ = StepNone;
401 thread_local_.last_statement_position_ = kNoSourcePosition; 387 thread_local_.last_statement_position_ = kNoSourcePosition;
402 thread_local_.last_fp_ = 0; 388 thread_local_.last_frame_count_ = -1;
403 thread_local_.target_fp_ = 0; 389 thread_local_.target_frame_count_ = -1;
404 thread_local_.return_value_ = Handle<Object>(); 390 thread_local_.return_value_ = Handle<Object>();
405 thread_local_.async_task_count_ = 0; 391 thread_local_.async_task_count_ = 0;
406 clear_suspended_generator(); 392 clear_suspended_generator();
407 // TODO(isolates): frames_are_dropped_? 393 // TODO(isolates): frames_are_dropped_?
408 base::NoBarrier_Store(&thread_local_.current_debug_scope_, 394 base::NoBarrier_Store(&thread_local_.current_debug_scope_,
409 static_cast<base::AtomicWord>(0)); 395 static_cast<base::AtomicWord>(0));
410 UpdateHookOnFunctionCall(); 396 UpdateHookOnFunctionCall();
411 } 397 }
412 398
413 399
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 // Enter the debugger. 493 // Enter the debugger.
508 DebugScope debug_scope(this); 494 DebugScope debug_scope(this);
509 if (debug_scope.failed()) return; 495 if (debug_scope.failed()) return;
510 496
511 // Postpone interrupt during breakpoint processing. 497 // Postpone interrupt during breakpoint processing.
512 PostponeInterruptsScope postpone(isolate_); 498 PostponeInterruptsScope postpone(isolate_);
513 499
514 // Return if we fail to retrieve debug info. 500 // Return if we fail to retrieve debug info.
515 Handle<JSFunction> function(frame->function()); 501 Handle<JSFunction> function(frame->function());
516 Handle<SharedFunctionInfo> shared(function->shared()); 502 Handle<SharedFunctionInfo> shared(function->shared());
517 if (!EnsureDebugInfo(shared, function)) return; 503 if (!EnsureDebugInfo(shared)) return;
518 Handle<DebugInfo> debug_info(shared->GetDebugInfo(), isolate_); 504 Handle<DebugInfo> debug_info(shared->GetDebugInfo(), isolate_);
519 505
520 // Find the break location where execution has stopped. 506 // Find the break location where execution has stopped.
521 BreakLocation location = BreakLocation::FromFrame(debug_info, frame); 507 BreakLocation location = BreakLocation::FromFrame(debug_info, frame);
522 508
523 // Find actual break points, if any, and trigger debug break event. 509 // Find actual break points, if any, and trigger debug break event.
524 MaybeHandle<FixedArray> break_points_hit = 510 MaybeHandle<FixedArray> break_points_hit =
525 CheckBreakPoints(debug_info, &location); 511 CheckBreakPoints(debug_info, &location);
526 if (!break_points_hit.is_null()) { 512 if (!break_points_hit.is_null()) {
527 // Clear all current stepping setup. 513 // Clear all current stepping setup.
528 ClearStepping(); 514 ClearStepping();
529 // Notify the debug event listeners. 515 // Notify the debug event listeners.
530 Handle<JSArray> jsarr = isolate_->factory()->NewJSArrayWithElements( 516 Handle<JSArray> jsarr = isolate_->factory()->NewJSArrayWithElements(
531 break_points_hit.ToHandleChecked()); 517 break_points_hit.ToHandleChecked());
532 OnDebugBreak(jsarr); 518 OnDebugBreak(jsarr);
533 return; 519 return;
534 } 520 }
535 521
536 // No break point. Check for stepping. 522 // No break point. Check for stepping.
537 StepAction step_action = last_step_action(); 523 StepAction step_action = last_step_action();
538 Address current_fp = frame->UnpaddedFP(); 524 int current_frame_count = CurrentFrameCount();
539 Address target_fp = thread_local_.target_fp_; 525 int target_frame_count = thread_local_.target_frame_count_;
540 Address last_fp = thread_local_.last_fp_; 526 int last_frame_count = thread_local_.last_frame_count_;
541 527
542 bool step_break = false; 528 bool step_break = false;
543 switch (step_action) { 529 switch (step_action) {
544 case StepNone: 530 case StepNone:
545 return; 531 return;
546 case StepOut: 532 case StepOut:
547 // Step out has not reached the target frame yet. 533 // Step out should not break in a deeper frame than target frame.
548 if (current_fp < target_fp) return; 534 if (current_frame_count > target_frame_count) return;
549 step_break = true; 535 step_break = true;
550 break; 536 break;
551 case StepNext: 537 case StepNext:
552 // Step next should not break in a deeper frame. 538 // Step next should not break in a deeper frame than target frame.
553 if (current_fp < target_fp) return; 539 if (current_frame_count > target_frame_count) return;
554 // For step-next, a tail call is like a return and should break. 540 // For step-next, a tail call is like a return and should break.
555 step_break = location.IsTailCall(); 541 step_break = location.IsTailCall();
556 // Fall through. 542 // Fall through.
557 case StepIn: { 543 case StepIn: {
558 FrameSummary summary = FrameSummary::GetTop(frame); 544 FrameSummary summary = FrameSummary::GetTop(frame);
559 step_break = step_break || location.IsReturn() || current_fp != last_fp || 545 step_break = step_break || location.IsReturn() ||
546 current_frame_count != last_frame_count ||
560 thread_local_.last_statement_position_ != 547 thread_local_.last_statement_position_ !=
561 summary.SourceStatementPosition(); 548 summary.SourceStatementPosition();
562 break; 549 break;
563 } 550 }
564 } 551 }
565 552
566 // Clear all current stepping setup. 553 // Clear all current stepping setup.
567 ClearStepping(); 554 ClearStepping();
568 555
569 if (step_break) { 556 if (step_break) {
(...skipping 17 matching lines...) Expand all
587 if (has_break_points) *has_break_points = has_break_points_to_check; 574 if (has_break_points) *has_break_points = has_break_points_to_check;
588 if (!has_break_points_to_check) return {}; 575 if (!has_break_points_to_check) return {};
589 576
590 Handle<Object> break_point_objects = 577 Handle<Object> break_point_objects =
591 debug_info->GetBreakPointObjects(location->position()); 578 debug_info->GetBreakPointObjects(location->position());
592 return Debug::GetHitBreakPointObjects(break_point_objects); 579 return Debug::GetHitBreakPointObjects(break_point_objects);
593 } 580 }
594 581
595 582
596 bool Debug::IsMutedAtCurrentLocation(JavaScriptFrame* frame) { 583 bool Debug::IsMutedAtCurrentLocation(JavaScriptFrame* frame) {
584 HandleScope scope(isolate_);
597 // A break location is considered muted if break locations on the current 585 // A break location is considered muted if break locations on the current
598 // statement have at least one break point, and all of these break points 586 // statement have at least one break point, and all of these break points
599 // evaluate to false. Aside from not triggering a debug break event at the 587 // evaluate to false. Aside from not triggering a debug break event at the
600 // break location, we also do not trigger one for debugger statements, nor 588 // break location, we also do not trigger one for debugger statements, nor
601 // an exception event on exception at this location. 589 // an exception event on exception at this location.
602 Object* fun = frame->function(); 590 FrameSummary summary = FrameSummary::GetTop(frame);
603 if (!fun->IsJSFunction()) return false; 591 DCHECK(!summary.IsWasm());
604 JSFunction* function = JSFunction::cast(fun); 592 Handle<JSFunction> function = summary.AsJavaScript().function();
605 if (!function->shared()->HasDebugInfo()) return false; 593 if (!function->shared()->HasDebugInfo()) return false;
606 HandleScope scope(isolate_);
607 Handle<DebugInfo> debug_info(function->shared()->GetDebugInfo()); 594 Handle<DebugInfo> debug_info(function->shared()->GetDebugInfo());
608 // Enter the debugger. 595 // Enter the debugger.
609 DebugScope debug_scope(this); 596 DebugScope debug_scope(this);
610 if (debug_scope.failed()) return false; 597 if (debug_scope.failed()) return false;
611 List<BreakLocation> break_locations; 598 List<BreakLocation> break_locations;
612 BreakLocation::AllAtCurrentStatement(debug_info, frame, &break_locations); 599 BreakLocation::AllAtCurrentStatement(debug_info, frame, &break_locations);
613 bool has_break_points_at_all = false; 600 bool has_break_points_at_all = false;
614 for (int i = 0; i < break_locations.length(); i++) { 601 for (int i = 0; i < break_locations.length(); i++) {
615 bool has_break_points; 602 bool has_break_points;
616 MaybeHandle<FixedArray> check_result = 603 MaybeHandle<FixedArray> check_result =
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 } 649 }
663 650
664 651
665 bool Debug::SetBreakPoint(Handle<JSFunction> function, 652 bool Debug::SetBreakPoint(Handle<JSFunction> function,
666 Handle<Object> break_point_object, 653 Handle<Object> break_point_object,
667 int* source_position) { 654 int* source_position) {
668 HandleScope scope(isolate_); 655 HandleScope scope(isolate_);
669 656
670 // Make sure the function is compiled and has set up the debug info. 657 // Make sure the function is compiled and has set up the debug info.
671 Handle<SharedFunctionInfo> shared(function->shared()); 658 Handle<SharedFunctionInfo> shared(function->shared());
672 if (!EnsureDebugInfo(shared, function)) { 659 if (!EnsureDebugInfo(shared)) return true;
673 // Return if retrieving debug info failed.
674 return true;
675 }
676
677 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 660 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
678 // Source positions starts with zero. 661 // Source positions starts with zero.
679 DCHECK(*source_position >= 0); 662 DCHECK(*source_position >= 0);
680 663
681 // Find the break point and change it. 664 // Find the break point and change it.
682 *source_position = 665 *source_position =
683 FindBreakablePosition(debug_info, *source_position, STATEMENT_ALIGNED); 666 FindBreakablePosition(debug_info, *source_position, STATEMENT_ALIGNED);
684 DebugInfo::SetBreakPoint(debug_info, *source_position, break_point_object); 667 DebugInfo::SetBreakPoint(debug_info, *source_position, break_point_object);
685 // At least one active break point now. 668 // At least one active break point now.
686 DCHECK(debug_info->GetBreakPointCount() > 0); 669 DCHECK(debug_info->GetBreakPointCount() > 0);
(...skipping 19 matching lines...) Expand all
706 689
707 HandleScope scope(isolate_); 690 HandleScope scope(isolate_);
708 691
709 // Obtain shared function info for the function. 692 // Obtain shared function info for the function.
710 Handle<Object> result = 693 Handle<Object> result =
711 FindSharedFunctionInfoInScript(script, *source_position); 694 FindSharedFunctionInfoInScript(script, *source_position);
712 if (result->IsUndefined(isolate_)) return false; 695 if (result->IsUndefined(isolate_)) return false;
713 696
714 // Make sure the function has set up the debug info. 697 // Make sure the function has set up the debug info.
715 Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(result); 698 Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(result);
716 if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) { 699 if (!EnsureDebugInfo(shared)) return false;
717 // Return if retrieving debug info failed.
718 return false;
719 }
720 700
721 // Find position within function. The script position might be before the 701 // Find position within function. The script position might be before the
722 // source position of the first function. 702 // source position of the first function.
723 if (shared->start_position() > *source_position) { 703 if (shared->start_position() > *source_position) {
724 *source_position = shared->start_position(); 704 *source_position = shared->start_position();
725 } 705 }
726 706
727 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 707 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
728 708
729 // Find the break point and change it. 709 // Find the break point and change it.
730 *source_position = 710 *source_position =
731 FindBreakablePosition(debug_info, *source_position, alignment); 711 FindBreakablePosition(debug_info, *source_position, alignment);
732 DebugInfo::SetBreakPoint(debug_info, *source_position, break_point_object); 712 DebugInfo::SetBreakPoint(debug_info, *source_position, break_point_object);
733 // At least one active break point now. 713 // At least one active break point now.
734 DCHECK(debug_info->GetBreakPointCount() > 0); 714 DCHECK(debug_info->GetBreakPointCount() > 0);
735 715
736 ClearBreakPoints(debug_info); 716 ClearBreakPoints(debug_info);
737 ApplyBreakPoints(debug_info); 717 ApplyBreakPoints(debug_info);
738 718
739 feature_tracker()->Track(DebugFeatureTracker::kBreakPoint); 719 feature_tracker()->Track(DebugFeatureTracker::kBreakPoint);
740 return true; 720 return true;
741 } 721 }
742 722
743 int Debug::FindBreakablePosition(Handle<DebugInfo> debug_info, 723 int Debug::FindBreakablePosition(Handle<DebugInfo> debug_info,
744 int source_position, 724 int source_position,
745 BreakPositionAlignment alignment) { 725 BreakPositionAlignment alignment) {
746 int statement_position; 726 int statement_position;
747 int position; 727 int position;
748 if (debug_info->HasDebugCode()) { 728 if (debug_info->HasDebugCode()) {
749 CodeBreakIterator it(debug_info, ALL_BREAK_LOCATIONS); 729 CodeBreakIterator it(debug_info);
750 it.SkipToPosition(source_position, alignment); 730 it.SkipToPosition(source_position, alignment);
751 statement_position = it.statement_position(); 731 statement_position = it.statement_position();
752 position = it.position(); 732 position = it.position();
753 } else { 733 } else {
754 DCHECK(debug_info->HasDebugBytecodeArray()); 734 DCHECK(debug_info->HasDebugBytecodeArray());
755 BytecodeArrayBreakIterator it(debug_info, ALL_BREAK_LOCATIONS); 735 BytecodeArrayBreakIterator it(debug_info);
756 it.SkipToPosition(source_position, alignment); 736 it.SkipToPosition(source_position, alignment);
757 statement_position = it.statement_position(); 737 statement_position = it.statement_position();
758 position = it.position(); 738 position = it.position();
759 } 739 }
760 return alignment == STATEMENT_ALIGNED ? statement_position : position; 740 return alignment == STATEMENT_ALIGNED ? statement_position : position;
761 } 741 }
762 742
763 void Debug::ApplyBreakPoints(Handle<DebugInfo> debug_info) { 743 void Debug::ApplyBreakPoints(Handle<DebugInfo> debug_info) {
764 DisallowHeapAllocation no_gc; 744 DisallowHeapAllocation no_gc;
765 if (debug_info->break_points()->IsUndefined(isolate_)) return; 745 if (debug_info->break_points()->IsUndefined(isolate_)) return;
766 FixedArray* break_points = debug_info->break_points(); 746 FixedArray* break_points = debug_info->break_points();
767 for (int i = 0; i < break_points->length(); i++) { 747 for (int i = 0; i < break_points->length(); i++) {
768 if (break_points->get(i)->IsUndefined(isolate_)) continue; 748 if (break_points->get(i)->IsUndefined(isolate_)) continue;
769 BreakPointInfo* info = BreakPointInfo::cast(break_points->get(i)); 749 BreakPointInfo* info = BreakPointInfo::cast(break_points->get(i));
770 if (info->GetBreakPointCount() == 0) continue; 750 if (info->GetBreakPointCount() == 0) continue;
771 if (debug_info->HasDebugCode()) { 751 if (debug_info->HasDebugCode()) {
772 CodeBreakIterator it(debug_info, ALL_BREAK_LOCATIONS); 752 CodeBreakIterator it(debug_info);
773 it.SkipToPosition(info->source_position(), BREAK_POSITION_ALIGNED); 753 it.SkipToPosition(info->source_position(), BREAK_POSITION_ALIGNED);
774 it.SetDebugBreak(); 754 it.SetDebugBreak();
775 } 755 }
776 if (debug_info->HasDebugBytecodeArray()) { 756 if (debug_info->HasDebugBytecodeArray()) {
777 BytecodeArrayBreakIterator it(debug_info, ALL_BREAK_LOCATIONS); 757 BytecodeArrayBreakIterator it(debug_info);
778 it.SkipToPosition(info->source_position(), BREAK_POSITION_ALIGNED); 758 it.SkipToPosition(info->source_position(), BREAK_POSITION_ALIGNED);
779 it.SetDebugBreak(); 759 it.SetDebugBreak();
780 } 760 }
781 } 761 }
782 } 762 }
783 763
784 void Debug::ClearBreakPoints(Handle<DebugInfo> debug_info) { 764 void Debug::ClearBreakPoints(Handle<DebugInfo> debug_info) {
785 DisallowHeapAllocation no_gc; 765 DisallowHeapAllocation no_gc;
786 if (debug_info->HasDebugCode()) { 766 if (debug_info->HasDebugCode()) {
787 for (CodeBreakIterator it(debug_info, ALL_BREAK_LOCATIONS); !it.Done(); 767 for (CodeBreakIterator it(debug_info); !it.Done(); it.Next()) {
788 it.Next()) {
789 it.ClearDebugBreak(); 768 it.ClearDebugBreak();
790 } 769 }
791 } 770 }
792 if (debug_info->HasDebugBytecodeArray()) { 771 if (debug_info->HasDebugBytecodeArray()) {
793 for (BytecodeArrayBreakIterator it(debug_info, ALL_BREAK_LOCATIONS); 772 for (BytecodeArrayBreakIterator it(debug_info); !it.Done(); it.Next()) {
794 !it.Done(); it.Next()) {
795 it.ClearDebugBreak(); 773 it.ClearDebugBreak();
796 } 774 }
797 } 775 }
798 } 776 }
799 777
800 void Debug::ClearBreakPoint(Handle<Object> break_point_object) { 778 void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
801 HandleScope scope(isolate_); 779 HandleScope scope(isolate_);
802 780
803 for (DebugInfoListNode* node = debug_info_list_; node != NULL; 781 for (DebugInfoListNode* node = debug_info_list_; node != NULL;
804 node = node->next()) { 782 node = node->next()) {
(...skipping 20 matching lines...) Expand all
825 for (DebugInfoListNode* node = debug_info_list_; node != NULL; 803 for (DebugInfoListNode* node = debug_info_list_; node != NULL;
826 node = node->next()) { 804 node = node->next()) {
827 ClearBreakPoints(node->debug_info()); 805 ClearBreakPoints(node->debug_info());
828 } 806 }
829 // Remove all debug info. 807 // Remove all debug info.
830 while (debug_info_list_ != NULL) { 808 while (debug_info_list_ != NULL) {
831 RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info()); 809 RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info());
832 } 810 }
833 } 811 }
834 812
835 void Debug::FloodWithOneShot(Handle<JSFunction> function, 813 void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) {
836 BreakLocatorType type) { 814 if (!shared->IsSubjectToDebugging() || IsBlackboxed(shared)) return;
837 // Debug utility functions are not subject to debugging.
838 if (function->native_context() == *debug_context()) return;
839
840 if (!function->shared()->IsSubjectToDebugging() ||
841 IsBlackboxed(function->shared())) {
842 // Builtin functions are not subject to stepping, but need to be
843 // deoptimized, because optimized code does not check for debug
844 // step in at call sites.
845 Deoptimizer::DeoptimizeFunction(*function);
846 return;
847 }
848 // Make sure the function is compiled and has set up the debug info. 815 // Make sure the function is compiled and has set up the debug info.
849 Handle<SharedFunctionInfo> shared(function->shared()); 816 if (!EnsureDebugInfo(shared)) return;
850 if (!EnsureDebugInfo(shared, function)) { 817 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
851 // Return if we failed to retrieve the debug info.
852 return;
853 }
854
855 // Flood the function with break points. 818 // Flood the function with break points.
856 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
857 if (debug_info->HasDebugCode()) { 819 if (debug_info->HasDebugCode()) {
858 for (CodeBreakIterator it(debug_info, type); !it.Done(); it.Next()) { 820 for (CodeBreakIterator it(debug_info); !it.Done(); it.Next()) {
859 it.SetDebugBreak(); 821 it.SetDebugBreak();
860 } 822 }
861 } 823 }
862 if (debug_info->HasDebugBytecodeArray()) { 824 if (debug_info->HasDebugBytecodeArray()) {
863 for (BytecodeArrayBreakIterator it(debug_info, type); !it.Done(); 825 for (BytecodeArrayBreakIterator it(debug_info); !it.Done(); it.Next()) {
864 it.Next()) {
865 it.SetDebugBreak(); 826 it.SetDebugBreak();
866 } 827 }
867 } 828 }
868 } 829 }
869 830
870 void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) { 831 void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) {
871 if (type == BreakUncaughtException) { 832 if (type == BreakUncaughtException) {
872 break_on_uncaught_exception_ = enable; 833 break_on_uncaught_exception_ = enable;
873 } else { 834 } else {
874 break_on_exception_ = enable; 835 break_on_exception_ = enable;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 if (break_points_hit_count == 0) return {}; 869 if (break_points_hit_count == 0) return {};
909 break_points_hit->Shrink(break_points_hit_count); 870 break_points_hit->Shrink(break_points_hit_count);
910 return break_points_hit; 871 return break_points_hit;
911 } 872 }
912 873
913 void Debug::PrepareStepIn(Handle<JSFunction> function) { 874 void Debug::PrepareStepIn(Handle<JSFunction> function) {
914 CHECK(last_step_action() >= StepIn); 875 CHECK(last_step_action() >= StepIn);
915 if (ignore_events()) return; 876 if (ignore_events()) return;
916 if (in_debug_scope()) return; 877 if (in_debug_scope()) return;
917 if (break_disabled()) return; 878 if (break_disabled()) return;
918 FloodWithOneShot(function); 879 FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared(), isolate_));
919 } 880 }
920 881
921 void Debug::PrepareStepInSuspendedGenerator() { 882 void Debug::PrepareStepInSuspendedGenerator() {
922 CHECK(has_suspended_generator()); 883 CHECK(has_suspended_generator());
923 if (ignore_events()) return; 884 if (ignore_events()) return;
924 if (in_debug_scope()) return; 885 if (in_debug_scope()) return;
925 if (break_disabled()) return; 886 if (break_disabled()) return;
926 thread_local_.last_step_action_ = StepIn; 887 thread_local_.last_step_action_ = StepIn;
927 UpdateHookOnFunctionCall(); 888 UpdateHookOnFunctionCall();
928 Handle<JSFunction> function( 889 Handle<JSFunction> function(
929 JSGeneratorObject::cast(thread_local_.suspended_generator_)->function()); 890 JSGeneratorObject::cast(thread_local_.suspended_generator_)->function());
930 FloodWithOneShot(function); 891 FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared(), isolate_));
931 clear_suspended_generator(); 892 clear_suspended_generator();
932 } 893 }
933 894
934 void Debug::PrepareStepOnThrow() { 895 void Debug::PrepareStepOnThrow() {
935 if (last_step_action() == StepNone) return; 896 if (last_step_action() == StepNone) return;
936 if (ignore_events()) return; 897 if (ignore_events()) return;
937 if (in_debug_scope()) return; 898 if (in_debug_scope()) return;
938 if (break_disabled()) return; 899 if (break_disabled()) return;
939 900
940 ClearOneShot(); 901 ClearOneShot();
941 902
903 int current_frame_count = CurrentFrameCount();
904
942 // Iterate through the JavaScript stack looking for handlers. 905 // Iterate through the JavaScript stack looking for handlers.
943 JavaScriptFrameIterator it(isolate_); 906 JavaScriptFrameIterator it(isolate_);
944 while (!it.done()) { 907 while (!it.done()) {
945 JavaScriptFrame* frame = it.frame(); 908 JavaScriptFrame* frame = it.frame();
946 if (frame->LookupExceptionHandlerInTable(nullptr, nullptr) > 0) break; 909 if (frame->LookupExceptionHandlerInTable(nullptr, nullptr) > 0) break;
910 List<SharedFunctionInfo*> infos;
911 frame->GetFunctions(&infos);
912 current_frame_count -= infos.length();
947 it.Advance(); 913 it.Advance();
948 } 914 }
949 915
950 if (last_step_action() == StepNext || last_step_action() == StepOut) { 916 // No handler found. Nothing to instrument.
951 while (!it.done()) { 917 if (it.done()) return;
952 Address current_fp = it.frame()->UnpaddedFP(); 918
953 if (current_fp >= thread_local_.target_fp_) break; 919 bool found_handler = false;
954 it.Advance(); 920 // Iterate frames, including inlined frames. First, find the handler frame.
921 // Then skip to the frame we want to break in, then instrument for stepping.
922 for (; !it.done(); it.Advance()) {
923 JavaScriptFrame* frame = JavaScriptFrame::cast(it.frame());
924 if (last_step_action() == StepIn) {
925 // Deoptimize frame to ensure calls are checked for step-in.
926 Deoptimizer::DeoptimizeFunction(frame->function());
927 }
928 List<FrameSummary> summaries;
929 frame->Summarize(&summaries);
930 for (int i = summaries.length() - 1; i >= 0; i--, current_frame_count--) {
931 if (!found_handler) {
932 // We have yet to find the handler. If the frame inlines multiple
933 // functions, we have to check each one for the handler.
934 // If it only contains one function, we already found the handler.
935 if (summaries.length() > 1) {
936 Handle<AbstractCode> code =
937 summaries[i].AsJavaScript().abstract_code();
938 CHECK_EQ(AbstractCode::INTERPRETED_FUNCTION, code->kind());
939 BytecodeArray* bytecode = code->GetBytecodeArray();
940 HandlerTable* table = HandlerTable::cast(bytecode->handler_table());
941 int code_offset = summaries[i].code_offset();
942 HandlerTable::CatchPrediction prediction;
943 int index = table->LookupRange(code_offset, nullptr, &prediction);
944 if (index > 0) found_handler = true;
945 } else {
946 found_handler = true;
947 }
948 }
949
950 if (found_handler) {
951 // We found the handler. If we are stepping next or out, we need to
952 // iterate until we found the suitable target frame to break in.
953 if ((last_step_action() == StepNext || last_step_action() == StepOut) &&
954 current_frame_count > thread_local_.target_frame_count_) {
955 continue;
956 }
957 Handle<SharedFunctionInfo> info(
958 summaries[i].AsJavaScript().function()->shared());
959 if (!info->IsSubjectToDebugging() || IsBlackboxed(info)) continue;
960 FloodWithOneShot(info);
961 return;
962 }
955 } 963 }
956 } 964 }
957
958 // Find the closest Javascript frame we can flood with one-shots.
959 while (!it.done() &&
960 (!it.frame()->function()->shared()->IsSubjectToDebugging() ||
961 IsBlackboxed(it.frame()->function()->shared()))) {
962 it.Advance();
963 }
964
965 if (it.done()) return; // No suitable Javascript catch handler.
966
967 FloodWithOneShot(Handle<JSFunction>(it.frame()->function()));
968 } 965 }
969 966
970 967
971 void Debug::PrepareStep(StepAction step_action) { 968 void Debug::PrepareStep(StepAction step_action) {
972 HandleScope scope(isolate_); 969 HandleScope scope(isolate_);
973 970
974 DCHECK(in_debug_scope()); 971 DCHECK(in_debug_scope());
975 972
976 // Get the frame where the execution has stopped and skip the debug frame if 973 // Get the frame where the execution has stopped and skip the debug frame if
977 // any. The debug frame will only be present if execution was stopped due to 974 // any. The debug frame will only be present if execution was stopped due to
978 // hitting a break point. In other situations (e.g. unhandled exception) the 975 // hitting a break point. In other situations (e.g. unhandled exception) the
979 // debug frame is not present. 976 // debug frame is not present.
980 StackFrame::Id frame_id = break_frame_id(); 977 StackFrame::Id frame_id = break_frame_id();
981 // If there is no JavaScript stack don't do anything. 978 // If there is no JavaScript stack don't do anything.
982 if (frame_id == StackFrame::NO_ID) return; 979 if (frame_id == StackFrame::NO_ID) return;
983 980
984 StackTraceFrameIterator frames_it(isolate_, frame_id);
985 StandardFrame* frame = frames_it.frame();
986
987 feature_tracker()->Track(DebugFeatureTracker::kStepping); 981 feature_tracker()->Track(DebugFeatureTracker::kStepping);
988 982
989 thread_local_.last_step_action_ = step_action; 983 thread_local_.last_step_action_ = step_action;
990 UpdateHookOnFunctionCall(); 984 UpdateHookOnFunctionCall();
991 985
986 StackTraceFrameIterator frames_it(isolate_, frame_id);
987 StandardFrame* frame = frames_it.frame();
988
992 // Handle stepping in wasm functions via the wasm interpreter. 989 // Handle stepping in wasm functions via the wasm interpreter.
993 if (frame->is_wasm()) { 990 if (frame->is_wasm()) {
994 // If the top frame is compiled, we cannot step. 991 // If the top frame is compiled, we cannot step.
995 if (frame->is_wasm_compiled()) return; 992 if (frame->is_wasm_compiled()) return;
996 WasmInterpreterEntryFrame* wasm_frame = 993 WasmInterpreterEntryFrame* wasm_frame =
997 WasmInterpreterEntryFrame::cast(frame); 994 WasmInterpreterEntryFrame::cast(frame);
998 wasm_frame->wasm_instance()->debug_info()->PrepareStep(step_action); 995 wasm_frame->wasm_instance()->debug_info()->PrepareStep(step_action);
999 return; 996 return;
1000 } 997 }
1001 998
1002 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame); 999 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame);
1003 1000 DCHECK(js_frame->function()->IsJSFunction());
1004 // If the function on the top frame is unresolved perform step out. This will
1005 // be the case when calling unknown function and having the debugger stopped
1006 // in an unhandled exception.
1007 if (!js_frame->function()->IsJSFunction()) {
1008 // Step out: Find the calling JavaScript frame and flood it with
1009 // breakpoints.
1010 frames_it.Advance();
1011 // Fill the function to return to with one-shot break points.
1012 JSFunction* function = JavaScriptFrame::cast(frames_it.frame())->function();
1013 FloodWithOneShot(handle(function, isolate_));
1014 return;
1015 }
1016 1001
1017 // Get the debug info (create it if it does not exist). 1002 // Get the debug info (create it if it does not exist).
1018 auto summary = FrameSummary::GetTop(frame).AsJavaScript(); 1003 auto summary = FrameSummary::GetTop(frame).AsJavaScript();
1019 Handle<JSFunction> function(summary.function()); 1004 Handle<JSFunction> function(summary.function());
1020 Handle<SharedFunctionInfo> shared(function->shared()); 1005 Handle<SharedFunctionInfo> shared(function->shared());
1021 if (!EnsureDebugInfo(shared, function)) { 1006 if (!EnsureDebugInfo(shared)) return;
1022 // Return if ensuring debug info failed. 1007 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1023 return;
1024 }
1025 1008
1026 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1027 BreakLocation location = BreakLocation::FromFrame(debug_info, js_frame); 1009 BreakLocation location = BreakLocation::FromFrame(debug_info, js_frame);
1028 1010
1029 // Any step at a return is a step-out. 1011 // Any step at a return is a step-out.
1030 if (location.IsReturn()) step_action = StepOut; 1012 if (location.IsReturn()) step_action = StepOut;
1031 // A step-next at a tail call is a step-out. 1013 // A step-next at a tail call is a step-out.
1032 if (location.IsTailCall() && step_action == StepNext) step_action = StepOut; 1014 if (location.IsTailCall() && step_action == StepNext) step_action = StepOut;
1033 // A step-next in blackboxed function is a step-out. 1015 // A step-next in blackboxed function is a step-out.
1034 if (step_action == StepNext && IsBlackboxed(shared)) step_action = StepOut; 1016 if (step_action == StepNext && IsBlackboxed(shared)) step_action = StepOut;
1035 1017
1036 thread_local_.last_statement_position_ = 1018 thread_local_.last_statement_position_ =
1037 summary.abstract_code()->SourceStatementPosition(summary.code_offset()); 1019 summary.abstract_code()->SourceStatementPosition(summary.code_offset());
1038 thread_local_.last_fp_ = frame->UnpaddedFP(); 1020 int current_frame_count = CurrentFrameCount();
1021 thread_local_.last_frame_count_ = current_frame_count;
1039 // No longer perform the current async step. 1022 // No longer perform the current async step.
1040 clear_suspended_generator(); 1023 clear_suspended_generator();
1041 1024
1042 switch (step_action) { 1025 switch (step_action) {
1043 case StepNone: 1026 case StepNone:
1044 UNREACHABLE(); 1027 UNREACHABLE();
1045 break; 1028 break;
1046 case StepOut: 1029 case StepOut: {
1047 // Advance to caller frame.
1048 frames_it.Advance();
1049 // Find top-most function which is subject to debugging.
1050 while (!frames_it.done()) {
1051 StandardFrame* caller_frame = frames_it.frame();
1052 if (caller_frame->is_wasm()) {
1053 // TODO(clemensh): Implement stepping out from JS to WASM.
1054 break;
1055 }
1056 Handle<JSFunction> js_caller_function(
1057 JavaScriptFrame::cast(caller_frame)->function(), isolate_);
1058 if (js_caller_function->shared()->IsSubjectToDebugging() &&
1059 !IsBlackboxed(js_caller_function->shared())) {
1060 // Fill the caller function to return to with one-shot break points.
1061 FloodWithOneShot(js_caller_function);
1062 thread_local_.target_fp_ = frames_it.frame()->UnpaddedFP();
1063 break;
1064 }
1065 // Builtin functions are not subject to stepping, but need to be
1066 // deoptimized to include checks for step-in at call sites.
1067 Deoptimizer::DeoptimizeFunction(*js_caller_function);
1068 frames_it.Advance();
1069 }
1070 // Clear last position info. For stepping out it does not matter. 1030 // Clear last position info. For stepping out it does not matter.
1071 thread_local_.last_statement_position_ = kNoSourcePosition; 1031 thread_local_.last_statement_position_ = kNoSourcePosition;
1072 thread_local_.last_fp_ = 0; 1032 thread_local_.last_frame_count_ = -1;
1033 // Skip the current frame, find the first frame we want to step out to
1034 // and deoptimize every frame along the way.
1035 bool in_current_frame = true;
1036 for (; !frames_it.done(); frames_it.Advance()) {
1037 // TODO(clemensh): Implement stepping out from JS to WASM.
1038 if (frames_it.frame()->is_wasm()) continue;
1039 JavaScriptFrame* frame = JavaScriptFrame::cast(frames_it.frame());
1040 if (last_step_action() == StepIn) {
1041 // Deoptimize frame to ensure calls are checked for step-in.
1042 Deoptimizer::DeoptimizeFunction(frame->function());
1043 }
1044 HandleScope scope(isolate_);
1045 List<Handle<SharedFunctionInfo>> infos;
1046 frame->GetFunctions(&infos);
1047 for (; !infos.is_empty(); current_frame_count--) {
1048 Handle<SharedFunctionInfo> info = infos.RemoveLast();
1049 if (in_current_frame) {
1050 // We want to skip out, so skip the current frame.
1051 in_current_frame = false;
1052 continue;
1053 }
1054 if (!info->IsSubjectToDebugging() || IsBlackboxed(info)) continue;
1055 FloodWithOneShot(info);
1056 thread_local_.target_frame_count_ = current_frame_count;
1057 return;
1058 }
1059 }
1073 break; 1060 break;
1061 }
1074 case StepNext: 1062 case StepNext:
1075 thread_local_.target_fp_ = frame->UnpaddedFP(); 1063 thread_local_.target_frame_count_ = current_frame_count;
1076 FloodWithOneShot(function); 1064 // Fall through.
1077 break;
1078 case StepIn: 1065 case StepIn:
1079 // TODO(clemensh): Implement stepping from JS into WASM. 1066 // TODO(clemensh): Implement stepping from JS into WASM.
1080 FloodWithOneShot(function); 1067 FloodWithOneShot(shared);
1081 break; 1068 break;
1082 } 1069 }
1083 } 1070 }
1084 1071
1085 // Simple function for returning the source positions for active break points. 1072 // Simple function for returning the source positions for active break points.
1086 Handle<Object> Debug::GetSourceBreakLocations( 1073 Handle<Object> Debug::GetSourceBreakLocations(
1087 Handle<SharedFunctionInfo> shared, 1074 Handle<SharedFunctionInfo> shared,
1088 BreakPositionAlignment position_alignment) { 1075 BreakPositionAlignment position_alignment) {
1089 Isolate* isolate = shared->GetIsolate(); 1076 Isolate* isolate = shared->GetIsolate();
1090 if (!shared->HasDebugInfo()) { 1077 if (!shared->HasDebugInfo()) {
1091 return isolate->factory()->undefined_value(); 1078 return isolate->factory()->undefined_value();
1092 } 1079 }
1093 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 1080 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1094 if (debug_info->GetBreakPointCount() == 0) { 1081 if (debug_info->GetBreakPointCount() == 0) {
1095 return isolate->factory()->undefined_value(); 1082 return isolate->factory()->undefined_value();
1096 } 1083 }
1097 Handle<FixedArray> locations = 1084 Handle<FixedArray> locations =
1098 isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount()); 1085 isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount());
1099 int count = 0; 1086 int count = 0;
1100 for (int i = 0; i < debug_info->break_points()->length(); ++i) { 1087 for (int i = 0; i < debug_info->break_points()->length(); ++i) {
1101 if (!debug_info->break_points()->get(i)->IsUndefined(isolate)) { 1088 if (!debug_info->break_points()->get(i)->IsUndefined(isolate)) {
1102 BreakPointInfo* break_point_info = 1089 BreakPointInfo* break_point_info =
1103 BreakPointInfo::cast(debug_info->break_points()->get(i)); 1090 BreakPointInfo::cast(debug_info->break_points()->get(i));
1104 int break_points = break_point_info->GetBreakPointCount(); 1091 int break_points = break_point_info->GetBreakPointCount();
1105 if (break_points == 0) continue; 1092 if (break_points == 0) continue;
1106 Smi* position = NULL; 1093 Smi* position = NULL;
1107 if (position_alignment == STATEMENT_ALIGNED) { 1094 if (position_alignment == STATEMENT_ALIGNED) {
1108 if (debug_info->HasDebugCode()) { 1095 if (debug_info->HasDebugCode()) {
1109 CodeBreakIterator it(debug_info, ALL_BREAK_LOCATIONS); 1096 CodeBreakIterator it(debug_info);
1110 it.SkipToPosition(break_point_info->source_position(), 1097 it.SkipToPosition(break_point_info->source_position(),
1111 BREAK_POSITION_ALIGNED); 1098 BREAK_POSITION_ALIGNED);
1112 position = Smi::FromInt(it.statement_position()); 1099 position = Smi::FromInt(it.statement_position());
1113 } else { 1100 } else {
1114 DCHECK(debug_info->HasDebugBytecodeArray()); 1101 DCHECK(debug_info->HasDebugBytecodeArray());
1115 BytecodeArrayBreakIterator it(debug_info, ALL_BREAK_LOCATIONS); 1102 BytecodeArrayBreakIterator it(debug_info);
1116 it.SkipToPosition(break_point_info->source_position(), 1103 it.SkipToPosition(break_point_info->source_position(),
1117 BREAK_POSITION_ALIGNED); 1104 BREAK_POSITION_ALIGNED);
1118 position = Smi::FromInt(it.statement_position()); 1105 position = Smi::FromInt(it.statement_position());
1119 } 1106 }
1120 } else { 1107 } else {
1121 DCHECK_EQ(BREAK_POSITION_ALIGNED, position_alignment); 1108 DCHECK_EQ(BREAK_POSITION_ALIGNED, position_alignment);
1122 position = Smi::FromInt(break_point_info->source_position()); 1109 position = Smi::FromInt(break_point_info->source_position());
1123 } 1110 }
1124 for (int j = 0; j < break_points; ++j) locations->set(count++, position); 1111 for (int j = 0; j < break_points; ++j) locations->set(count++, position);
1125 } 1112 }
1126 } 1113 }
1127 return locations; 1114 return locations;
1128 } 1115 }
1129 1116
1130 void Debug::ClearStepping() { 1117 void Debug::ClearStepping() {
1131 // Clear the various stepping setup. 1118 // Clear the various stepping setup.
1132 ClearOneShot(); 1119 ClearOneShot();
1133 1120
1134 thread_local_.last_step_action_ = StepNone; 1121 thread_local_.last_step_action_ = StepNone;
1135 thread_local_.last_statement_position_ = kNoSourcePosition; 1122 thread_local_.last_statement_position_ = kNoSourcePosition;
1136 thread_local_.last_fp_ = 0; 1123 thread_local_.last_frame_count_ = -1;
1137 thread_local_.target_fp_ = 0; 1124 thread_local_.target_frame_count_ = -1;
1138 UpdateHookOnFunctionCall(); 1125 UpdateHookOnFunctionCall();
1139 } 1126 }
1140 1127
1141 1128
1142 // Clears all the one-shot break points that are currently set. Normally this 1129 // Clears all the one-shot break points that are currently set. Normally this
1143 // function is called each time a break point is hit as one shot break points 1130 // function is called each time a break point is hit as one shot break points
1144 // are used to support stepping. 1131 // are used to support stepping.
1145 void Debug::ClearOneShot() { 1132 void Debug::ClearOneShot() {
1146 // The current implementation just runs through all the breakpoints. When the 1133 // The current implementation just runs through all the breakpoints. When the
1147 // last break point for a function is removed that function is automatically 1134 // last break point for a function is removed that function is automatically
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
1345 positions->insert(alignment == STATEMENT_ALIGNED ? it->statement_position() 1332 positions->insert(alignment == STATEMENT_ALIGNED ? it->statement_position()
1346 : it->position()); 1333 : it->position());
1347 it->Next(); 1334 it->Next();
1348 } 1335 }
1349 } 1336 }
1350 1337
1351 void FindBreakablePositions(Handle<DebugInfo> debug_info, int start_position, 1338 void FindBreakablePositions(Handle<DebugInfo> debug_info, int start_position,
1352 int end_position, BreakPositionAlignment alignment, 1339 int end_position, BreakPositionAlignment alignment,
1353 std::set<int>* positions) { 1340 std::set<int>* positions) {
1354 if (debug_info->HasDebugCode()) { 1341 if (debug_info->HasDebugCode()) {
1355 CodeBreakIterator it(debug_info, ALL_BREAK_LOCATIONS); 1342 CodeBreakIterator it(debug_info);
1356 GetBreakablePositions(&it, start_position, end_position, alignment, 1343 GetBreakablePositions(&it, start_position, end_position, alignment,
1357 positions); 1344 positions);
1358 } else { 1345 } else {
1359 DCHECK(debug_info->HasDebugBytecodeArray()); 1346 DCHECK(debug_info->HasDebugBytecodeArray());
1360 BytecodeArrayBreakIterator it(debug_info, ALL_BREAK_LOCATIONS); 1347 BytecodeArrayBreakIterator it(debug_info);
1361 GetBreakablePositions(&it, start_position, end_position, alignment, 1348 GetBreakablePositions(&it, start_position, end_position, alignment,
1362 positions); 1349 positions);
1363 } 1350 }
1364 } 1351 }
1365 } // namespace 1352 } // namespace
1366 1353
1367 bool Debug::GetPossibleBreakpoints(Handle<Script> script, int start_position, 1354 bool Debug::GetPossibleBreakpoints(Handle<Script> script, int start_position,
1368 int end_position, std::set<int>* positions) { 1355 int end_position, std::set<int>* positions) {
1369 while (true) { 1356 while (true) {
1370 HandleScope scope(isolate_); 1357 HandleScope scope(isolate_);
(...skipping 14 matching lines...) Expand all
1385 for (int i = 0; i < candidates.length(); ++i) { 1372 for (int i = 0; i < candidates.length(); ++i) {
1386 // Code that cannot be compiled lazily are internal and not debuggable. 1373 // Code that cannot be compiled lazily are internal and not debuggable.
1387 DCHECK(candidates[i]->allows_lazy_compilation()); 1374 DCHECK(candidates[i]->allows_lazy_compilation());
1388 if (!candidates[i]->HasDebugCode()) { 1375 if (!candidates[i]->HasDebugCode()) {
1389 if (!Compiler::CompileDebugCode(candidates[i])) { 1376 if (!Compiler::CompileDebugCode(candidates[i])) {
1390 return false; 1377 return false;
1391 } else { 1378 } else {
1392 was_compiled = true; 1379 was_compiled = true;
1393 } 1380 }
1394 } 1381 }
1395 if (!EnsureDebugInfo(candidates[i], Handle<JSFunction>::null())) 1382 if (!EnsureDebugInfo(candidates[i])) return false;
1396 return false;
1397 } 1383 }
1398 if (was_compiled) continue; 1384 if (was_compiled) continue;
1399 1385
1400 for (int i = 0; i < candidates.length(); ++i) { 1386 for (int i = 0; i < candidates.length(); ++i) {
1401 CHECK(candidates[i]->HasDebugInfo()); 1387 CHECK(candidates[i]->HasDebugInfo());
1402 Handle<DebugInfo> debug_info(candidates[i]->GetDebugInfo()); 1388 Handle<DebugInfo> debug_info(candidates[i]->GetDebugInfo());
1403 FindBreakablePositions(debug_info, start_position, end_position, 1389 FindBreakablePositions(debug_info, start_position, end_position,
1404 STATEMENT_ALIGNED, positions); 1390 STATEMENT_ALIGNED, positions);
1405 } 1391 }
1406 return true; 1392 return true;
1407 } 1393 }
1408 UNREACHABLE(); 1394 UNREACHABLE();
1409 return false; 1395 return false;
1410 } 1396 }
1411 1397
1412 void Debug::RecordGenerator(Handle<JSGeneratorObject> generator_object) { 1398 void Debug::RecordGenerator(Handle<JSGeneratorObject> generator_object) {
1413 if (last_step_action() <= StepOut) return; 1399 if (last_step_action() <= StepOut) return;
1414 1400
1415 if (last_step_action() == StepNext) { 1401 if (last_step_action() == StepNext) {
1416 // Only consider this generator a step-next target if not stepping in. 1402 // Only consider this generator a step-next target if not stepping in.
1417 JavaScriptFrameIterator stack_iterator(isolate_); 1403 if (thread_local_.target_frame_count_ < CurrentFrameCount()) return;
1418 JavaScriptFrame* frame = stack_iterator.frame();
1419 if (frame->UnpaddedFP() < thread_local_.target_fp_) return;
1420 } 1404 }
1421 1405
1422 DCHECK(!has_suspended_generator()); 1406 DCHECK(!has_suspended_generator());
1423 thread_local_.suspended_generator_ = *generator_object; 1407 thread_local_.suspended_generator_ = *generator_object;
1424 ClearStepping(); 1408 ClearStepping();
1425 } 1409 }
1426 1410
1427 class SharedFunctionInfoFinder { 1411 class SharedFunctionInfoFinder {
1428 public: 1412 public:
1429 explicit SharedFunctionInfoFinder(int target_position) 1413 explicit SharedFunctionInfoFinder(int target_position)
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1517 HandleScope scope(isolate_); 1501 HandleScope scope(isolate_);
1518 // Code that cannot be compiled lazily are internal and not debuggable. 1502 // Code that cannot be compiled lazily are internal and not debuggable.
1519 DCHECK(shared->allows_lazy_compilation()); 1503 DCHECK(shared->allows_lazy_compilation());
1520 if (!Compiler::CompileDebugCode(handle(shared))) break; 1504 if (!Compiler::CompileDebugCode(handle(shared))) break;
1521 } 1505 }
1522 return isolate_->factory()->undefined_value(); 1506 return isolate_->factory()->undefined_value();
1523 } 1507 }
1524 1508
1525 1509
1526 // Ensures the debug information is present for shared. 1510 // Ensures the debug information is present for shared.
1527 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared, 1511 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) {
1528 Handle<JSFunction> function) {
1529 if (!shared->IsSubjectToDebugging()) return false;
1530
1531 // Return if we already have the debug info for shared. 1512 // Return if we already have the debug info for shared.
1532 if (shared->HasDebugInfo()) return true; 1513 if (shared->HasDebugInfo()) return true;
1533 1514 if (!shared->IsSubjectToDebugging()) return false;
1534 if (function.is_null()) { 1515 if (!shared->is_compiled() && !Compiler::CompileDebugCode(shared)) {
1535 DCHECK(shared->HasDebugCode());
1536 } else if (!Compiler::Compile(function, Compiler::CLEAR_EXCEPTION)) {
1537 return false; 1516 return false;
1538 } 1517 }
1539 1518
1540 // To prepare bytecode for debugging, we already need to have the debug 1519 // To prepare bytecode for debugging, we already need to have the debug
1541 // info (containing the debug copy) upfront, but since we do not recompile, 1520 // info (containing the debug copy) upfront, but since we do not recompile,
1542 // preparing for break points cannot fail. 1521 // preparing for break points cannot fail.
1543 CreateDebugInfo(shared); 1522 CreateDebugInfo(shared);
1544 CHECK(PrepareFunctionForBreakPoints(shared)); 1523 CHECK(PrepareFunctionForBreakPoints(shared));
1545 return true; 1524 return true;
1546 } 1525 }
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1692 Handle<Smi> id) { 1671 Handle<Smi> id) {
1693 DCHECK(id->IsNumber()); 1672 DCHECK(id->IsNumber());
1694 // Create the async task event object. 1673 // Create the async task event object.
1695 Handle<Object> argv[] = {type, id}; 1674 Handle<Object> argv[] = {type, id};
1696 return CallFunction("MakeAsyncTaskEvent", arraysize(argv), argv); 1675 return CallFunction("MakeAsyncTaskEvent", arraysize(argv), argv);
1697 } 1676 }
1698 1677
1699 1678
1700 void Debug::OnThrow(Handle<Object> exception) { 1679 void Debug::OnThrow(Handle<Object> exception) {
1701 if (in_debug_scope() || ignore_events()) return; 1680 if (in_debug_scope() || ignore_events()) return;
1702 PrepareStepOnThrow();
1703 // Temporarily clear any scheduled_exception to allow evaluating 1681 // Temporarily clear any scheduled_exception to allow evaluating
1704 // JavaScript from the debug event handler. 1682 // JavaScript from the debug event handler.
1705 HandleScope scope(isolate_); 1683 HandleScope scope(isolate_);
1706 Handle<Object> scheduled_exception; 1684 Handle<Object> scheduled_exception;
1707 if (isolate_->has_scheduled_exception()) { 1685 if (isolate_->has_scheduled_exception()) {
1708 scheduled_exception = handle(isolate_->scheduled_exception(), isolate_); 1686 scheduled_exception = handle(isolate_->scheduled_exception(), isolate_);
1709 isolate_->clear_scheduled_exception(); 1687 isolate_->clear_scheduled_exception();
1710 } 1688 }
1711 OnException(exception, isolate_->GetPromiseOnStackOnThrow()); 1689 OnException(exception, isolate_->GetPromiseOnStackOnThrow());
1712 if (!scheduled_exception.is_null()) { 1690 if (!scheduled_exception.is_null()) {
1713 isolate_->thread_local_top()->scheduled_exception_ = *scheduled_exception; 1691 isolate_->thread_local_top()->scheduled_exception_ = *scheduled_exception;
1714 } 1692 }
1693 PrepareStepOnThrow();
1715 } 1694 }
1716 1695
1717 void Debug::OnPromiseReject(Handle<Object> promise, Handle<Object> value) { 1696 void Debug::OnPromiseReject(Handle<Object> promise, Handle<Object> value) {
1718 if (in_debug_scope() || ignore_events()) return; 1697 if (in_debug_scope() || ignore_events()) return;
1719 HandleScope scope(isolate_); 1698 HandleScope scope(isolate_);
1720 // Check whether the promise has been marked as having triggered a message. 1699 // Check whether the promise has been marked as having triggered a message.
1721 Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol(); 1700 Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol();
1722 if (!promise->IsJSObject() || 1701 if (!promise->IsJSObject() ||
1723 JSReceiver::GetDataProperty(Handle<JSObject>::cast(promise), key) 1702 JSReceiver::GetDataProperty(Handle<JSObject>::cast(promise), key)
1724 ->IsUndefined(isolate_)) { 1703 ->IsUndefined(isolate_)) {
(...skipping 23 matching lines...) Expand all
1748 while (!it.done()) { 1727 while (!it.done()) {
1749 if (!IsFrameBlackboxed(it.frame())) return false; 1728 if (!IsFrameBlackboxed(it.frame())) return false;
1750 it.Advance(); 1729 it.Advance();
1751 } 1730 }
1752 return true; 1731 return true;
1753 } 1732 }
1754 1733
1755 bool Debug::IsFrameBlackboxed(JavaScriptFrame* frame) { 1734 bool Debug::IsFrameBlackboxed(JavaScriptFrame* frame) {
1756 HandleScope scope(isolate_); 1735 HandleScope scope(isolate_);
1757 if (!frame->HasInlinedFrames()) { 1736 if (!frame->HasInlinedFrames()) {
1758 return IsBlackboxed(frame->function()->shared()); 1737 Handle<SharedFunctionInfo> shared(frame->function()->shared(), isolate_);
1738 return IsBlackboxed(shared);
1759 } 1739 }
1760 List<SharedFunctionInfo*> raw_shareds; 1740 List<Handle<SharedFunctionInfo>> infos;
1761 frame->GetFunctions(&raw_shareds); 1741 frame->GetFunctions(&infos);
1762 List<Handle<SharedFunctionInfo>> shareds; 1742 for (const auto& info : infos)
1763 for (int i = 0; i < raw_shareds.length(); ++i) { 1743 if (!IsBlackboxed(info)) return false;
1764 shareds.Add(handle(raw_shareds[i]));
1765 }
1766 for (int i = 0; i < shareds.length(); ++i) {
1767 if (!IsBlackboxed(shareds[i])) return false;
1768 }
1769 return true; 1744 return true;
1770 } 1745 }
1771 1746
1772 void Debug::OnException(Handle<Object> exception, Handle<Object> promise) { 1747 void Debug::OnException(Handle<Object> exception, Handle<Object> promise) {
1773 // We cannot generate debug events when JS execution is disallowed. 1748 // We cannot generate debug events when JS execution is disallowed.
1774 // TODO(5530): Reenable debug events within DisallowJSScopes once relevant 1749 // TODO(5530): Reenable debug events within DisallowJSScopes once relevant
1775 // code (MakeExceptionEvent and ProcessDebugEvent) have been moved to C++. 1750 // code (MakeExceptionEvent and ProcessDebugEvent) have been moved to C++.
1776 if (!AllowJavascriptExecution::IsAllowed(isolate_)) return; 1751 if (!AllowJavascriptExecution::IsAllowed(isolate_)) return;
1777 1752
1778 Isolate::CatchType catch_type = isolate_->PredictExceptionCatcher(); 1753 Isolate::CatchType catch_type = isolate_->PredictExceptionCatcher();
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
1999 } 1974 }
2000 1975
2001 namespace { 1976 namespace {
2002 debug::Location GetDebugLocation(Handle<Script> script, int source_position) { 1977 debug::Location GetDebugLocation(Handle<Script> script, int source_position) {
2003 Script::PositionInfo info; 1978 Script::PositionInfo info;
2004 Script::GetPositionInfo(script, source_position, &info, Script::WITH_OFFSET); 1979 Script::GetPositionInfo(script, source_position, &info, Script::WITH_OFFSET);
2005 return debug::Location(info.line, info.column); 1980 return debug::Location(info.line, info.column);
2006 } 1981 }
2007 } // namespace 1982 } // namespace
2008 1983
2009 bool Debug::IsBlackboxed(SharedFunctionInfo* shared) {
2010 HandleScope scope(isolate_);
2011 Handle<SharedFunctionInfo> shared_function_info(shared);
2012 return IsBlackboxed(shared_function_info);
2013 }
2014
2015 bool Debug::IsBlackboxed(Handle<SharedFunctionInfo> shared) { 1984 bool Debug::IsBlackboxed(Handle<SharedFunctionInfo> shared) {
2016 if (!debug_delegate_) return false; 1985 if (!debug_delegate_) return false;
2017 if (!shared->computed_debug_is_blackboxed()) { 1986 if (!shared->computed_debug_is_blackboxed()) {
2018 bool is_blackboxed = false; 1987 bool is_blackboxed = false;
2019 if (shared->script()->IsScript()) { 1988 if (shared->script()->IsScript()) {
2020 HandleScope handle_scope(isolate_); 1989 HandleScope handle_scope(isolate_);
2021 Handle<Script> script(Script::cast(shared->script())); 1990 Handle<Script> script(Script::cast(shared->script()));
2022 if (script->type() == i::Script::TYPE_NORMAL) { 1991 if (script->type() == i::Script::TYPE_NORMAL) {
2023 debug::Location start = 1992 debug::Location start =
2024 GetDebugLocation(script, shared->start_position()); 1993 GetDebugLocation(script, shared->start_position());
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
2148 // Set new entry. 2117 // Set new entry.
2149 if (!callback->IsNullOrUndefined(isolate_)) { 2118 if (!callback->IsNullOrUndefined(isolate_)) {
2150 event_listener_ = global_handles->Create(*callback); 2119 event_listener_ = global_handles->Create(*callback);
2151 if (data.is_null()) data = isolate_->factory()->undefined_value(); 2120 if (data.is_null()) data = isolate_->factory()->undefined_value();
2152 event_listener_data_ = global_handles->Create(*data); 2121 event_listener_data_ = global_handles->Create(*data);
2153 } 2122 }
2154 2123
2155 UpdateState(); 2124 UpdateState();
2156 } 2125 }
2157 2126
2127 int Debug::CurrentFrameCount() {
2128 StackTraceFrameIterator it(isolate_);
2129 if (break_frame_id() != StackFrame::NO_ID) {
2130 // Skip to break frame.
2131 DCHECK(in_debug_scope());
2132 while (!it.done() && it.frame()->id() != break_frame_id()) it.Advance();
2133 }
2134 int counter = 0;
2135 while (!it.done()) {
2136 if (it.frame()->is_optimized()) {
2137 List<SharedFunctionInfo*> infos;
2138 OptimizedFrame::cast(it.frame())->GetFunctions(&infos);
2139 counter += infos.length();
2140 } else {
2141 counter++;
2142 }
2143 it.Advance();
2144 }
2145 return counter;
2146 }
2147
2158 void Debug::SetDebugDelegate(debug::DebugDelegate* delegate) { 2148 void Debug::SetDebugDelegate(debug::DebugDelegate* delegate) {
2159 debug_delegate_ = delegate; 2149 debug_delegate_ = delegate;
2160 UpdateState(); 2150 UpdateState();
2161 } 2151 }
2162 2152
2163 void Debug::UpdateState() { 2153 void Debug::UpdateState() {
2164 bool is_active = !event_listener_.is_null() || debug_delegate_ != nullptr; 2154 bool is_active = !event_listener_.is_null() || debug_delegate_ != nullptr;
2165 if (is_active || in_debug_scope()) { 2155 if (is_active || in_debug_scope()) {
2166 // Note that the debug context could have already been loaded to 2156 // Note that the debug context could have already been loaded to
2167 // bootstrap test cases. 2157 // bootstrap test cases.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2209 // Ignore debug break if debugger is not active. 2199 // Ignore debug break if debugger is not active.
2210 if (!is_active()) return; 2200 if (!is_active()) return;
2211 2201
2212 StackLimitCheck check(isolate_); 2202 StackLimitCheck check(isolate_);
2213 if (check.HasOverflowed()) return; 2203 if (check.HasOverflowed()) return;
2214 2204
2215 { JavaScriptFrameIterator it(isolate_); 2205 { JavaScriptFrameIterator it(isolate_);
2216 DCHECK(!it.done()); 2206 DCHECK(!it.done());
2217 Object* fun = it.frame()->function(); 2207 Object* fun = it.frame()->function();
2218 if (fun && fun->IsJSFunction()) { 2208 if (fun && fun->IsJSFunction()) {
2209 HandleScope scope(isolate_);
2219 // Don't stop in builtin and blackboxed functions. 2210 // Don't stop in builtin and blackboxed functions.
2220 if (!JSFunction::cast(fun)->shared()->IsSubjectToDebugging() || 2211 Handle<SharedFunctionInfo> shared(JSFunction::cast(fun)->shared(),
2221 IsBlackboxed(JSFunction::cast(fun)->shared())) { 2212 isolate_);
2213 if (!shared->IsSubjectToDebugging() || IsBlackboxed(shared)) {
2222 // Inspector uses pause on next statement for asynchronous breakpoints. 2214 // Inspector uses pause on next statement for asynchronous breakpoints.
2223 // When breakpoint is fired we try to break on first not blackboxed 2215 // When breakpoint is fired we try to break on first not blackboxed
2224 // statement. To achieve this goal we need to deoptimize current 2216 // statement. To achieve this goal we need to deoptimize current
2225 // function and don't clear requested DebugBreak even if it's blackboxed 2217 // function and don't clear requested DebugBreak even if it's blackboxed
2226 // to be able to break on not blackboxed function call. 2218 // to be able to break on not blackboxed function call.
2227 // TODO(yangguo): introduce break_on_function_entry since current 2219 // TODO(yangguo): introduce break_on_function_entry since current
2228 // implementation is slow. 2220 // implementation is slow.
2229 Deoptimizer::DeoptimizeFunction(JSFunction::cast(fun)); 2221 Deoptimizer::DeoptimizeFunction(JSFunction::cast(fun));
2230 return; 2222 return;
2231 } 2223 }
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
2419 return v8::Utils::ToLocal(callback_data_); 2411 return v8::Utils::ToLocal(callback_data_);
2420 } 2412 }
2421 2413
2422 2414
2423 v8::Isolate* EventDetailsImpl::GetIsolate() const { 2415 v8::Isolate* EventDetailsImpl::GetIsolate() const {
2424 return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate()); 2416 return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate());
2425 } 2417 }
2426 2418
2427 } // namespace internal 2419 } // namespace internal
2428 } // namespace v8 2420 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698