| OLD | NEW |
| 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/compiler.h" | 8 #include "src/compiler.h" |
| 9 #include "src/debug/debug-evaluate.h" | 9 #include "src/debug/debug-evaluate.h" |
| 10 #include "src/debug/debug-frames.h" | 10 #include "src/debug/debug-frames.h" |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 CHECK(isolate->debug()->CheckExecutionState(break_id)); | 428 CHECK(isolate->debug()->CheckExecutionState(break_id)); |
| 429 | 429 |
| 430 // Count all frames which are relevant to debugging stack trace. | 430 // Count all frames which are relevant to debugging stack trace. |
| 431 int n = 0; | 431 int n = 0; |
| 432 StackFrame::Id id = isolate->debug()->break_frame_id(); | 432 StackFrame::Id id = isolate->debug()->break_frame_id(); |
| 433 if (id == StackFrame::NO_ID) { | 433 if (id == StackFrame::NO_ID) { |
| 434 // If there is no JavaScript stack frame count is 0. | 434 // If there is no JavaScript stack frame count is 0. |
| 435 return Smi::kZero; | 435 return Smi::kZero; |
| 436 } | 436 } |
| 437 | 437 |
| 438 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); |
| 438 for (StackTraceFrameIterator it(isolate, id); !it.done(); it.Advance()) { | 439 for (StackTraceFrameIterator it(isolate, id); !it.done(); it.Advance()) { |
| 439 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); | 440 frames.Clear(); |
| 440 if (it.is_wasm()) { | 441 it.frame()->Summarize(&frames); |
| 441 n++; | 442 for (int i = frames.length() - 1; i >= 0; i--) { |
| 442 } else { | 443 // Omit functions from native and extension scripts. |
| 443 it.javascript_frame()->Summarize(&frames); | 444 if (frames[i].is_subject_to_debugging()) n++; |
| 444 for (int i = frames.length() - 1; i >= 0; i--) { | |
| 445 // Omit functions from native and extension scripts. | |
| 446 if (frames[i].function()->shared()->IsSubjectToDebugging()) n++; | |
| 447 } | |
| 448 } | 445 } |
| 449 } | 446 } |
| 450 return Smi::FromInt(n); | 447 return Smi::FromInt(n); |
| 451 } | 448 } |
| 452 | 449 |
| 453 | |
| 454 static const int kFrameDetailsFrameIdIndex = 0; | 450 static const int kFrameDetailsFrameIdIndex = 0; |
| 455 static const int kFrameDetailsReceiverIndex = 1; | 451 static const int kFrameDetailsReceiverIndex = 1; |
| 456 static const int kFrameDetailsFunctionIndex = 2; | 452 static const int kFrameDetailsFunctionIndex = 2; |
| 457 static const int kFrameDetailsScriptIndex = 3; | 453 static const int kFrameDetailsScriptIndex = 3; |
| 458 static const int kFrameDetailsArgumentCountIndex = 4; | 454 static const int kFrameDetailsArgumentCountIndex = 4; |
| 459 static const int kFrameDetailsLocalCountIndex = 5; | 455 static const int kFrameDetailsLocalCountIndex = 5; |
| 460 static const int kFrameDetailsSourcePositionIndex = 6; | 456 static const int kFrameDetailsSourcePositionIndex = 6; |
| 461 static const int kFrameDetailsConstructCallIndex = 7; | 457 static const int kFrameDetailsConstructCallIndex = 7; |
| 462 static const int kFrameDetailsAtReturnIndex = 8; | 458 static const int kFrameDetailsAtReturnIndex = 8; |
| 463 static const int kFrameDetailsFlagsIndex = 9; | 459 static const int kFrameDetailsFlagsIndex = 9; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 492 | 488 |
| 493 // Find the relevant frame with the requested index. | 489 // Find the relevant frame with the requested index. |
| 494 StackFrame::Id id = isolate->debug()->break_frame_id(); | 490 StackFrame::Id id = isolate->debug()->break_frame_id(); |
| 495 if (id == StackFrame::NO_ID) { | 491 if (id == StackFrame::NO_ID) { |
| 496 // If there are no JavaScript stack frames return undefined. | 492 // If there are no JavaScript stack frames return undefined. |
| 497 return heap->undefined_value(); | 493 return heap->undefined_value(); |
| 498 } | 494 } |
| 499 | 495 |
| 500 StackTraceFrameIterator it(isolate, id); | 496 StackTraceFrameIterator it(isolate, id); |
| 501 // Inlined frame index in optimized frame, starting from outer function. | 497 // Inlined frame index in optimized frame, starting from outer function. |
| 502 int inlined_jsframe_index = | 498 int inlined_frame_index = |
| 503 DebugFrameHelper::FindIndexedNonNativeFrame(&it, index); | 499 DebugFrameHelper::FindIndexedNonNativeFrame(&it, index); |
| 504 if (inlined_jsframe_index == -1) return heap->undefined_value(); | 500 if (inlined_frame_index == -1) return heap->undefined_value(); |
| 505 | 501 |
| 506 FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate); | 502 FrameInspector frame_inspector(it.frame(), inlined_frame_index, isolate); |
| 507 | 503 |
| 508 // Traverse the saved contexts chain to find the active context for the | 504 // Traverse the saved contexts chain to find the active context for the |
| 509 // selected frame. | 505 // selected frame. |
| 510 SaveContext* save = | 506 SaveContext* save = |
| 511 DebugFrameHelper::FindSavedContextForFrame(isolate, it.frame()); | 507 DebugFrameHelper::FindSavedContextForFrame(isolate, it.frame()); |
| 512 | 508 |
| 513 // Get the frame id. | 509 // Get the frame id. |
| 514 Handle<Object> frame_id(DebugFrameHelper::WrapFrameId(it.frame()->id()), | 510 Handle<Object> frame_id(DebugFrameHelper::WrapFrameId(it.frame()->id()), |
| 515 isolate); | 511 isolate); |
| 516 | 512 |
| 517 // Find source position in unoptimized code. | 513 if (frame_inspector.summary().IsWasm()) { |
| 518 int position = frame_inspector.GetSourcePosition(); | |
| 519 | |
| 520 if (it.is_wasm()) { | |
| 521 // Create the details array (no dynamic information for wasm). | 514 // Create the details array (no dynamic information for wasm). |
| 522 Handle<FixedArray> details = | 515 Handle<FixedArray> details = |
| 523 isolate->factory()->NewFixedArray(kFrameDetailsFirstDynamicIndex); | 516 isolate->factory()->NewFixedArray(kFrameDetailsFirstDynamicIndex); |
| 524 | 517 |
| 525 // Add the frame id. | 518 // Add the frame id. |
| 526 details->set(kFrameDetailsFrameIdIndex, *frame_id); | 519 details->set(kFrameDetailsFrameIdIndex, *frame_id); |
| 527 | 520 |
| 528 // Add the function name. | 521 // Add the function name. |
| 529 Handle<WasmCompiledModule> compiled_module( | 522 Handle<String> func_name = frame_inspector.summary().FunctionName(); |
| 530 it.wasm_compiled_frame()->wasm_instance()->compiled_module(), isolate); | |
| 531 int func_index = it.wasm_compiled_frame()->function_index(); | |
| 532 Handle<String> func_name = WasmCompiledModule::GetFunctionName( | |
| 533 isolate, compiled_module, func_index); | |
| 534 details->set(kFrameDetailsFunctionIndex, *func_name); | 523 details->set(kFrameDetailsFunctionIndex, *func_name); |
| 535 | 524 |
| 536 // Add the script wrapper | 525 // Add the script wrapper |
| 537 Handle<Object> script_wrapper = | 526 Handle<Object> script_wrapper = |
| 538 Script::GetWrapper(frame_inspector.GetScript()); | 527 Script::GetWrapper(frame_inspector.GetScript()); |
| 539 details->set(kFrameDetailsScriptIndex, *script_wrapper); | 528 details->set(kFrameDetailsScriptIndex, *script_wrapper); |
| 540 | 529 |
| 541 // Add the arguments count. | 530 // Add the arguments count. |
| 542 details->set(kFrameDetailsArgumentCountIndex, Smi::kZero); | 531 details->set(kFrameDetailsArgumentCountIndex, Smi::kZero); |
| 543 | 532 |
| 544 // Add the locals count | 533 // Add the locals count |
| 545 details->set(kFrameDetailsLocalCountIndex, Smi::kZero); | 534 details->set(kFrameDetailsLocalCountIndex, Smi::kZero); |
| 546 | 535 |
| 547 // Add the source position. | 536 // Add the source position. |
| 548 // For wasm, it is function-local, so translate it to a module-relative | 537 int position = frame_inspector.summary().SourcePosition(); |
| 549 // position, such that together with the script it uniquely identifies the | 538 details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position)); |
| 550 // position. | |
| 551 Handle<Object> positionValue; | |
| 552 if (position != kNoSourcePosition) { | |
| 553 int translated_position = position; | |
| 554 // No further translation needed for asm.js modules. | |
| 555 if (!compiled_module->is_asm_js()) { | |
| 556 translated_position += | |
| 557 wasm::GetFunctionCodeOffset(compiled_module, func_index); | |
| 558 } | |
| 559 details->set(kFrameDetailsSourcePositionIndex, | |
| 560 Smi::FromInt(translated_position)); | |
| 561 } | |
| 562 | 539 |
| 563 // Add the constructor information. | 540 // Add the constructor information. |
| 564 details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(false)); | 541 details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(false)); |
| 565 | 542 |
| 566 // Add the at return information. | 543 // Add the at return information. |
| 567 details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(false)); | 544 details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(false)); |
| 568 | 545 |
| 569 // Add flags to indicate information on whether this frame is | 546 // Add flags to indicate information on whether this frame is |
| 570 // bit 0: invoked in the debugger context. | 547 // bit 0: invoked in the debugger context. |
| 571 // bit 1: optimized frame. | 548 // bit 1: optimized frame. |
| 572 // bit 2: inlined in optimized frame | 549 // bit 2: inlined in optimized frame |
| 573 int flags = 0; | 550 int flags = 0; |
| 574 if (*save->context() == *isolate->debug()->debug_context()) { | 551 if (*save->context() == *isolate->debug()->debug_context()) { |
| 575 flags |= 1 << 0; | 552 flags |= 1 << 0; |
| 576 } | 553 } |
| 577 details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags)); | 554 details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags)); |
| 578 | 555 |
| 579 return *isolate->factory()->NewJSArrayWithElements(details); | 556 return *isolate->factory()->NewJSArrayWithElements(details); |
| 580 } | 557 } |
| 581 | 558 |
| 559 // Find source position in unoptimized code. |
| 560 int position = frame_inspector.GetSourcePosition(); |
| 561 |
| 582 // Handle JavaScript frames. | 562 // Handle JavaScript frames. |
| 583 bool is_optimized = it.frame()->is_optimized(); | 563 bool is_optimized = it.frame()->is_optimized(); |
| 584 | 564 |
| 585 // Check for constructor frame. | 565 // Check for constructor frame. |
| 586 bool constructor = frame_inspector.IsConstructor(); | 566 bool constructor = frame_inspector.IsConstructor(); |
| 587 | 567 |
| 588 // Get scope info and read from it for local variable information. | 568 // Get scope info and read from it for local variable information. |
| 589 Handle<JSFunction> function = | 569 Handle<JSFunction> function = |
| 590 Handle<JSFunction>::cast(frame_inspector.GetFunction()); | 570 Handle<JSFunction>::cast(frame_inspector.GetFunction()); |
| 591 CHECK(function->shared()->IsSubjectToDebugging()); | 571 CHECK(function->shared()->IsSubjectToDebugging()); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 // to the frame information. | 633 // to the frame information. |
| 654 Handle<Object> return_value = isolate->factory()->undefined_value(); | 634 Handle<Object> return_value = isolate->factory()->undefined_value(); |
| 655 if (at_return) { | 635 if (at_return) { |
| 656 return_value = isolate->debug()->return_value(); | 636 return_value = isolate->debug()->return_value(); |
| 657 } | 637 } |
| 658 | 638 |
| 659 // Now advance to the arguments adapter frame (if any). It contains all | 639 // Now advance to the arguments adapter frame (if any). It contains all |
| 660 // the provided parameters whereas the function frame always have the number | 640 // the provided parameters whereas the function frame always have the number |
| 661 // of arguments matching the functions parameters. The rest of the | 641 // of arguments matching the functions parameters. The rest of the |
| 662 // information (except for what is collected above) is the same. | 642 // information (except for what is collected above) is the same. |
| 663 if ((inlined_jsframe_index == 0) && | 643 if ((inlined_frame_index == 0) && |
| 664 it.javascript_frame()->has_adapted_arguments()) { | 644 it.javascript_frame()->has_adapted_arguments()) { |
| 665 it.AdvanceToArgumentsFrame(); | 645 it.AdvanceToArgumentsFrame(); |
| 666 frame_inspector.SetArgumentsFrame(it.frame()); | 646 frame_inspector.SetArgumentsFrame(it.frame()); |
| 667 } | 647 } |
| 668 | 648 |
| 669 // Find the number of arguments to fill. At least fill the number of | 649 // Find the number of arguments to fill. At least fill the number of |
| 670 // parameters for the function and fill more if more parameters are provided. | 650 // parameters for the function and fill more if more parameters are provided. |
| 671 int argument_count = scope_info->ParameterCount(); | 651 int argument_count = scope_info->ParameterCount(); |
| 672 if (argument_count < frame_inspector.GetParametersCount()) { | 652 if (argument_count < frame_inspector.GetParametersCount()) { |
| 673 argument_count = frame_inspector.GetParametersCount(); | 653 argument_count = frame_inspector.GetParametersCount(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 711 // Add flags to indicate information on whether this frame is | 691 // Add flags to indicate information on whether this frame is |
| 712 // bit 0: invoked in the debugger context. | 692 // bit 0: invoked in the debugger context. |
| 713 // bit 1: optimized frame. | 693 // bit 1: optimized frame. |
| 714 // bit 2: inlined in optimized frame | 694 // bit 2: inlined in optimized frame |
| 715 int flags = 0; | 695 int flags = 0; |
| 716 if (*save->context() == *isolate->debug()->debug_context()) { | 696 if (*save->context() == *isolate->debug()->debug_context()) { |
| 717 flags |= 1 << 0; | 697 flags |= 1 << 0; |
| 718 } | 698 } |
| 719 if (is_optimized) { | 699 if (is_optimized) { |
| 720 flags |= 1 << 1; | 700 flags |= 1 << 1; |
| 721 flags |= inlined_jsframe_index << 2; | 701 flags |= inlined_frame_index << 2; |
| 722 } | 702 } |
| 723 details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags)); | 703 details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags)); |
| 724 | 704 |
| 725 // Fill the dynamic part. | 705 // Fill the dynamic part. |
| 726 int details_index = kFrameDetailsFirstDynamicIndex; | 706 int details_index = kFrameDetailsFirstDynamicIndex; |
| 727 | 707 |
| 728 // Add arguments name and value. | 708 // Add arguments name and value. |
| 729 for (int i = 0; i < argument_count; i++) { | 709 for (int i = 0; i < argument_count; i++) { |
| 730 // Name of the argument. | 710 // Name of the argument. |
| 731 if (i < scope_info->ParameterCount()) { | 711 if (i < scope_info->ParameterCount()) { |
| (...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1939 } | 1919 } |
| 1940 | 1920 |
| 1941 | 1921 |
| 1942 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { | 1922 RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { |
| 1943 UNIMPLEMENTED(); | 1923 UNIMPLEMENTED(); |
| 1944 return NULL; | 1924 return NULL; |
| 1945 } | 1925 } |
| 1946 | 1926 |
| 1947 } // namespace internal | 1927 } // namespace internal |
| 1948 } // namespace v8 | 1928 } // namespace v8 |
| OLD | NEW |