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

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

Issue 2096863003: [wasm] prototype for breakpoint support. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@extend-script-functionality
Patch Set: Created 4 years, 6 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
« no previous file with comments | « src/debug/debug.h ('k') | src/debug/debug-frames.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "src/api.h" 7 #include "src/api.h"
8 #include "src/arguments.h" 8 #include "src/arguments.h"
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 14 matching lines...) Expand all
25 #include "src/wasm/wasm-debug.h" 25 #include "src/wasm/wasm-debug.h"
26 #include "src/wasm/wasm-module.h" 26 #include "src/wasm/wasm-module.h"
27 27
28 #include "include/v8-debug.h" 28 #include "include/v8-debug.h"
29 29
30 namespace v8 { 30 namespace v8 {
31 namespace internal { 31 namespace internal {
32 32
33 namespace { 33 namespace {
34 34
35 inline int CallOffsetFromCodeOffset(int code_offset, bool is_interpreted) { 35 inline int GetCodeOffset(StandardFrame* frame) {
36 // Frame summary is top-down, i.e. caller before callee.
37 // For whatever reason, javascript takes the lowest caller as the code offset
38 // for the frame, where for wasm we need the highest one.
39 return frame->is_java_script() ? FrameSummary::GetFirst(frame).code_offset()
40 : FrameSummary::GetLast(frame).code_offset();
41 }
42
43 inline int CallOffsetFromCodeOffset(int code_offset, StandardFrame* frame) {
36 // Code offset points to the instruction after the call. Subtract 1 to 44 // Code offset points to the instruction after the call. Subtract 1 to
37 // exclude that instruction from the search. For bytecode, the code offset 45 // exclude that instruction from the search. For interpreted frames, the code
38 // still points to the call. 46 // offset still points to the call.
39 return is_interpreted ? code_offset : code_offset - 1; 47 bool interpreted = frame->is_interpreted() || frame->is_wasm_interpreted();
48 return interpreted ? code_offset : code_offset - 1;
49 }
50
51 std::pair<Handle<JSObject>, int> GetWasmObjectAndFunctionIndexFromCode(
52 Code* code) {
53 FixedArray* deopt_data = code->deoptimization_data();
54 DCHECK_EQ(2, deopt_data->length());
55 Handle<JSObject> wasm(JSObject::cast(deopt_data->get(0)));
56 int func_index = Smi::cast(deopt_data->get(1))->value();
57 return std::make_pair(wasm, func_index);
40 } 58 }
41 59
42 } // namespace 60 } // namespace
43 61
44 Debug::Debug(Isolate* isolate) 62 Debug::Debug(Isolate* isolate)
45 : debug_context_(Handle<Context>()), 63 : debug_context_(Handle<Context>()),
46 event_listener_(Handle<Object>()), 64 event_listener_(Handle<Object>()),
47 event_listener_data_(Handle<Object>()), 65 event_listener_data_(Handle<Object>()),
48 message_handler_(NULL), 66 message_handler_(NULL),
49 command_received_(0), 67 command_received_(0),
(...skipping 28 matching lines...) Expand all
78 : debug_info_(debug_info), 96 : debug_info_(debug_info),
79 code_offset_(code_offset), 97 code_offset_(code_offset),
80 type_(type), 98 type_(type),
81 position_(position), 99 position_(position),
82 statement_position_(statement_position) {} 100 statement_position_(statement_position) {}
83 101
84 BreakLocation::Iterator* BreakLocation::GetIterator( 102 BreakLocation::Iterator* BreakLocation::GetIterator(
85 Handle<DebugInfo> debug_info, BreakLocatorType type) { 103 Handle<DebugInfo> debug_info, BreakLocatorType type) {
86 if (debug_info->abstract_code()->IsBytecodeArray()) { 104 if (debug_info->abstract_code()->IsBytecodeArray()) {
87 return new BytecodeArrayIterator(debug_info, type); 105 return new BytecodeArrayIterator(debug_info, type);
106 } else if (debug_info->abstract_code()->GetCode()->kind() ==
107 Code::WASM_FUNCTION) {
108 return new WasmBytecodeIterator(debug_info, type);
88 } else { 109 } else {
89 return new CodeIterator(debug_info, type); 110 return new CodeIterator(debug_info, type);
90 } 111 }
91 } 112 }
92 113
93 BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info) 114 BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info)
94 : debug_info_(debug_info), 115 : debug_info_(debug_info),
95 break_index_(-1), 116 break_index_(-1),
96 position_(1), 117 position_(1),
97 statement_position_(1) {} 118 statement_position_(1) {}
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 } else { 278 } else {
258 return NOT_DEBUG_BREAK; 279 return NOT_DEBUG_BREAK;
259 } 280 }
260 } 281 }
261 282
262 BreakLocation BreakLocation::BytecodeArrayIterator::GetBreakLocation() { 283 BreakLocation BreakLocation::BytecodeArrayIterator::GetBreakLocation() {
263 return BreakLocation(debug_info_, GetDebugBreakType(), code_offset(), 284 return BreakLocation(debug_info_, GetDebugBreakType(), code_offset(),
264 position(), statement_position()); 285 position(), statement_position());
265 } 286 }
266 287
288 namespace {
289
290 wasm::WasmInstructionIterator GetWasmInsnIterator(
291 Handle<DebugInfo> debug_info) {
292 auto wasm_and_index = GetWasmObjectAndFunctionIndexFromCode(
293 debug_info->abstract_code()->GetCode());
294 Handle<wasm::WasmDebugInfo> wasm_debug_info(
295 wasm::GetDebugInfo(wasm_and_index.first));
296 return wasm::WasmDebugInfo::GetInstructionIterator(wasm_debug_info,
297 wasm_and_index.second);
298 }
299
300 } // namespace
301
302 BreakLocation::WasmBytecodeIterator::WasmBytecodeIterator(
303 Handle<DebugInfo> debug_info, BreakLocatorType type)
304 : Iterator(debug_info),
305 wasm_insn_iterator(GetWasmInsnIterator(debug_info)),
306 break_locator_type_(type) {
307 // Get wasm object and function index from deopt data.
308 Code* code = debug_info->abstract_code()->GetCode();
309 Handle<JSObject> wasm;
310 std::tie(wasm, func_index) = GetWasmObjectAndFunctionIndexFromCode(code);
311 wasm_debug_info = handle(wasm::GetDebugInfo(wasm));
312 Next();
313 }
314
315 BreakLocation BreakLocation::WasmBytecodeIterator::GetBreakLocation() {
316 DebugBreakType type;
317 switch (wasm_debug_info->GetInstructionType(func_index,
318 wasm_insn_iterator.pc_offset())) {
319 case wasm::WasmDebugInfo::InstructionType::RETURN:
320 type = DEBUG_BREAK_SLOT_AT_RETURN;
321 break;
322 case wasm::WasmDebugInfo::InstructionType::CALL:
323 type = DEBUG_BREAK_SLOT_AT_CALL;
324 break;
325 default:
326 type = DEBUG_BREAK_SLOT;
327 break;
328 }
329 return BreakLocation(debug_info_, type, code_offset(), position(),
330 statement_position());
331 }
332
333 void BreakLocation::WasmBytecodeIterator::Next() {
334 ++break_index_;
335 for (bool first = break_index_ == 0; !Done(); first = false) {
336 if (!first) wasm_insn_iterator.Next();
337 position_ = statement_position_ = wasm_insn_iterator.pc_offset();
338 if (break_locator_type_ == ALL_BREAK_LOCATIONS) break;
339 DCHECK_EQ(BreakLocatorType::CALLS_AND_RETURNS, break_locator_type_);
340 using InsnType = wasm::WasmDebugInfo::InstructionType;
341 InsnType type = wasm_debug_info->GetInstructionType(func_index, position_);
342 if (type == InsnType::RETURN || type == InsnType::CALL) break;
343 }
344 }
345
267 // Find the break point at the supplied address, or the closest one before 346 // Find the break point at the supplied address, or the closest one before
268 // the address. 347 // the address.
269 BreakLocation BreakLocation::FromCodeOffset(Handle<DebugInfo> debug_info, 348 BreakLocation BreakLocation::FromCodeOffset(Handle<DebugInfo> debug_info,
270 int offset) { 349 int offset) {
271 base::SmartPointer<Iterator> it(GetIterator(debug_info)); 350 base::SmartPointer<Iterator> it(GetIterator(debug_info));
272 it->SkipTo(BreakIndexFromCodeOffset(debug_info, offset)); 351 it->SkipTo(BreakIndexFromCodeOffset(debug_info, offset));
273 return it->GetBreakLocation(); 352 return it->GetBreakLocation();
274 } 353 }
275 354
276 BreakLocation BreakLocation::FromFrame(Handle<DebugInfo> debug_info, 355 BreakLocation BreakLocation::FromFrame(StandardFrame* frame) {
277 JavaScriptFrame* frame) { 356 // Get the debug info (create it if it does not exist).
278 int code_offset = FrameSummary::GetFirst(frame).code_offset(); 357 Handle<DebugInfo> debug_info(DebugInfo::cast(frame->debug_info(true)));
279 int call_offset = 358
280 CallOffsetFromCodeOffset(code_offset, frame->is_interpreted()); 359 int code_offset = GetCodeOffset(frame);
360 int call_offset = CallOffsetFromCodeOffset(code_offset, frame);
281 return FromCodeOffset(debug_info, call_offset); 361 return FromCodeOffset(debug_info, call_offset);
282 } 362 }
283 363
284 void BreakLocation::AllForStatementPosition(Handle<DebugInfo> debug_info, 364 void BreakLocation::AllForStatementPosition(Handle<DebugInfo> debug_info,
285 int statement_position, 365 int statement_position,
286 List<BreakLocation>* result_out) { 366 List<BreakLocation>* result_out) {
287 for (base::SmartPointer<Iterator> it(GetIterator(debug_info)); !it->Done(); 367 for (base::SmartPointer<Iterator> it(GetIterator(debug_info)); !it->Done();
288 it->Next()) { 368 it->Next()) {
289 if (it->statement_position() == statement_position) { 369 if (it->statement_position() == statement_position) {
290 result_out->Add(it->GetBreakLocation()); 370 result_out->Add(it->GetBreakLocation());
291 } 371 }
292 } 372 }
293 } 373 }
294 374
295 int BreakLocation::BreakIndexFromCodeOffset(Handle<DebugInfo> debug_info, 375 int BreakLocation::BreakIndexFromCodeOffset(Handle<DebugInfo> debug_info,
296 int offset) { 376 int offset) {
297 // Run through all break points to locate the one closest to the address. 377 // Run through all break points to locate the one closest to the address.
298 int closest_break = 0; 378 int closest_break = 0;
299 int distance = kMaxInt; 379 int distance = kMaxInt;
300 DCHECK(0 <= offset && offset < debug_info->abstract_code()->Size()); 380 DCHECK_LE(0, offset);
301 for (base::SmartPointer<Iterator> it(GetIterator(debug_info)); !it->Done(); 381 for (base::SmartPointer<Iterator> it(GetIterator(debug_info)); !it->Done();
302 it->Next()) { 382 it->Next()) {
303 // Check if this break point is closer that what was previously found. 383 // Check if this break point is closer that what was previously found.
304 if (it->code_offset() <= offset && offset - it->code_offset() < distance) { 384 if (it->code_offset() <= offset && offset - it->code_offset() < distance) {
305 closest_break = it->break_index(); 385 closest_break = it->break_index();
306 distance = offset - it->code_offset(); 386 distance = offset - it->code_offset();
307 // Check whether we can't get any closer. 387 // Check whether we can't get any closer.
308 if (distance == 0) break; 388 if (distance == 0) break;
309 } 389 }
310 } 390 }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 479
400 // If there is already a break point here just return. This might happen if 480 // If there is already a break point here just return. This might happen if
401 // the same code is flooded with break points twice. Flooding the same 481 // the same code is flooded with break points twice. Flooding the same
402 // function twice might happen when stepping in a function with an exception 482 // function twice might happen when stepping in a function with an exception
403 // handler as the handler and the function is the same. 483 // handler as the handler and the function is the same.
404 if (IsDebugBreak()) return; 484 if (IsDebugBreak()) return;
405 485
406 DCHECK(IsDebugBreakSlot()); 486 DCHECK(IsDebugBreakSlot());
407 if (abstract_code()->IsCode()) { 487 if (abstract_code()->IsCode()) {
408 Code* code = abstract_code()->GetCode(); 488 Code* code = abstract_code()->GetCode();
409 DCHECK(code->kind() == Code::FUNCTION); 489 if (code->kind() == Code::FUNCTION) {
410 Builtins* builtins = isolate()->builtins(); 490 Builtins* builtins = isolate()->builtins();
411 Handle<Code> target = IsReturn() ? builtins->Return_DebugBreak() 491 Handle<Code> target = IsReturn() ? builtins->Return_DebugBreak()
412 : builtins->Slot_DebugBreak(); 492 : builtins->Slot_DebugBreak();
413 Address pc = code->instruction_start() + code_offset(); 493 Address pc = code->instruction_start() + code_offset();
414 DebugCodegen::PatchDebugBreakSlot(isolate(), pc, target); 494 DebugCodegen::PatchDebugBreakSlot(isolate(), pc, target);
495 } else {
496 DCHECK(code->kind() == Code::WASM_FUNCTION);
497 // Get wasm object and function index from deopt data.
498 Handle<JSObject> wasm;
499 int func_index;
500 std::tie(wasm, func_index) = GetWasmObjectAndFunctionIndexFromCode(code);
501 Handle<wasm::WasmDebugInfo> debug_info(wasm::GetDebugInfo(wasm));
502 wasm::WasmDebugInfo::SetBreakpoint(debug_info, func_index, position());
503 }
415 } else { 504 } else {
416 BytecodeArray* bytecode_array = abstract_code()->GetBytecodeArray(); 505 BytecodeArray* bytecode_array = abstract_code()->GetBytecodeArray();
417 interpreter::Bytecode bytecode = 506 interpreter::Bytecode bytecode =
418 interpreter::Bytecodes::FromByte(bytecode_array->get(code_offset())); 507 interpreter::Bytecodes::FromByte(bytecode_array->get(code_offset()));
419 interpreter::Bytecode debugbreak = 508 interpreter::Bytecode debugbreak =
420 interpreter::Bytecodes::GetDebugBreak(bytecode); 509 interpreter::Bytecodes::GetDebugBreak(bytecode);
421 bytecode_array->set(code_offset(), 510 bytecode_array->set(code_offset(),
422 interpreter::Bytecodes::ToByte(debugbreak)); 511 interpreter::Bytecodes::ToByte(debugbreak));
423 } 512 }
424 DCHECK(IsDebugBreak()); 513 DCHECK(IsDebugBreak());
(...skipping 17 matching lines...) Expand all
442 } 531 }
443 DCHECK(!IsDebugBreak()); 532 DCHECK(!IsDebugBreak());
444 } 533 }
445 534
446 535
447 bool BreakLocation::IsDebugBreak() const { 536 bool BreakLocation::IsDebugBreak() const {
448 if (IsDebuggerStatement()) return false; 537 if (IsDebuggerStatement()) return false;
449 DCHECK(IsDebugBreakSlot()); 538 DCHECK(IsDebugBreakSlot());
450 if (abstract_code()->IsCode()) { 539 if (abstract_code()->IsCode()) {
451 Code* code = abstract_code()->GetCode(); 540 Code* code = abstract_code()->GetCode();
452 DCHECK(code->kind() == Code::FUNCTION); 541 if (code->kind() == Code::FUNCTION) {
453 Address pc = code->instruction_start() + code_offset(); 542 Address pc = code->instruction_start() + code_offset();
454 return DebugCodegen::DebugBreakSlotIsPatched(pc); 543 return DebugCodegen::DebugBreakSlotIsPatched(pc);
544 }
545 DCHECK(code->kind() == Code::WASM_FUNCTION);
546 Handle<JSObject> wasm;
547 int func_index;
548 std::tie(wasm, func_index) = GetWasmObjectAndFunctionIndexFromCode(code);
549 Handle<wasm::WasmDebugInfo> wasm_debug_info(wasm::GetDebugInfo(wasm));
550 return wasm_debug_info->HasBreakpoint(func_index, position());
455 } else { 551 } else {
456 BytecodeArray* bytecode_array = abstract_code()->GetBytecodeArray(); 552 BytecodeArray* bytecode_array = abstract_code()->GetBytecodeArray();
457 interpreter::Bytecode bytecode = 553 interpreter::Bytecode bytecode =
458 interpreter::Bytecodes::FromByte(bytecode_array->get(code_offset())); 554 interpreter::Bytecodes::FromByte(bytecode_array->get(code_offset()));
459 return interpreter::Bytecodes::IsDebugBreak(bytecode); 555 return interpreter::Bytecodes::IsDebugBreak(bytecode);
460 } 556 }
461 } 557 }
462 558
463 559
464 Handle<Object> BreakLocation::BreakPointObjects() const { 560 Handle<Object> BreakLocation::BreakPointObjects() const {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 ClearStepping(); 663 ClearStepping();
568 664
569 // Return debugger is not loaded. 665 // Return debugger is not loaded.
570 if (!is_loaded()) return; 666 if (!is_loaded()) return;
571 667
572 // Clear debugger context global handle. 668 // Clear debugger context global handle.
573 GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location()); 669 GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location());
574 debug_context_ = Handle<Context>(); 670 debug_context_ = Handle<Context>();
575 } 671 }
576 672
577 void Debug::Break(JavaScriptFrame* frame) { 673 void Debug::Break(StandardFrame* frame) {
578 HandleScope scope(isolate_); 674 HandleScope scope(isolate_);
579 675
580 // Initialize LiveEdit. 676 // Initialize LiveEdit.
581 LiveEdit::InitializeThreadLocal(this); 677 LiveEdit::InitializeThreadLocal(this);
582 678
583 // Just continue if breaks are disabled or debugger cannot be loaded. 679 // Just continue if breaks are disabled or debugger cannot be loaded.
584 if (break_disabled()) return; 680 if (break_disabled()) return;
585 681
586 // Enter the debugger. 682 // Enter the debugger.
587 DebugScope debug_scope(this); 683 DebugScope debug_scope(this);
588 if (debug_scope.failed()) return; 684 if (debug_scope.failed()) return;
589 685
590 // Postpone interrupt during breakpoint processing. 686 // Postpone interrupt during breakpoint processing.
591 PostponeInterruptsScope postpone(isolate_); 687 PostponeInterruptsScope postpone(isolate_);
592 688
593 // Get the debug info (create it if it does not exist).
594 Handle<JSFunction> function(frame->function());
595 Handle<SharedFunctionInfo> shared(function->shared());
596 if (!EnsureDebugInfo(shared, function)) {
597 // Return if we failed to retrieve the debug info.
598 return;
599 }
600 Handle<DebugInfo> debug_info(shared->GetDebugInfo(), isolate_);
601
602 // Find the break location where execution has stopped. 689 // Find the break location where execution has stopped.
603 BreakLocation location = BreakLocation::FromFrame(debug_info, frame); 690 BreakLocation location = BreakLocation::FromFrame(frame);
604 691
605 // Find actual break points, if any, and trigger debug break event. 692 // Find actual break points, if any, and trigger debug break event.
606 Handle<Object> break_points_hit = CheckBreakPoints(&location); 693 Handle<Object> break_points_hit = CheckBreakPoints(&location);
607 if (!break_points_hit->IsUndefined(isolate_)) { 694 if (!break_points_hit->IsUndefined(isolate_)) {
608 // Clear all current stepping setup. 695 // Clear all current stepping setup.
609 ClearStepping(); 696 ClearStepping();
610 // Notify the debug event listeners. 697 // Notify the debug event listeners.
611 OnDebugBreak(break_points_hit, false); 698 OnDebugBreak(break_points_hit, false);
612 return; 699 return;
613 } 700 }
(...skipping 13 matching lines...) Expand all
627 if (current_fp < target_fp) return; 714 if (current_fp < target_fp) return;
628 step_break = true; 715 step_break = true;
629 break; 716 break;
630 case StepNext: 717 case StepNext:
631 // Step next should not break in a deeper frame. 718 // Step next should not break in a deeper frame.
632 if (current_fp < target_fp) return; 719 if (current_fp < target_fp) return;
633 // For step-next, a tail call is like a return and should break. 720 // For step-next, a tail call is like a return and should break.
634 step_break = location.IsTailCall(); 721 step_break = location.IsTailCall();
635 // Fall through. 722 // Fall through.
636 case StepIn: { 723 case StepIn: {
637 FrameSummary summary = FrameSummary::GetFirst(frame); 724 int offset = GetCodeOffset(frame);
638 int offset = summary.code_offset();
639 step_break = step_break || location.IsReturn() || 725 step_break = step_break || location.IsReturn() ||
640 (current_fp != last_fp) || 726 (current_fp != last_fp) ||
641 (thread_local_.last_statement_position_ != 727 (thread_local_.last_statement_position_ !=
642 location.abstract_code()->SourceStatementPosition(offset)); 728 location.abstract_code()->SourceStatementPosition(offset));
643 break; 729 break;
644 } 730 }
645 case StepFrame: 731 case StepFrame:
646 step_break = current_fp != last_fp; 732 step_break = current_fp != last_fp;
647 break; 733 break;
648 } 734 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 // an exception event on exception at this location. 792 // an exception event on exception at this location.
707 Object* fun = frame->function(); 793 Object* fun = frame->function();
708 if (!fun->IsJSFunction()) return false; 794 if (!fun->IsJSFunction()) return false;
709 JSFunction* function = JSFunction::cast(fun); 795 JSFunction* function = JSFunction::cast(fun);
710 if (!function->shared()->HasDebugInfo()) return false; 796 if (!function->shared()->HasDebugInfo()) return false;
711 HandleScope scope(isolate_); 797 HandleScope scope(isolate_);
712 Handle<DebugInfo> debug_info(function->shared()->GetDebugInfo()); 798 Handle<DebugInfo> debug_info(function->shared()->GetDebugInfo());
713 // Enter the debugger. 799 // Enter the debugger.
714 DebugScope debug_scope(this); 800 DebugScope debug_scope(this);
715 if (debug_scope.failed()) return false; 801 if (debug_scope.failed()) return false;
716 BreakLocation current_position = BreakLocation::FromFrame(debug_info, frame); 802 BreakLocation current_position = BreakLocation::FromFrame(frame);
717 List<BreakLocation> break_locations; 803 List<BreakLocation> break_locations;
718 BreakLocation::AllForStatementPosition( 804 BreakLocation::AllForStatementPosition(
719 debug_info, current_position.statement_position(), &break_locations); 805 debug_info, current_position.statement_position(), &break_locations);
720 bool has_break_points_at_all = false; 806 bool has_break_points_at_all = false;
721 for (int i = 0; i < break_locations.length(); i++) { 807 for (int i = 0; i < break_locations.length(); i++) {
722 bool has_break_points; 808 bool has_break_points;
723 Handle<Object> check_result = 809 Handle<Object> check_result =
724 CheckBreakPoints(&break_locations[i], &has_break_points); 810 CheckBreakPoints(&break_locations[i], &has_break_points);
725 has_break_points_at_all |= has_break_points; 811 has_break_points_at_all |= has_break_points;
726 if (has_break_points && !check_result->IsUndefined(isolate_)) return false; 812 if (has_break_points && !check_result->IsUndefined(isolate_)) return false;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 878
793 // At least one active break point now. 879 // At least one active break point now.
794 return debug_info->GetBreakPointCount() > 0; 880 return debug_info->GetBreakPointCount() > 0;
795 } 881 }
796 882
797 883
798 bool Debug::SetBreakPointForScript(Handle<Script> script, 884 bool Debug::SetBreakPointForScript(Handle<Script> script,
799 Handle<Object> break_point_object, 885 Handle<Object> break_point_object,
800 int* source_position, 886 int* source_position,
801 BreakPositionAlignment alignment) { 887 BreakPositionAlignment alignment) {
802 if (script->type() == Script::TYPE_WASM) {
803 // TODO(clemensh): set breakpoint for wasm.
804 return false;
805 }
806 HandleScope scope(isolate_); 888 HandleScope scope(isolate_);
807 889
808 // Obtain shared function info for the function. 890 Handle<DebugInfo> debug_info;
809 Handle<Object> result = 891 int start_position = 0;
810 FindSharedFunctionInfoInScript(script, *source_position); 892 if (script->type() == Script::TYPE_WASM) {
811 if (result->IsUndefined(isolate_)) return false; 893 Handle<wasm::WasmDebugInfo> wasm_debug(
894 wasm::GetDebugInfo(handle(script->wasm_object(), isolate_)), isolate_);
895 uint32_t func_index = script->wasm_function_index();
896 debug_info = handle(
897 wasm::WasmDebugInfo::GetDebugInfo(wasm_debug, func_index), isolate_);
898 } else {
899 // Obtain shared function info for the function.
900 Handle<Object> result =
901 FindSharedFunctionInfoInScript(script, *source_position);
902 if (result->IsUndefined(isolate_)) return false;
812 903
813 // Make sure the function has set up the debug info. 904 // Get debug info, create it if necessary.
814 Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(result); 905 Handle<SharedFunctionInfo> shared =
815 if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) { 906 Handle<SharedFunctionInfo>::cast(result);
816 // Return if retrieving debug info failed. 907 if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) {
817 return false; 908 // Return if retrieving debug info failed.
909 return false;
910 }
911 debug_info = handle(shared->GetDebugInfo(), isolate_);
912 start_position = shared->start_position();
818 } 913 }
819 914
820 // Find position within function. The script position might be before the 915 // Find position within function. The script position might be before the
821 // source position of the first function. 916 // source position of the first function.
822 int position; 917 int position =
823 if (shared->start_position() > *source_position) { 918 start_position > *source_position ? 0 : *source_position - start_position;
824 position = 0;
825 } else {
826 position = *source_position - shared->start_position();
827 }
828 919
829 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
830 // Source positions starts with zero. 920 // Source positions starts with zero.
831 DCHECK(position >= 0); 921 DCHECK_LE(0, position);
832 922
833 // Find the break point and change it. 923 // Find the break point and change it.
834 BreakLocation location = 924 BreakLocation location =
835 BreakLocation::FromPosition(debug_info, position, alignment); 925 BreakLocation::FromPosition(debug_info, position, alignment);
836 location.SetBreakPoint(break_point_object); 926 location.SetBreakPoint(break_point_object);
837 927
838 feature_tracker()->Track(DebugFeatureTracker::kBreakPoint); 928 feature_tracker()->Track(DebugFeatureTracker::kBreakPoint);
839 929
840 position = (alignment == STATEMENT_ALIGNED) ? location.statement_position() 930 position = (alignment == STATEMENT_ALIGNED) ? location.statement_position()
841 : location.position(); 931 : location.position();
842 932
843 *source_position = position + shared->start_position(); 933 *source_position = position + start_position;
844 934
845 // At least one active break point now. 935 // At least one active break point now.
846 DCHECK(debug_info->GetBreakPointCount() > 0); 936 DCHECK(debug_info->GetBreakPointCount() > 0);
847 return true; 937 return true;
848 } 938 }
849 939
850 940
851 void Debug::ClearBreakPoint(Handle<Object> break_point_object) { 941 void Debug::ClearBreakPoint(Handle<Object> break_point_object) {
852 HandleScope scope(isolate_); 942 HandleScope scope(isolate_);
853 943
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
1038 // Return if ensuring debug info failed. 1128 // Return if ensuring debug info failed.
1039 return; 1129 return;
1040 } 1130 }
1041 1131
1042 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 1132 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1043 // Refresh frame summary if the code has been recompiled for debugging. 1133 // Refresh frame summary if the code has been recompiled for debugging.
1044 if (AbstractCode::cast(shared->code()) != *summary.abstract_code()) { 1134 if (AbstractCode::cast(shared->code()) != *summary.abstract_code()) {
1045 summary = FrameSummary::GetFirst(frame); 1135 summary = FrameSummary::GetFirst(frame);
1046 } 1136 }
1047 1137
1048 int call_offset = 1138 int call_offset = CallOffsetFromCodeOffset(summary.code_offset(), frame);
1049 CallOffsetFromCodeOffset(summary.code_offset(), frame->is_interpreted());
1050 BreakLocation location = 1139 BreakLocation location =
1051 BreakLocation::FromCodeOffset(debug_info, call_offset); 1140 BreakLocation::FromCodeOffset(debug_info, call_offset);
1052 1141
1053 // Any step at a return is a step-out. 1142 // Any step at a return is a step-out.
1054 if (location.IsReturn()) step_action = StepOut; 1143 if (location.IsReturn()) step_action = StepOut;
1055 // A step-next at a tail call is a step-out. 1144 // A step-next at a tail call is a step-out.
1056 if (location.IsTailCall() && step_action == StepNext) step_action = StepOut; 1145 if (location.IsTailCall() && step_action == StepNext) step_action = StepOut;
1057 1146
1058 thread_local_.last_statement_position_ = 1147 thread_local_.last_statement_position_ =
1059 debug_info->abstract_code()->SourceStatementPosition( 1148 debug_info->abstract_code()->SourceStatementPosition(
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
1596 return; 1685 return;
1597 } 1686 }
1598 // Move to next in list. 1687 // Move to next in list.
1599 prev = current; 1688 prev = current;
1600 current = current->next(); 1689 current = current->next();
1601 } 1690 }
1602 1691
1603 UNREACHABLE(); 1692 UNREACHABLE();
1604 } 1693 }
1605 1694
1606 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { 1695 void Debug::SetAfterBreakTarget(StandardFrame* frame) {
1607 after_break_target_ = NULL; 1696 after_break_target_ = NULL;
1608 if (!LiveEdit::SetAfterBreakTarget(this)) { 1697 if (!LiveEdit::SetAfterBreakTarget(this)) {
1609 // Continue just after the slot. 1698 // Continue just after the slot.
1610 after_break_target_ = frame->pc(); 1699 after_break_target_ = frame->pc();
1611 } 1700 }
1612 } 1701 }
1613 1702
1614 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { 1703 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
1615 HandleScope scope(isolate_); 1704 HandleScope scope(isolate_);
1616 1705
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after
2308 // Store the previous break id, frame id and return value. 2397 // Store the previous break id, frame id and return value.
2309 break_id_ = debug_->break_id(); 2398 break_id_ = debug_->break_id();
2310 break_frame_id_ = debug_->break_frame_id(); 2399 break_frame_id_ = debug_->break_frame_id();
2311 return_value_ = debug_->return_value(); 2400 return_value_ = debug_->return_value();
2312 2401
2313 // Create the new break info. If there is no proper frames there is no break 2402 // Create the new break info. If there is no proper frames there is no break
2314 // frame id. 2403 // frame id.
2315 StackTraceFrameIterator it(isolate()); 2404 StackTraceFrameIterator it(isolate());
2316 bool has_frames = !it.done(); 2405 bool has_frames = !it.done();
2317 // We don't currently support breaking inside wasm framess. 2406 // We don't currently support breaking inside wasm framess.
2318 DCHECK(!has_frames || !it.is_wasm());
2319 debug_->thread_local_.break_frame_id_ = 2407 debug_->thread_local_.break_frame_id_ =
2320 has_frames ? it.frame()->id() : StackFrame::NO_ID; 2408 has_frames ? it.frame()->id() : StackFrame::NO_ID;
2321 debug_->SetNextBreakId(); 2409 debug_->SetNextBreakId();
2322 2410
2323 debug_->UpdateState(); 2411 debug_->UpdateState();
2324 // Make sure that debugger is loaded and enter the debugger context. 2412 // Make sure that debugger is loaded and enter the debugger context.
2325 // The previous context is kept in save_. 2413 // The previous context is kept in save_.
2326 failed_ = !debug_->is_loaded(); 2414 failed_ = !debug_->is_loaded();
2327 if (!failed_) isolate()->set_context(*debug->debug_context()); 2415 if (!failed_) isolate()->set_context(*debug->debug_context());
2328 } 2416 }
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
2605 } 2693 }
2606 2694
2607 2695
2608 void LockingCommandMessageQueue::Clear() { 2696 void LockingCommandMessageQueue::Clear() {
2609 base::LockGuard<base::Mutex> lock_guard(&mutex_); 2697 base::LockGuard<base::Mutex> lock_guard(&mutex_);
2610 queue_.Clear(); 2698 queue_.Clear();
2611 } 2699 }
2612 2700
2613 } // namespace internal 2701 } // namespace internal
2614 } // namespace v8 2702 } // namespace v8
OLDNEW
« no previous file with comments | « src/debug/debug.h ('k') | src/debug/debug-frames.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698