Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/isolate.h" | 5 #include "src/isolate.h" |
| 6 | 6 |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 | 8 |
| 9 #include <fstream> // NOLINT(readability/streams) | 9 #include <fstream> // NOLINT(readability/streams) |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 607 JSReceiver::GetDataProperty(error_object, key_detailed); | 607 JSReceiver::GetDataProperty(error_object, key_detailed); |
| 608 if (stack_trace->IsJSArray()) return Handle<JSArray>::cast(stack_trace); | 608 if (stack_trace->IsJSArray()) return Handle<JSArray>::cast(stack_trace); |
| 609 return Handle<JSArray>(); | 609 return Handle<JSArray>(); |
| 610 } | 610 } |
| 611 | 611 |
| 612 | 612 |
| 613 class CaptureStackTraceHelper { | 613 class CaptureStackTraceHelper { |
| 614 public: | 614 public: |
| 615 CaptureStackTraceHelper(Isolate* isolate, | 615 CaptureStackTraceHelper(Isolate* isolate, |
| 616 StackTrace::StackTraceOptions options) | 616 StackTrace::StackTraceOptions options) |
| 617 : isolate_(isolate) { | 617 : isolate_(isolate), options_(options) {} |
| 618 if (options & StackTrace::kColumnOffset) { | |
| 619 column_key_ = | |
| 620 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("column")); | |
| 621 } | |
| 622 if (options & StackTrace::kLineNumber) { | |
| 623 line_key_ = | |
| 624 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("lineNumber")); | |
| 625 } | |
| 626 if (options & StackTrace::kScriptId) { | |
| 627 script_id_key_ = | |
| 628 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("scriptId")); | |
| 629 } | |
| 630 if (options & StackTrace::kScriptName) { | |
| 631 script_name_key_ = | |
| 632 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("scriptName")); | |
| 633 } | |
| 634 if (options & StackTrace::kScriptNameOrSourceURL) { | |
| 635 script_name_or_source_url_key_ = factory()->InternalizeOneByteString( | |
| 636 STATIC_CHAR_VECTOR("scriptNameOrSourceURL")); | |
| 637 } | |
| 638 if (options & StackTrace::kFunctionName) { | |
| 639 function_key_ = factory()->InternalizeOneByteString( | |
| 640 STATIC_CHAR_VECTOR("functionName")); | |
| 641 } | |
| 642 if (options & StackTrace::kIsEval) { | |
| 643 eval_key_ = | |
| 644 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("isEval")); | |
| 645 } | |
| 646 if (options & StackTrace::kIsConstructor) { | |
| 647 constructor_key_ = factory()->InternalizeOneByteString( | |
| 648 STATIC_CHAR_VECTOR("isConstructor")); | |
| 649 } | |
| 650 } | |
| 651 | 618 |
| 652 Handle<JSObject> NewStackFrameObject(FrameSummary& summ) { | 619 Handle<StackFrameInfo> NewStackFrameObject(FrameSummary& summ) { |
| 653 if (summ.IsJavaScript()) return NewStackFrameObject(summ.AsJavaScript()); | 620 if (summ.IsJavaScript()) return NewStackFrameObject(summ.AsJavaScript()); |
| 654 if (summ.IsWasm()) return NewStackFrameObject(summ.AsWasm()); | 621 if (summ.IsWasm()) return NewStackFrameObject(summ.AsWasm()); |
| 655 UNREACHABLE(); | 622 UNREACHABLE(); |
| 656 return Handle<JSObject>::null(); | 623 return factory()->NewStackFrameInfo(); |
| 657 } | 624 } |
| 658 | 625 |
| 659 Handle<JSObject> NewStackFrameObject( | 626 Handle<StackFrameInfo> NewStackFrameObject( |
| 660 const FrameSummary::JavaScriptFrameSummary& summ) { | 627 const FrameSummary::JavaScriptFrameSummary& summ) { |
| 661 Handle<JSObject> stack_frame = | 628 Handle<StackFrameInfo> frame = factory()->NewStackFrameInfo(); |
| 662 factory()->NewJSObject(isolate_->object_function()); | |
| 663 Handle<Script> script = Handle<Script>::cast(summ.script()); | 629 Handle<Script> script = Handle<Script>::cast(summ.script()); |
| 664 | 630 if (options_ & StackTrace::kLineNumber) { |
| 665 if (!line_key_.is_null()) { | |
| 666 Script::PositionInfo info; | 631 Script::PositionInfo info; |
| 667 bool valid_pos = Script::GetPositionInfo(script, summ.SourcePosition(), | 632 bool valid_pos = Script::GetPositionInfo(script, summ.SourcePosition(), |
| 668 &info, Script::WITH_OFFSET); | 633 &info, Script::WITH_OFFSET); |
|
Yang
2017/04/03 07:58:40
Getting position info is fairly expensive. We can
kozy
2017/04/03 14:54:56
Thanks, I'll upload separate CLfor this because cu
| |
| 669 | 634 if (valid_pos) { |
| 670 if (!column_key_.is_null() && valid_pos) { | 635 frame->set_line_number(info.line + 1); |
| 671 JSObject::AddProperty(stack_frame, column_key_, | 636 if (options_ & StackTrace::kColumnOffset) { |
| 672 handle(Smi::FromInt(info.column + 1), isolate_), | 637 frame->set_column_number(info.column + 1); |
| 673 NONE); | 638 } |
| 674 } | 639 } |
| 675 JSObject::AddProperty(stack_frame, line_key_, | |
| 676 handle(Smi::FromInt(info.line + 1), isolate_), | |
| 677 NONE); | |
| 678 } | 640 } |
| 679 | 641 |
| 680 if (!script_id_key_.is_null()) { | 642 if (options_ & StackTrace::kScriptId) frame->set_script_id(script->id()); |
| 681 JSObject::AddProperty(stack_frame, script_id_key_, | 643 if (options_ & StackTrace::kScriptName) { |
| 682 handle(Smi::FromInt(script->id()), isolate_), NONE); | 644 frame->set_script_name(script->name()); |
| 683 } | 645 } |
| 684 | 646 if (options_ & StackTrace::kScriptNameOrSourceURL) { |
| 685 if (!script_name_key_.is_null()) { | 647 frame->set_script_name_or_source_url(script->GetNameOrSourceURL()); |
| 686 JSObject::AddProperty(stack_frame, script_name_key_, | |
| 687 handle(script->name(), isolate_), NONE); | |
| 688 } | 648 } |
| 689 | 649 if (options_ & StackTrace::kIsEval) { |
| 690 if (!script_name_or_source_url_key_.is_null()) { | 650 frame->set_is_eval(script->compilation_type() == |
| 691 Handle<Object> result(script->GetNameOrSourceURL(), isolate_); | 651 Script::COMPILATION_TYPE_EVAL); |
| 692 JSObject::AddProperty(stack_frame, script_name_or_source_url_key_, result, | |
| 693 NONE); | |
| 694 } | 652 } |
| 695 | 653 if (options_ & StackTrace::kFunctionName) { |
| 696 if (!eval_key_.is_null()) { | 654 frame->set_function_name(*summ.FunctionName()); |
| 697 Handle<Object> is_eval = factory()->ToBoolean( | |
| 698 script->compilation_type() == Script::COMPILATION_TYPE_EVAL); | |
| 699 JSObject::AddProperty(stack_frame, eval_key_, is_eval, NONE); | |
| 700 } | 655 } |
| 701 | 656 if (options_ & StackTrace::kIsConstructor) { |
| 702 if (!function_key_.is_null()) { | 657 frame->set_is_constructor(summ.is_constructor()); |
| 703 Handle<String> fun_name = summ.FunctionName(); | |
| 704 JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE); | |
| 705 } | 658 } |
| 706 | 659 return frame; |
| 707 if (!constructor_key_.is_null()) { | |
| 708 Handle<Object> is_constructor_obj = | |
| 709 factory()->ToBoolean(summ.is_constructor()); | |
| 710 JSObject::AddProperty(stack_frame, constructor_key_, is_constructor_obj, | |
| 711 NONE); | |
| 712 } | |
| 713 return stack_frame; | |
| 714 } | 660 } |
| 715 | 661 |
| 716 Handle<JSObject> NewStackFrameObject(BuiltinExitFrame* frame) { | 662 Handle<StackFrameInfo> NewStackFrameObject( |
| 717 Handle<JSObject> stack_frame = | 663 const FrameSummary::WasmFrameSummary& summ) { |
| 718 factory()->NewJSObject(isolate_->object_function()); | 664 Handle<StackFrameInfo> info = factory()->NewStackFrameInfo(); |
| 719 Handle<JSFunction> fun = handle(frame->function(), isolate_); | |
| 720 if (!function_key_.is_null()) { | |
| 721 Handle<Object> fun_name = JSFunction::GetDebugName(fun); | |
| 722 JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE); | |
| 723 } | |
| 724 | 665 |
| 725 // We don't have a script and hence cannot set line and col positions. | 666 if (options_ & StackTrace::kFunctionName) { |
| 726 DCHECK(!fun->shared()->script()->IsScript()); | |
| 727 | |
| 728 return stack_frame; | |
| 729 } | |
| 730 | |
| 731 Handle<JSObject> NewStackFrameObject( | |
| 732 const FrameSummary::WasmFrameSummary& summ) { | |
| 733 Handle<JSObject> stack_frame = | |
| 734 factory()->NewJSObject(isolate_->object_function()); | |
| 735 | |
| 736 if (!function_key_.is_null()) { | |
| 737 Handle<WasmCompiledModule> compiled_module( | 667 Handle<WasmCompiledModule> compiled_module( |
| 738 summ.wasm_instance()->compiled_module(), isolate_); | 668 summ.wasm_instance()->compiled_module(), isolate_); |
| 739 Handle<String> name = WasmCompiledModule::GetFunctionName( | 669 Handle<String> name = WasmCompiledModule::GetFunctionName( |
| 740 isolate_, compiled_module, summ.function_index()); | 670 isolate_, compiled_module, summ.function_index()); |
| 741 JSObject::AddProperty(stack_frame, function_key_, name, NONE); | 671 info->set_function_name(*name); |
| 742 } | 672 } |
| 743 // Encode the function index as line number (1-based). | 673 // Encode the function index as line number (1-based). |
| 744 if (!line_key_.is_null()) { | 674 if (options_ & StackTrace::kLineNumber) { |
| 745 JSObject::AddProperty( | 675 info->set_line_number(summ.function_index() + 1); |
| 746 stack_frame, line_key_, | |
| 747 isolate_->factory()->NewNumberFromInt(summ.function_index() + 1), | |
| 748 NONE); | |
| 749 } | 676 } |
| 750 // Encode the byte offset as column (1-based). | 677 // Encode the byte offset as column (1-based). |
| 751 if (!column_key_.is_null()) { | 678 if (options_ & StackTrace::kColumnOffset) { |
| 752 int position = summ.byte_offset(); | 679 int position = summ.byte_offset(); |
| 753 // Make position 1-based. | 680 // Make position 1-based. |
| 754 if (position >= 0) ++position; | 681 if (position >= 0) ++position; |
| 755 JSObject::AddProperty(stack_frame, column_key_, | 682 info->set_column_number(position); |
| 756 isolate_->factory()->NewNumberFromInt(position), | |
| 757 NONE); | |
| 758 } | 683 } |
| 759 if (!script_id_key_.is_null()) { | 684 if (options_ & StackTrace::kScriptId) { |
| 760 int script_id = summ.script()->id(); | 685 info->set_script_id(summ.script()->id()); |
| 761 JSObject::AddProperty(stack_frame, script_id_key_, | |
| 762 handle(Smi::FromInt(script_id), isolate_), NONE); | |
| 763 } | 686 } |
| 764 | 687 return info; |
| 765 return stack_frame; | |
| 766 } | 688 } |
| 767 | 689 |
| 768 private: | 690 private: |
| 769 inline Factory* factory() { return isolate_->factory(); } | 691 inline Factory* factory() { return isolate_->factory(); } |
| 770 | 692 |
| 771 Isolate* isolate_; | 693 Isolate* isolate_; |
| 772 Handle<String> column_key_; | 694 StackTrace::StackTraceOptions options_; |
| 773 Handle<String> line_key_; | |
| 774 Handle<String> script_id_key_; | |
| 775 Handle<String> script_name_key_; | |
| 776 Handle<String> script_name_or_source_url_key_; | |
| 777 Handle<String> function_key_; | |
| 778 Handle<String> eval_key_; | |
| 779 Handle<String> constructor_key_; | |
| 780 }; | 695 }; |
| 781 | 696 |
| 782 Handle<JSArray> Isolate::CaptureCurrentStackTrace( | 697 Handle<JSArray> Isolate::CaptureCurrentStackTrace( |
| 783 int frame_limit, StackTrace::StackTraceOptions options) { | 698 int frame_limit, StackTrace::StackTraceOptions options) { |
| 784 DisallowJavascriptExecution no_js(this); | 699 DisallowJavascriptExecution no_js(this); |
| 785 CaptureStackTraceHelper helper(this, options); | 700 CaptureStackTraceHelper helper(this, options); |
| 786 | 701 |
| 787 // Ensure no negative values. | 702 // Ensure no negative values. |
| 788 int limit = Max(frame_limit, 0); | 703 int limit = Max(frame_limit, 0); |
| 789 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit); | 704 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit); |
| 790 Handle<FixedArray> stack_trace_elems( | 705 Handle<FixedArray> stack_trace_elems( |
| 791 FixedArray::cast(stack_trace->elements()), this); | 706 FixedArray::cast(stack_trace->elements()), this); |
| 792 | 707 |
| 793 int frames_seen = 0; | 708 int frames_seen = 0; |
| 794 for (StackTraceFrameIterator it(this); !it.done() && (frames_seen < limit); | 709 for (StackTraceFrameIterator it(this); !it.done() && (frames_seen < limit); |
| 795 it.Advance()) { | 710 it.Advance()) { |
| 796 StandardFrame* frame = it.frame(); | 711 StandardFrame* frame = it.frame(); |
| 797 // Set initial size to the maximum inlining level + 1 for the outermost | 712 // Set initial size to the maximum inlining level + 1 for the outermost |
| 798 // function. | 713 // function. |
| 799 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); | 714 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); |
| 800 frame->Summarize(&frames); | 715 frame->Summarize(&frames); |
| 801 for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) { | 716 for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) { |
| 802 // Filter frames from other security contexts. | 717 // Filter frames from other security contexts. |
| 803 if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) && | 718 if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) && |
| 804 !this->context()->HasSameSecurityTokenAs(*frames[i].native_context())) | 719 !this->context()->HasSameSecurityTokenAs(*frames[i].native_context())) |
| 805 continue; | 720 continue; |
| 806 Handle<JSObject> new_frame_obj = helper.NewStackFrameObject(frames[i]); | 721 Handle<StackFrameInfo> new_frame_obj = |
| 722 helper.NewStackFrameObject(frames[i]); | |
| 807 stack_trace_elems->set(frames_seen, *new_frame_obj); | 723 stack_trace_elems->set(frames_seen, *new_frame_obj); |
| 808 frames_seen++; | 724 frames_seen++; |
| 809 } | 725 } |
| 810 } | 726 } |
| 811 | 727 |
| 812 stack_trace->set_length(Smi::FromInt(frames_seen)); | 728 stack_trace->set_length(Smi::FromInt(frames_seen)); |
| 813 return stack_trace; | 729 return stack_trace; |
| 814 } | 730 } |
| 815 | 731 |
| 816 | 732 |
| (...skipping 2922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3739 // Then check whether this scope intercepts. | 3655 // Then check whether this scope intercepts. |
| 3740 if ((flag & intercept_mask_)) { | 3656 if ((flag & intercept_mask_)) { |
| 3741 intercepted_flags_ |= flag; | 3657 intercepted_flags_ |= flag; |
| 3742 return true; | 3658 return true; |
| 3743 } | 3659 } |
| 3744 return false; | 3660 return false; |
| 3745 } | 3661 } |
| 3746 | 3662 |
| 3747 } // namespace internal | 3663 } // namespace internal |
| 3748 } // namespace v8 | 3664 } // namespace v8 |
| OLD | NEW |