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

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

Issue 2109093003: [wasm] Enable wasm frame inspection for debugging (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 5 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/objects.cc ('k') | src/runtime/runtime-liveedit.cc » ('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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/runtime/runtime-utils.h" 5 #include "src/runtime/runtime-utils.h"
6 6
7 #include "src/arguments.h" 7 #include "src/arguments.h"
8 #include "src/debug/debug-evaluate.h" 8 #include "src/debug/debug-evaluate.h"
9 #include "src/debug/debug-frames.h" 9 #include "src/debug/debug-frames.h"
10 #include "src/debug/debug-scopes.h" 10 #include "src/debug/debug-scopes.h"
11 #include "src/debug/debug.h" 11 #include "src/debug/debug.h"
12 #include "src/frames-inl.h" 12 #include "src/frames-inl.h"
13 #include "src/interpreter/bytecodes.h" 13 #include "src/interpreter/bytecodes.h"
14 #include "src/interpreter/interpreter.h" 14 #include "src/interpreter/interpreter.h"
15 #include "src/isolate-inl.h" 15 #include "src/isolate-inl.h"
16 #include "src/runtime/runtime.h" 16 #include "src/runtime/runtime.h"
17 #include "src/wasm/wasm-module.h"
17 18
18 namespace v8 { 19 namespace v8 {
19 namespace internal { 20 namespace internal {
20 21
21 RUNTIME_FUNCTION(Runtime_DebugBreak) { 22 RUNTIME_FUNCTION(Runtime_DebugBreak) {
22 SealHandleScope shs(isolate); 23 SealHandleScope shs(isolate);
23 DCHECK(args.length() == 1); 24 DCHECK(args.length() == 1);
24 CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); 25 CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
25 isolate->debug()->set_return_value(value); 26 isolate->debug()->set_return_value(value);
26 27
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id)); 447 RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
447 448
448 // Count all frames which are relevant to debugging stack trace. 449 // Count all frames which are relevant to debugging stack trace.
449 int n = 0; 450 int n = 0;
450 StackFrame::Id id = isolate->debug()->break_frame_id(); 451 StackFrame::Id id = isolate->debug()->break_frame_id();
451 if (id == StackFrame::NO_ID) { 452 if (id == StackFrame::NO_ID) {
452 // If there is no JavaScript stack frame count is 0. 453 // If there is no JavaScript stack frame count is 0.
453 return Smi::FromInt(0); 454 return Smi::FromInt(0);
454 } 455 }
455 456
456 for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) { 457 for (StackTraceFrameIterator it(isolate, id); !it.done(); it.Advance()) {
457 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); 458 List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
458 it.frame()->Summarize(&frames); 459 if (it.is_wasm()) {
459 for (int i = frames.length() - 1; i >= 0; i--) { 460 n++;
460 // Omit functions from native and extension scripts. 461 } else {
461 if (frames[i].function()->shared()->IsSubjectToDebugging()) n++; 462 it.javascript_frame()->Summarize(&frames);
463 for (int i = frames.length() - 1; i >= 0; i--) {
464 // Omit functions from native and extension scripts.
465 if (frames[i].function()->shared()->IsSubjectToDebugging()) n++;
466 }
462 } 467 }
463 } 468 }
464 return Smi::FromInt(n); 469 return Smi::FromInt(n);
465 } 470 }
466 471
467 472
468 static const int kFrameDetailsFrameIdIndex = 0; 473 static const int kFrameDetailsFrameIdIndex = 0;
469 static const int kFrameDetailsReceiverIndex = 1; 474 static const int kFrameDetailsReceiverIndex = 1;
470 static const int kFrameDetailsFunctionIndex = 2; 475 static const int kFrameDetailsFunctionIndex = 2;
471 static const int kFrameDetailsArgumentCountIndex = 3; 476 static const int kFrameDetailsScriptIndex = 3;
472 static const int kFrameDetailsLocalCountIndex = 4; 477 static const int kFrameDetailsArgumentCountIndex = 4;
473 static const int kFrameDetailsSourcePositionIndex = 5; 478 static const int kFrameDetailsLocalCountIndex = 5;
474 static const int kFrameDetailsConstructCallIndex = 6; 479 static const int kFrameDetailsSourcePositionIndex = 6;
475 static const int kFrameDetailsAtReturnIndex = 7; 480 static const int kFrameDetailsConstructCallIndex = 7;
476 static const int kFrameDetailsFlagsIndex = 8; 481 static const int kFrameDetailsAtReturnIndex = 8;
477 static const int kFrameDetailsFirstDynamicIndex = 9; 482 static const int kFrameDetailsFlagsIndex = 9;
478 483 static const int kFrameDetailsFirstDynamicIndex = 10;
479 484
480 // Return an array with frame details 485 // Return an array with frame details
481 // args[0]: number: break id 486 // args[0]: number: break id
482 // args[1]: number: frame index 487 // args[1]: number: frame index
483 // 488 //
484 // The array returned contains the following information: 489 // The array returned contains the following information:
485 // 0: Frame id 490 // 0: Frame id
486 // 1: Receiver 491 // 1: Receiver
487 // 2: Function 492 // 2: Function
488 // 3: Argument count 493 // 3: Script
489 // 4: Local count 494 // 4: Argument count
490 // 5: Source position 495 // 5: Local count
491 // 6: Constructor call 496 // 6: Source position
492 // 7: Is at return 497 // 7: Constructor call
493 // 8: Flags 498 // 8: Is at return
499 // 9: Flags
494 // Arguments name, value 500 // Arguments name, value
495 // Locals name, value 501 // Locals name, value
496 // Return value if any 502 // Return value if any
497 RUNTIME_FUNCTION(Runtime_GetFrameDetails) { 503 RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
498 HandleScope scope(isolate); 504 HandleScope scope(isolate);
499 DCHECK(args.length() == 2); 505 DCHECK(args.length() == 2);
500 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); 506 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
501 RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id)); 507 RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
502 508
503 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); 509 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
504 Heap* heap = isolate->heap(); 510 Heap* heap = isolate->heap();
505 511
506 // Find the relevant frame with the requested index. 512 // Find the relevant frame with the requested index.
507 StackFrame::Id id = isolate->debug()->break_frame_id(); 513 StackFrame::Id id = isolate->debug()->break_frame_id();
508 if (id == StackFrame::NO_ID) { 514 if (id == StackFrame::NO_ID) {
509 // If there are no JavaScript stack frames return undefined. 515 // If there are no JavaScript stack frames return undefined.
510 return heap->undefined_value(); 516 return heap->undefined_value();
511 } 517 }
512 518
513 JavaScriptFrameIterator it(isolate, id); 519 StackTraceFrameIterator it(isolate, id);
514 // Inlined frame index in optimized frame, starting from outer function. 520 // Inlined frame index in optimized frame, starting from outer function.
515 int inlined_jsframe_index = 521 int inlined_jsframe_index =
516 DebugFrameHelper::FindIndexedNonNativeFrame(&it, index); 522 DebugFrameHelper::FindIndexedNonNativeFrame(&it, index);
517 if (inlined_jsframe_index == -1) return heap->undefined_value(); 523 if (inlined_jsframe_index == -1) return heap->undefined_value();
518 524
519 FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate); 525 FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate);
520 bool is_optimized = it.frame()->is_optimized();
521 526
522 // Traverse the saved contexts chain to find the active context for the 527 // Traverse the saved contexts chain to find the active context for the
523 // selected frame. 528 // selected frame.
524 SaveContext* save = 529 SaveContext* save =
525 DebugFrameHelper::FindSavedContextForFrame(isolate, it.frame()); 530 DebugFrameHelper::FindSavedContextForFrame(isolate, it.frame());
526 531
527 // Get the frame id. 532 // Get the frame id.
528 Handle<Object> frame_id(DebugFrameHelper::WrapFrameId(it.frame()->id()), 533 Handle<Object> frame_id(DebugFrameHelper::WrapFrameId(it.frame()->id()),
529 isolate); 534 isolate);
530 535
531 // Find source position in unoptimized code. 536 // Find source position in unoptimized code.
532 int position = frame_inspector.GetSourcePosition(); 537 int position = frame_inspector.GetSourcePosition();
533 538
539 if (it.is_wasm()) {
540 // Create the details array (no dynamic information for wasm).
541 Handle<FixedArray> details =
542 isolate->factory()->NewFixedArray(kFrameDetailsFirstDynamicIndex);
543
544 // Add the frame id.
545 details->set(kFrameDetailsFrameIdIndex, *frame_id);
546
547 // Add the function name.
548 Handle<Object> wasm_obj(it.wasm_frame()->wasm_obj(), isolate);
549 int func_index = it.wasm_frame()->function_index();
550 Handle<String> func_name =
551 wasm::GetWasmFunctionName(isolate, wasm_obj, func_index);
552 details->set(kFrameDetailsFunctionIndex, *func_name);
553
554 // Add the script wrapper
555 Handle<Object> script_wrapper =
556 Script::GetWrapper(frame_inspector.GetScript());
557 details->set(kFrameDetailsScriptIndex, *script_wrapper);
558
559 // Add the arguments count.
560 details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(0));
561
562 // Add the locals count
563 details->set(kFrameDetailsLocalCountIndex, Smi::FromInt(0));
564
565 // Add the source position.
566 if (position != RelocInfo::kNoPosition) {
567 details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
568 }
569
570 // Add the constructor information.
571 details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(false));
572
573 // Add the at return information.
574 details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(false));
575
576 // Add flags to indicate information on whether this frame is
577 // bit 0: invoked in the debugger context.
578 // bit 1: optimized frame.
579 // bit 2: inlined in optimized frame
580 int flags = 0;
581 if (*save->context() == *isolate->debug()->debug_context()) {
582 flags |= 1 << 0;
583 }
584 details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
585
586 return *isolate->factory()->NewJSArrayWithElements(details);
587 }
588
589 // Handle JavaScript frames.
590 bool is_optimized = it.frame()->is_optimized();
591
534 // Check for constructor frame. 592 // Check for constructor frame.
535 bool constructor = frame_inspector.IsConstructor(); 593 bool constructor = frame_inspector.IsConstructor();
536 594
537 // Get scope info and read from it for local variable information. 595 // Get scope info and read from it for local variable information.
538 Handle<JSFunction> function = 596 Handle<JSFunction> function =
539 Handle<JSFunction>::cast(frame_inspector.GetFunction()); 597 Handle<JSFunction>::cast(frame_inspector.GetFunction());
540 RUNTIME_ASSERT(function->shared()->IsSubjectToDebugging()); 598 RUNTIME_ASSERT(function->shared()->IsSubjectToDebugging());
541 Handle<SharedFunctionInfo> shared(function->shared()); 599 Handle<SharedFunctionInfo> shared(function->shared());
542 Handle<ScopeInfo> scope_info(shared->scope_info()); 600 Handle<ScopeInfo> scope_info(shared->scope_info());
543 DCHECK(*scope_info != ScopeInfo::Empty(isolate)); 601 DCHECK(*scope_info != ScopeInfo::Empty(isolate));
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 Object* value = context->get(context_slot_index); 646 Object* value = context->get(context_slot_index);
589 locals->set(local * 2 + 1, value); 647 locals->set(local * 2 + 1, value);
590 local++; 648 local++;
591 } 649 }
592 } 650 }
593 651
594 // Check whether this frame is positioned at return. If not top 652 // Check whether this frame is positioned at return. If not top
595 // frame or if the frame is optimized it cannot be at a return. 653 // frame or if the frame is optimized it cannot be at a return.
596 bool at_return = false; 654 bool at_return = false;
597 if (!is_optimized && index == 0) { 655 if (!is_optimized && index == 0) {
598 at_return = isolate->debug()->IsBreakAtReturn(it.frame()); 656 at_return = isolate->debug()->IsBreakAtReturn(it.javascript_frame());
599 } 657 }
600 658
601 // If positioned just before return find the value to be returned and add it 659 // If positioned just before return find the value to be returned and add it
602 // to the frame information. 660 // to the frame information.
603 Handle<Object> return_value = isolate->factory()->undefined_value(); 661 Handle<Object> return_value = isolate->factory()->undefined_value();
604 if (at_return) { 662 if (at_return) {
605 return_value = isolate->debug()->return_value(); 663 return_value = isolate->debug()->return_value();
606 } 664 }
607 665
608 // Now advance to the arguments adapter frame (if any). It contains all 666 // Now advance to the arguments adapter frame (if any). It contains all
609 // the provided parameters whereas the function frame always have the number 667 // the provided parameters whereas the function frame always have the number
610 // of arguments matching the functions parameters. The rest of the 668 // of arguments matching the functions parameters. The rest of the
611 // information (except for what is collected above) is the same. 669 // information (except for what is collected above) is the same.
612 if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) { 670 if ((inlined_jsframe_index == 0) &&
671 it.javascript_frame()->has_adapted_arguments()) {
613 it.AdvanceToArgumentsFrame(); 672 it.AdvanceToArgumentsFrame();
614 frame_inspector.SetArgumentsFrame(it.frame()); 673 frame_inspector.SetArgumentsFrame(it.frame());
615 } 674 }
616 675
617 // Find the number of arguments to fill. At least fill the number of 676 // Find the number of arguments to fill. At least fill the number of
618 // parameters for the function and fill more if more parameters are provided. 677 // parameters for the function and fill more if more parameters are provided.
619 int argument_count = scope_info->ParameterCount(); 678 int argument_count = scope_info->ParameterCount();
620 if (argument_count < frame_inspector.GetParametersCount()) { 679 if (argument_count < frame_inspector.GetParametersCount()) {
621 argument_count = frame_inspector.GetParametersCount(); 680 argument_count = frame_inspector.GetParametersCount();
622 } 681 }
623 682
624 // Calculate the size of the result. 683 // Calculate the size of the result.
625 int details_size = kFrameDetailsFirstDynamicIndex + 684 int details_size = kFrameDetailsFirstDynamicIndex +
626 2 * (argument_count + local_count) + (at_return ? 1 : 0); 685 2 * (argument_count + local_count) + (at_return ? 1 : 0);
627 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); 686 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
628 687
629 // Add the frame id. 688 // Add the frame id.
630 details->set(kFrameDetailsFrameIdIndex, *frame_id); 689 details->set(kFrameDetailsFrameIdIndex, *frame_id);
631 690
632 // Add the function (same as in function frame). 691 // Add the function (same as in function frame).
633 details->set(kFrameDetailsFunctionIndex, *(frame_inspector.GetFunction())); 692 details->set(kFrameDetailsFunctionIndex, *(frame_inspector.GetFunction()));
634 693
694 // Add the script wrapper
695 Handle<Object> script_wrapper =
696 Script::GetWrapper(frame_inspector.GetScript());
697 details->set(kFrameDetailsScriptIndex, *script_wrapper);
698
635 // Add the arguments count. 699 // Add the arguments count.
636 details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count)); 700 details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
637 701
638 // Add the locals count 702 // Add the locals count
639 details->set(kFrameDetailsLocalCountIndex, Smi::FromInt(local_count)); 703 details->set(kFrameDetailsLocalCountIndex, Smi::FromInt(local_count));
640 704
641 // Add the source position. 705 // Add the source position.
642 if (position != RelocInfo::kNoPosition) { 706 if (position != RelocInfo::kNoPosition) {
643 details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position)); 707 details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
644 } else { 708 } else {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]); 852 CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
789 853
790 ScopeIterator::Option option = ScopeIterator::DEFAULT; 854 ScopeIterator::Option option = ScopeIterator::DEFAULT;
791 if (args.length() == 4) { 855 if (args.length() == 4) {
792 CONVERT_BOOLEAN_ARG_CHECKED(flag, 3); 856 CONVERT_BOOLEAN_ARG_CHECKED(flag, 3);
793 if (flag) option = ScopeIterator::IGNORE_NESTED_SCOPES; 857 if (flag) option = ScopeIterator::IGNORE_NESTED_SCOPES;
794 } 858 }
795 859
796 // Get the frame where the debugging is performed. 860 // Get the frame where the debugging is performed.
797 StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id); 861 StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id);
798 JavaScriptFrameIterator frame_it(isolate, id); 862 StackTraceFrameIterator frame_it(isolate, id);
799 JavaScriptFrame* frame = frame_it.frame(); 863 StandardFrame* frame = frame_it.frame();
800 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); 864 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
801 865
802 List<Handle<JSObject> > result(4); 866 List<Handle<JSObject> > result(4);
803 ScopeIterator it(isolate, &frame_inspector, option); 867 ScopeIterator it(isolate, &frame_inspector, option);
804 for (; !it.Done(); it.Next()) { 868 for (; !it.Done(); it.Next()) {
805 Handle<JSObject> details; 869 Handle<JSObject> details;
806 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details, 870 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details,
807 it.MaterializeScopeDetails()); 871 it.MaterializeScopeDetails());
808 result.Add(details); 872 result.Add(details);
809 } 873 }
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 1574
1511 static Handle<Object> GetJSPositionInfo(Handle<Script> script, int position, 1575 static Handle<Object> GetJSPositionInfo(Handle<Script> script, int position,
1512 Script::OffsetFlag offset_flag, 1576 Script::OffsetFlag offset_flag,
1513 Isolate* isolate) { 1577 Isolate* isolate) {
1514 Script::PositionInfo info; 1578 Script::PositionInfo info;
1515 if (!script->GetPositionInfo(position, &info, offset_flag)) { 1579 if (!script->GetPositionInfo(position, &info, offset_flag)) {
1516 return handle(isolate->heap()->null_value(), isolate); 1580 return handle(isolate->heap()->null_value(), isolate);
1517 } 1581 }
1518 1582
1519 Handle<String> source = handle(String::cast(script->source()), isolate); 1583 Handle<String> source = handle(String::cast(script->source()), isolate);
1520 Handle<String> sourceText = 1584 Handle<String> sourceText = script->type() == Script::TYPE_WASM
1521 isolate->factory()->NewSubString(source, info.line_start, info.line_end); 1585 ? isolate->factory()->empty_string()
1586 : isolate->factory()->NewSubString(
1587 source, info.line_start, info.line_end);
1522 1588
1523 Handle<JSObject> jsinfo = 1589 Handle<JSObject> jsinfo =
1524 isolate->factory()->NewJSObject(isolate->object_function()); 1590 isolate->factory()->NewJSObject(isolate->object_function());
1525 1591
1526 JSObject::AddProperty(jsinfo, isolate->factory()->script_string(), script, 1592 JSObject::AddProperty(jsinfo, isolate->factory()->script_string(), script,
1527 NONE); 1593 NONE);
1528 JSObject::AddProperty(jsinfo, isolate->factory()->position_string(), 1594 JSObject::AddProperty(jsinfo, isolate->factory()->position_string(),
1529 handle(Smi::FromInt(position), isolate), NONE); 1595 handle(Smi::FromInt(position), isolate), NONE);
1530 JSObject::AddProperty(jsinfo, isolate->factory()->line_string(), 1596 JSObject::AddProperty(jsinfo, isolate->factory()->line_string(),
1531 handle(Smi::FromInt(info.line), isolate), NONE); 1597 handle(Smi::FromInt(info.line), isolate), NONE);
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1714 return Smi::FromInt(isolate->debug()->is_active()); 1780 return Smi::FromInt(isolate->debug()->is_active());
1715 } 1781 }
1716 1782
1717 1783
1718 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { 1784 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) {
1719 UNIMPLEMENTED(); 1785 UNIMPLEMENTED();
1720 return NULL; 1786 return NULL;
1721 } 1787 }
1722 } // namespace internal 1788 } // namespace internal
1723 } // namespace v8 1789 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.cc ('k') | src/runtime/runtime-liveedit.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698