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

Side by Side Diff: src/isolate.cc

Issue 2619353006: Refactor FrameSummary for JS and Wasm frames (Closed)
Patch Set: Address comment Created 3 years, 11 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/frames-inl.h ('k') | src/list.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/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 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 case StackFrame::JAVA_SCRIPT: 454 case StackFrame::JAVA_SCRIPT:
455 case StackFrame::OPTIMIZED: 455 case StackFrame::OPTIMIZED:
456 case StackFrame::INTERPRETED: 456 case StackFrame::INTERPRETED:
457 case StackFrame::BUILTIN: { 457 case StackFrame::BUILTIN: {
458 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame); 458 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame);
459 // Set initial size to the maximum inlining level + 1 for the outermost 459 // Set initial size to the maximum inlining level + 1 for the outermost
460 // function. 460 // function.
461 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); 461 List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
462 js_frame->Summarize(&frames); 462 js_frame->Summarize(&frames);
463 for (int i = frames.length() - 1; i >= 0; i--) { 463 for (int i = frames.length() - 1; i >= 0; i--) {
464 Handle<JSFunction> fun = frames[i].function(); 464 const auto& summ = frames[i].AsJavaScript();
465 Handle<JSFunction> fun = summ.function();
465 466
466 // Filter out internal frames that we do not want to show. 467 // Filter out internal frames that we do not want to show.
467 if (!helper.IsVisibleInStackTrace(*fun)) continue; 468 if (!helper.IsVisibleInStackTrace(*fun)) continue;
468 469
469 Handle<Object> recv = frames[i].receiver(); 470 Handle<Object> recv = frames[i].receiver();
470 Handle<AbstractCode> abstract_code = frames[i].abstract_code(); 471 Handle<AbstractCode> abstract_code = summ.abstract_code();
471 const int offset = frames[i].code_offset(); 472 const int offset = frames[i].code_offset();
472 473
473 bool force_constructor = false; 474 bool force_constructor = false;
474 if (frame->type() == StackFrame::BUILTIN) { 475 if (frame->type() == StackFrame::BUILTIN) {
475 // Help CallSite::IsConstructor correctly detect hand-written 476 // Help CallSite::IsConstructor correctly detect hand-written
476 // construct stubs. 477 // construct stubs.
477 if (Code::cast(*abstract_code)->is_construct_stub()) { 478 if (Code::cast(*abstract_code)->is_construct_stub()) {
478 force_constructor = true; 479 force_constructor = true;
479 } 480 }
480 } 481 }
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 eval_key_ = 621 eval_key_ =
621 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("isEval")); 622 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("isEval"));
622 } 623 }
623 if (options & StackTrace::kIsConstructor) { 624 if (options & StackTrace::kIsConstructor) {
624 constructor_key_ = factory()->InternalizeOneByteString( 625 constructor_key_ = factory()->InternalizeOneByteString(
625 STATIC_CHAR_VECTOR("isConstructor")); 626 STATIC_CHAR_VECTOR("isConstructor"));
626 } 627 }
627 } 628 }
628 629
629 Handle<JSObject> NewStackFrameObject(FrameSummary& summ) { 630 Handle<JSObject> NewStackFrameObject(FrameSummary& summ) {
630 int position = summ.abstract_code()->SourcePosition(summ.code_offset()); 631 if (summ.IsJavaScript()) return NewStackFrameObject(summ.AsJavaScript());
631 return NewStackFrameObject(summ.function(), position, 632 if (summ.IsWasm()) return NewStackFrameObject(summ.AsWasm());
632 summ.is_constructor()); 633 UNREACHABLE();
634 return Handle<JSObject>::null();
633 } 635 }
634 636
635 Handle<JSObject> NewStackFrameObject(Handle<JSFunction> fun, int position, 637 Handle<JSObject> NewStackFrameObject(
636 bool is_constructor) { 638 const FrameSummary::JavaScriptFrameSummary& summ) {
637 Handle<JSObject> stack_frame = 639 Handle<JSObject> stack_frame =
638 factory()->NewJSObject(isolate_->object_function()); 640 factory()->NewJSObject(isolate_->object_function());
639 Handle<Script> script(Script::cast(fun->shared()->script()), isolate_); 641 Handle<Script> script = Handle<Script>::cast(summ.script());
640 642
641 if (!line_key_.is_null()) { 643 if (!line_key_.is_null()) {
642 Script::PositionInfo info; 644 Script::PositionInfo info;
643 bool valid_pos = 645 bool valid_pos = Script::GetPositionInfo(script, summ.SourcePosition(),
644 Script::GetPositionInfo(script, position, &info, Script::WITH_OFFSET); 646 &info, Script::WITH_OFFSET);
645 647
646 if (!column_key_.is_null() && valid_pos) { 648 if (!column_key_.is_null() && valid_pos) {
647 JSObject::AddProperty(stack_frame, column_key_, 649 JSObject::AddProperty(stack_frame, column_key_,
648 handle(Smi::FromInt(info.column + 1), isolate_), 650 handle(Smi::FromInt(info.column + 1), isolate_),
649 NONE); 651 NONE);
650 } 652 }
651 JSObject::AddProperty(stack_frame, line_key_, 653 JSObject::AddProperty(stack_frame, line_key_,
652 handle(Smi::FromInt(info.line + 1), isolate_), 654 handle(Smi::FromInt(info.line + 1), isolate_),
653 NONE); 655 NONE);
654 } 656 }
(...skipping 14 matching lines...) Expand all
669 NONE); 671 NONE);
670 } 672 }
671 673
672 if (!eval_key_.is_null()) { 674 if (!eval_key_.is_null()) {
673 Handle<Object> is_eval = factory()->ToBoolean( 675 Handle<Object> is_eval = factory()->ToBoolean(
674 script->compilation_type() == Script::COMPILATION_TYPE_EVAL); 676 script->compilation_type() == Script::COMPILATION_TYPE_EVAL);
675 JSObject::AddProperty(stack_frame, eval_key_, is_eval, NONE); 677 JSObject::AddProperty(stack_frame, eval_key_, is_eval, NONE);
676 } 678 }
677 679
678 if (!function_key_.is_null()) { 680 if (!function_key_.is_null()) {
679 Handle<Object> fun_name = JSFunction::GetDebugName(fun); 681 Handle<String> fun_name = summ.FunctionName();
680 JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE); 682 JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE);
681 } 683 }
682 684
683 if (!constructor_key_.is_null()) { 685 if (!constructor_key_.is_null()) {
684 Handle<Object> is_constructor_obj = factory()->ToBoolean(is_constructor); 686 Handle<Object> is_constructor_obj =
687 factory()->ToBoolean(summ.is_constructor());
685 JSObject::AddProperty(stack_frame, constructor_key_, is_constructor_obj, 688 JSObject::AddProperty(stack_frame, constructor_key_, is_constructor_obj,
686 NONE); 689 NONE);
687 } 690 }
688 return stack_frame; 691 return stack_frame;
689 } 692 }
690 693
691 Handle<JSObject> NewStackFrameObject(BuiltinExitFrame* frame) { 694 Handle<JSObject> NewStackFrameObject(BuiltinExitFrame* frame) {
692 Handle<JSObject> stack_frame = 695 Handle<JSObject> stack_frame =
693 factory()->NewJSObject(isolate_->object_function()); 696 factory()->NewJSObject(isolate_->object_function());
694 Handle<JSFunction> fun = handle(frame->function(), isolate_); 697 Handle<JSFunction> fun = handle(frame->function(), isolate_);
695 if (!function_key_.is_null()) { 698 if (!function_key_.is_null()) {
696 Handle<Object> fun_name = JSFunction::GetDebugName(fun); 699 Handle<Object> fun_name = JSFunction::GetDebugName(fun);
697 JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE); 700 JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE);
698 } 701 }
699 702
700 // We don't have a script and hence cannot set line and col positions. 703 // We don't have a script and hence cannot set line and col positions.
701 DCHECK(!fun->shared()->script()->IsScript()); 704 DCHECK(!fun->shared()->script()->IsScript());
702 705
703 return stack_frame; 706 return stack_frame;
704 } 707 }
705 708
706 Handle<JSObject> NewStackFrameObject(WasmCompiledFrame* frame) { 709 Handle<JSObject> NewStackFrameObject(
710 const FrameSummary::WasmFrameSummary& summ) {
707 Handle<JSObject> stack_frame = 711 Handle<JSObject> stack_frame =
708 factory()->NewJSObject(isolate_->object_function()); 712 factory()->NewJSObject(isolate_->object_function());
709 713
710 if (!function_key_.is_null()) { 714 if (!function_key_.is_null()) {
711 Handle<WasmCompiledModule> compiled_module( 715 Handle<WasmCompiledModule> compiled_module(
712 frame->wasm_instance()->compiled_module(), isolate_); 716 summ.wasm_instance()->compiled_module(), isolate_);
713 Handle<String> name = WasmCompiledModule::GetFunctionName( 717 Handle<String> name = WasmCompiledModule::GetFunctionName(
714 isolate_, compiled_module, frame->function_index()); 718 isolate_, compiled_module, summ.function_index());
715 JSObject::AddProperty(stack_frame, function_key_, name, NONE); 719 JSObject::AddProperty(stack_frame, function_key_, name, NONE);
716 } 720 }
717 // Encode the function index as line number (1-based). 721 // Encode the function index as line number (1-based).
718 if (!line_key_.is_null()) { 722 if (!line_key_.is_null()) {
719 JSObject::AddProperty( 723 JSObject::AddProperty(
720 stack_frame, line_key_, 724 stack_frame, line_key_,
721 isolate_->factory()->NewNumberFromInt(frame->function_index() + 1), 725 isolate_->factory()->NewNumberFromInt(summ.function_index() + 1),
722 NONE); 726 NONE);
723 } 727 }
724 // Encode the byte offset as column (1-based). 728 // Encode the byte offset as column (1-based).
725 if (!column_key_.is_null()) { 729 if (!column_key_.is_null()) {
726 Code* code = frame->LookupCode(); 730 int position = summ.byte_offset();
727 int offset = static_cast<int>(frame->pc() - code->instruction_start());
728 int position = AbstractCode::cast(code)->SourcePosition(offset);
729 // Make position 1-based. 731 // Make position 1-based.
730 if (position >= 0) ++position; 732 if (position >= 0) ++position;
731 JSObject::AddProperty(stack_frame, column_key_, 733 JSObject::AddProperty(stack_frame, column_key_,
732 isolate_->factory()->NewNumberFromInt(position), 734 isolate_->factory()->NewNumberFromInt(position),
733 NONE); 735 NONE);
734 } 736 }
735 if (!script_id_key_.is_null()) { 737 if (!script_id_key_.is_null()) {
736 int script_id = frame->script()->id(); 738 int script_id = summ.script()->id();
737 JSObject::AddProperty(stack_frame, script_id_key_, 739 JSObject::AddProperty(stack_frame, script_id_key_,
738 handle(Smi::FromInt(script_id), isolate_), NONE); 740 handle(Smi::FromInt(script_id), isolate_), NONE);
739 } 741 }
740 742
741 return stack_frame; 743 return stack_frame;
742 } 744 }
743 745
744 private: 746 private:
745 inline Factory* factory() { return isolate_->factory(); } 747 inline Factory* factory() { return isolate_->factory(); }
746 748
(...skipping 16 matching lines...) Expand all
763 // Ensure no negative values. 765 // Ensure no negative values.
764 int limit = Max(frame_limit, 0); 766 int limit = Max(frame_limit, 0);
765 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit); 767 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit);
766 Handle<FixedArray> stack_trace_elems( 768 Handle<FixedArray> stack_trace_elems(
767 FixedArray::cast(stack_trace->elements()), this); 769 FixedArray::cast(stack_trace->elements()), this);
768 770
769 int frames_seen = 0; 771 int frames_seen = 0;
770 for (StackTraceFrameIterator it(this); !it.done() && (frames_seen < limit); 772 for (StackTraceFrameIterator it(this); !it.done() && (frames_seen < limit);
771 it.Advance()) { 773 it.Advance()) {
772 StandardFrame* frame = it.frame(); 774 StandardFrame* frame = it.frame();
773 if (frame->is_java_script()) { 775 // Set initial size to the maximum inlining level + 1 for the outermost
774 // Set initial size to the maximum inlining level + 1 for the outermost 776 // function.
775 // function. 777 List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
776 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); 778 frame->Summarize(&frames);
777 JavaScriptFrame::cast(frame)->Summarize(&frames); 779 for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) {
778 for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) { 780 // Filter frames from other security contexts.
779 Handle<JSFunction> fun = frames[i].function(); 781 if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) &&
780 // Filter frames from other security contexts. 782 !this->context()->HasSameSecurityTokenAs(*frames[i].native_context()))
781 if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) && 783 continue;
782 !this->context()->HasSameSecurityTokenAs(fun->context())) 784 Handle<JSObject> new_frame_obj = helper.NewStackFrameObject(frames[i]);
783 continue;
784 Handle<JSObject> new_frame_obj = helper.NewStackFrameObject(frames[i]);
785 stack_trace_elems->set(frames_seen, *new_frame_obj);
786 frames_seen++;
787 }
788 } else {
789 DCHECK(frame->is_wasm());
790 WasmCompiledFrame* wasm_frame = WasmCompiledFrame::cast(frame);
791 Handle<JSObject> new_frame_obj = helper.NewStackFrameObject(wasm_frame);
792 stack_trace_elems->set(frames_seen, *new_frame_obj); 785 stack_trace_elems->set(frames_seen, *new_frame_obj);
793 frames_seen++; 786 frames_seen++;
794 } 787 }
795 } 788 }
796 789
797 stack_trace->set_length(Smi::FromInt(frames_seen)); 790 stack_trace->set_length(Smi::FromInt(frames_seen));
798 return stack_trace; 791 return stack_trace;
799 } 792 }
800 793
801 794
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
1338 HandlerTable::CatchPrediction PredictException(JavaScriptFrame* frame) { 1331 HandlerTable::CatchPrediction PredictException(JavaScriptFrame* frame) {
1339 HandlerTable::CatchPrediction prediction; 1332 HandlerTable::CatchPrediction prediction;
1340 if (frame->is_optimized()) { 1333 if (frame->is_optimized()) {
1341 if (frame->LookupExceptionHandlerInTable(nullptr, nullptr) > 0) { 1334 if (frame->LookupExceptionHandlerInTable(nullptr, nullptr) > 0) {
1342 // This optimized frame will catch. It's handler table does not include 1335 // This optimized frame will catch. It's handler table does not include
1343 // exception prediction, and we need to use the corresponding handler 1336 // exception prediction, and we need to use the corresponding handler
1344 // tables on the unoptimized code objects. 1337 // tables on the unoptimized code objects.
1345 List<FrameSummary> summaries; 1338 List<FrameSummary> summaries;
1346 frame->Summarize(&summaries); 1339 frame->Summarize(&summaries);
1347 for (const FrameSummary& summary : summaries) { 1340 for (const FrameSummary& summary : summaries) {
1348 Handle<AbstractCode> code = summary.abstract_code(); 1341 Handle<AbstractCode> code = summary.AsJavaScript().abstract_code();
1349 if (code->IsCode() && code->kind() == AbstractCode::BUILTIN) { 1342 if (code->IsCode() && code->kind() == AbstractCode::BUILTIN) {
1350 if (code->GetCode()->is_promise_rejection()) { 1343 if (code->GetCode()->is_promise_rejection()) {
1351 return HandlerTable::PROMISE; 1344 return HandlerTable::PROMISE;
1352 } 1345 }
1353 1346
1354 // This the exception throw in PromiseHandle which doesn't 1347 // This the exception throw in PromiseHandle which doesn't
1355 // cause a promise rejection. 1348 // cause a promise rejection.
1356 if (code->GetCode()->is_exception_caught()) { 1349 if (code->GetCode()->is_exception_caught()) {
1357 return HandlerTable::CAUGHT; 1350 return HandlerTable::CAUGHT;
1358 } 1351 }
1359 } 1352 }
1360 1353
1361 if (code->kind() == AbstractCode::OPTIMIZED_FUNCTION) { 1354 if (code->kind() == AbstractCode::OPTIMIZED_FUNCTION) {
1362 DCHECK(summary.function()->shared()->asm_function()); 1355 DCHECK(summary.AsJavaScript().function()->shared()->asm_function());
1363 // asm code cannot contain try-catch. 1356 // asm code cannot contain try-catch.
1364 continue; 1357 continue;
1365 } 1358 }
1366 // Must have been constructed from a bytecode array. 1359 // Must have been constructed from a bytecode array.
1367 CHECK_EQ(AbstractCode::INTERPRETED_FUNCTION, code->kind()); 1360 CHECK_EQ(AbstractCode::INTERPRETED_FUNCTION, code->kind());
1368 int code_offset = summary.code_offset(); 1361 int code_offset = summary.code_offset();
1369 BytecodeArray* bytecode = code->GetBytecodeArray(); 1362 BytecodeArray* bytecode = code->GetBytecodeArray();
1370 HandlerTable* table = HandlerTable::cast(bytecode->handler_table()); 1363 HandlerTable* table = HandlerTable::cast(bytecode->handler_table());
1371 int index = table->LookupRange(code_offset, nullptr, &prediction); 1364 int index = table->LookupRange(code_offset, nullptr, &prediction);
1372 if (index <= 0) continue; 1365 if (index <= 0) continue;
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1496 line->PrintOn(out); 1489 line->PrintOn(out);
1497 PrintF(out, "\n"); 1490 PrintF(out, "\n");
1498 } 1491 }
1499 } 1492 }
1500 } 1493 }
1501 1494
1502 bool Isolate::ComputeLocation(MessageLocation* target) { 1495 bool Isolate::ComputeLocation(MessageLocation* target) {
1503 StackTraceFrameIterator it(this); 1496 StackTraceFrameIterator it(this);
1504 if (it.done()) return false; 1497 if (it.done()) return false;
1505 StandardFrame* frame = it.frame(); 1498 StandardFrame* frame = it.frame();
1506 // TODO(clemensh): handle wasm frames
1507 if (!frame->is_java_script()) return false;
1508 JSFunction* fun = JavaScriptFrame::cast(frame)->function();
1509 Object* script = fun->shared()->script();
1510 if (!script->IsScript() ||
1511 (Script::cast(script)->source()->IsUndefined(this))) {
1512 return false;
1513 }
1514 Handle<Script> casted_script(Script::cast(script), this);
1515 // Compute the location from the function and the relocation info of the 1499 // Compute the location from the function and the relocation info of the
1516 // baseline code. For optimized code this will use the deoptimization 1500 // baseline code. For optimized code this will use the deoptimization
1517 // information to get canonical location information. 1501 // information to get canonical location information.
1518 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); 1502 List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
1519 JavaScriptFrame::cast(frame)->Summarize(&frames); 1503 frame->Summarize(&frames);
1520 FrameSummary& summary = frames.last(); 1504 FrameSummary& summary = frames.last();
1521 int pos = summary.abstract_code()->SourcePosition(summary.code_offset()); 1505 int pos = summary.SourcePosition();
1522 *target = MessageLocation(casted_script, pos, pos + 1, handle(fun, this)); 1506 Handle<JSFunction> fun;
1507 Handle<Object> script = summary.script();
1508 if (!script->IsScript() ||
1509 (Script::cast(*script)->source()->IsUndefined(this))) {
1510 return false;
1511 }
1512
1513 // TODO(wasm): Remove this once trap-if is always on.
1514 // Background: Without trap-if, the information on the stack trace is
1515 // incomplete (see bug v8:5007).
1516 if (summary.IsWasmCompiled() && !FLAG_wasm_trap_if) return false;
1517
1518 if (summary.IsJavaScript()) fun = summary.AsJavaScript().function();
1519 *target = MessageLocation(Handle<Script>::cast(script), pos, pos + 1, fun);
1523 return true; 1520 return true;
1524 } 1521 }
1525 1522
1526 bool Isolate::ComputeLocationFromException(MessageLocation* target, 1523 bool Isolate::ComputeLocationFromException(MessageLocation* target,
1527 Handle<Object> exception) { 1524 Handle<Object> exception) {
1528 if (!exception->IsJSObject()) return false; 1525 if (!exception->IsJSObject()) return false;
1529 1526
1530 Handle<Name> start_pos_symbol = factory()->error_start_pos_symbol(); 1527 Handle<Name> start_pos_symbol = factory()->error_start_pos_symbol();
1531 Handle<Object> start_pos = JSReceiver::GetDataProperty( 1528 Handle<Object> start_pos = JSReceiver::GetDataProperty(
1532 Handle<JSObject>::cast(exception), start_pos_symbol); 1529 Handle<JSObject>::cast(exception), start_pos_symbol);
(...skipping 2130 matching lines...) Expand 10 before | Expand all | Expand 10 after
3663 // Then check whether this scope intercepts. 3660 // Then check whether this scope intercepts.
3664 if ((flag & intercept_mask_)) { 3661 if ((flag & intercept_mask_)) {
3665 intercepted_flags_ |= flag; 3662 intercepted_flags_ |= flag;
3666 return true; 3663 return true;
3667 } 3664 }
3668 return false; 3665 return false;
3669 } 3666 }
3670 3667
3671 } // namespace internal 3668 } // namespace internal
3672 } // namespace v8 3669 } // namespace v8
OLDNEW
« no previous file with comments | « src/frames-inl.h ('k') | src/list.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698