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/frames.h" | 5 #include "src/frames.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/ast/ast.h" | 9 #include "src/ast/ast.h" |
10 #include "src/ast/scopeinfo.h" | 10 #include "src/ast/scopeinfo.h" |
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
790 | 790 |
791 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) const { | 791 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) const { |
792 DCHECK(functions->length() == 0); | 792 DCHECK(functions->length() == 0); |
793 functions->Add(function()); | 793 functions->Add(function()); |
794 } | 794 } |
795 | 795 |
796 | 796 |
797 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) { | 797 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) { |
798 DCHECK(functions->length() == 0); | 798 DCHECK(functions->length() == 0); |
799 Code* code_pointer = LookupCode(); | 799 Code* code_pointer = LookupCode(); |
800 int offset = static_cast<int>(pc() - code_pointer->address()); | 800 int offset = static_cast<int>(pc() - code_pointer->instruction_start()); |
801 FrameSummary summary(receiver(), | 801 FrameSummary summary(receiver(), |
802 function(), | 802 function(), |
803 code_pointer, | 803 code_pointer, |
804 offset, | 804 offset, |
805 IsConstructor()); | 805 IsConstructor()); |
806 functions->Add(summary); | 806 functions->Add(summary); |
807 } | 807 } |
808 | 808 |
809 | 809 |
810 int JavaScriptFrame::LookupExceptionHandlerInTable( | 810 int JavaScriptFrame::LookupExceptionHandlerInTable( |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
890 void JavaScriptFrame::RestoreOperandStack(FixedArray* store) { | 890 void JavaScriptFrame::RestoreOperandStack(FixedArray* store) { |
891 int operands_count = store->length(); | 891 int operands_count = store->length(); |
892 DCHECK_LE(operands_count, ComputeOperandsCount()); | 892 DCHECK_LE(operands_count, ComputeOperandsCount()); |
893 for (int i = 0; i < operands_count; i++) { | 893 for (int i = 0; i < operands_count; i++) { |
894 DCHECK_EQ(GetOperand(i), isolate()->heap()->the_hole_value()); | 894 DCHECK_EQ(GetOperand(i), isolate()->heap()->the_hole_value()); |
895 Memory::Object_at(GetOperandSlot(i)) = store->get(i); | 895 Memory::Object_at(GetOperandSlot(i)) = store->get(i); |
896 } | 896 } |
897 } | 897 } |
898 | 898 |
899 | 899 |
900 FrameSummary::FrameSummary(Object* receiver, JSFunction* function, Code* code, | 900 FrameSummary::FrameSummary(Object* receiver, JSFunction* function, |
901 int offset, bool is_constructor) | 901 HeapObject* abstract_code, int code_offset, |
rmcilroy
2016/01/22 19:16:34
Is there a reason this can't be AbstractCode type.
Yang
2016/01/28 09:09:53
It can be. But then the caller would have to do th
| |
902 bool is_constructor) | |
902 : receiver_(receiver, function->GetIsolate()), | 903 : receiver_(receiver, function->GetIsolate()), |
903 function_(function), | 904 function_(function), |
904 code_(code), | 905 abstract_code_(AbstractCode::cast(abstract_code)), |
905 offset_(offset), | 906 code_offset_(code_offset), |
906 is_constructor_(is_constructor) {} | 907 is_constructor_(is_constructor) {} |
907 | 908 |
908 | 909 |
909 void FrameSummary::Print() { | 910 void FrameSummary::Print() { |
910 PrintF("receiver: "); | 911 PrintF("receiver: "); |
911 receiver_->ShortPrint(); | 912 receiver_->ShortPrint(); |
912 PrintF("\nfunction: "); | 913 PrintF("\nfunction: "); |
913 function_->shared()->DebugName()->ShortPrint(); | 914 function_->shared()->DebugName()->ShortPrint(); |
914 PrintF("\ncode: "); | 915 PrintF("\ncode: "); |
915 code_->ShortPrint(); | 916 abstract_code_->ShortPrint(); |
916 if (code_->kind() == Code::FUNCTION) PrintF(" NON-OPT"); | 917 if (abstract_code_->IsCode()) { |
917 if (code_->kind() == Code::OPTIMIZED_FUNCTION) PrintF(" OPT"); | 918 Code* code = abstract_code_->GetCode(); |
918 PrintF("\npc: %d\n", offset_); | 919 if (code->kind() == Code::FUNCTION) PrintF(" UNOPT "); |
920 if (code->kind() == Code::OPTIMIZED_FUNCTION) PrintF(" OPT "); | |
921 } else { | |
922 PrintF(" BYTECODE "); | |
923 } | |
924 PrintF("\npc: %d\n", code_offset_); | |
919 } | 925 } |
920 | 926 |
921 | 927 |
922 void OptimizedFrame::Summarize(List<FrameSummary>* frames) { | 928 void OptimizedFrame::Summarize(List<FrameSummary>* frames) { |
923 DCHECK(frames->length() == 0); | 929 DCHECK(frames->length() == 0); |
924 DCHECK(is_optimized()); | 930 DCHECK(is_optimized()); |
925 | 931 |
926 // Delegate to JS frame in absence of turbofan deoptimization. | 932 // Delegate to JS frame in absence of turbofan deoptimization. |
927 // TODO(turbofan): Revisit once we support deoptimization across the board. | 933 // TODO(turbofan): Revisit once we support deoptimization across the board. |
928 if (LookupCode()->is_turbofanned() && function()->shared()->asm_function() && | 934 if (LookupCode()->is_turbofanned() && function()->shared()->asm_function() && |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
987 } else { | 993 } else { |
988 // The receiver is not in a stack slot nor in a literal. We give up. | 994 // The receiver is not in a stack slot nor in a literal. We give up. |
989 it.Skip(Translation::NumberOfOperandsFor(opcode)); | 995 it.Skip(Translation::NumberOfOperandsFor(opcode)); |
990 // TODO(3029): Materializing a captured object (or duplicated | 996 // TODO(3029): Materializing a captured object (or duplicated |
991 // object) is hard, we return undefined for now. This breaks the | 997 // object) is hard, we return undefined for now. This breaks the |
992 // produced stack trace, as constructor frames aren't marked as | 998 // produced stack trace, as constructor frames aren't marked as |
993 // such anymore. | 999 // such anymore. |
994 receiver = isolate()->heap()->undefined_value(); | 1000 receiver = isolate()->heap()->undefined_value(); |
995 } | 1001 } |
996 | 1002 |
997 Code* const code = shared_info->code(); | 1003 AbstractCode* abstract_code = shared_info->AbstractCode(); |
998 | 1004 |
999 unsigned pc_offset; | 1005 int code_offset; |
rmcilroy
2016/01/22 19:16:34
Could this still be unsigned? It should never be n
Yang
2016/01/28 09:09:53
Done.
| |
1000 if (frame_opcode == Translation::JS_FRAME) { | 1006 if (frame_opcode == Translation::JS_FRAME) { |
1007 Code* code = abstract_code->GetCode(); | |
1001 DeoptimizationOutputData* const output_data = | 1008 DeoptimizationOutputData* const output_data = |
1002 DeoptimizationOutputData::cast(code->deoptimization_data()); | 1009 DeoptimizationOutputData::cast(code->deoptimization_data()); |
1003 unsigned const entry = | 1010 unsigned const entry = |
1004 Deoptimizer::GetOutputInfo(output_data, ast_id, shared_info); | 1011 Deoptimizer::GetOutputInfo(output_data, ast_id, shared_info); |
1005 pc_offset = | 1012 code_offset = FullCodeGenerator::PcField::decode(entry); |
1006 FullCodeGenerator::PcField::decode(entry) + Code::kHeaderSize; | 1013 DCHECK_LE(0, code_offset); |
1007 DCHECK_NE(0U, pc_offset); | |
1008 } else { | 1014 } else { |
1009 // TODO(rmcilroy): Modify FrameSummary to enable us to summarize | 1015 // TODO(rmcilroy): Modify FrameSummary to enable us to summarize |
1010 // based on the BytecodeArray and bytecode offset. | 1016 // based on the BytecodeArray and bytecode offset. |
1011 DCHECK_EQ(frame_opcode, Translation::INTERPRETED_FRAME); | 1017 DCHECK_EQ(frame_opcode, Translation::INTERPRETED_FRAME); |
1012 pc_offset = 0; | 1018 code_offset = 0; |
rmcilroy
2016/01/22 19:16:34
Could this use GetBytecodeOffset now?
Yang
2016/01/28 09:09:53
No. The frame object is still an OptimizedFrame. T
| |
1013 } | 1019 } |
1014 FrameSummary summary(receiver, function, code, pc_offset, is_constructor); | 1020 FrameSummary summary(receiver, function, abstract_code, code_offset, |
1021 is_constructor); | |
1015 frames->Add(summary); | 1022 frames->Add(summary); |
1016 is_constructor = false; | 1023 is_constructor = false; |
1017 } else if (frame_opcode == Translation::CONSTRUCT_STUB_FRAME) { | 1024 } else if (frame_opcode == Translation::CONSTRUCT_STUB_FRAME) { |
1018 // The next encountered JS_FRAME will be marked as a constructor call. | 1025 // The next encountered JS_FRAME will be marked as a constructor call. |
1019 it.Skip(Translation::NumberOfOperandsFor(frame_opcode)); | 1026 it.Skip(Translation::NumberOfOperandsFor(frame_opcode)); |
1020 DCHECK(!is_constructor); | 1027 DCHECK(!is_constructor); |
1021 is_constructor = true; | 1028 is_constructor = true; |
1022 } else { | 1029 } else { |
1023 // Skip over operands to advance to the next opcode. | 1030 // Skip over operands to advance to the next opcode. |
1024 it.Skip(Translation::NumberOfOperandsFor(frame_opcode)); | 1031 it.Skip(Translation::NumberOfOperandsFor(frame_opcode)); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1148 | 1155 |
1149 void InterpretedFrame::PatchBytecodeOffset(int new_offset) { | 1156 void InterpretedFrame::PatchBytecodeOffset(int new_offset) { |
1150 const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex; | 1157 const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex; |
1151 DCHECK_EQ(InterpreterFrameConstants::kBytecodeOffsetFromFp, | 1158 DCHECK_EQ(InterpreterFrameConstants::kBytecodeOffsetFromFp, |
1152 StandardFrameConstants::kExpressionsOffset - index * kPointerSize); | 1159 StandardFrameConstants::kExpressionsOffset - index * kPointerSize); |
1153 int raw_offset = new_offset + BytecodeArray::kHeaderSize - kHeapObjectTag; | 1160 int raw_offset = new_offset + BytecodeArray::kHeaderSize - kHeapObjectTag; |
1154 SetExpression(index, Smi::FromInt(raw_offset)); | 1161 SetExpression(index, Smi::FromInt(raw_offset)); |
1155 } | 1162 } |
1156 | 1163 |
1157 | 1164 |
1165 void InterpretedFrame::Summarize(List<FrameSummary>* functions) { | |
1166 DCHECK(functions->length() == 0); | |
1167 DCHECK_EQ( | |
1168 isolate()->builtins()->builtin(Builtins::kInterpreterEntryTrampoline), | |
1169 LookupCode()); | |
1170 FrameSummary summary(receiver(), function(), | |
1171 function()->shared()->bytecode_array(), | |
1172 GetBytecodeOffset(), IsConstructor()); | |
1173 functions->Add(summary); | |
1174 } | |
1175 | |
1176 | |
1158 int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const { | 1177 int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const { |
1159 return Smi::cast(GetExpression(0))->value(); | 1178 return Smi::cast(GetExpression(0))->value(); |
1160 } | 1179 } |
1161 | 1180 |
1162 | 1181 |
1163 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const { | 1182 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const { |
1164 return fp() + StandardFrameConstants::kCallerSPOffset; | 1183 return fp() + StandardFrameConstants::kCallerSPOffset; |
1165 } | 1184 } |
1166 | 1185 |
1167 | 1186 |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1616 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { | 1635 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { |
1617 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); | 1636 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); |
1618 list.Add(frame, zone); | 1637 list.Add(frame, zone); |
1619 } | 1638 } |
1620 return list.ToVector(); | 1639 return list.ToVector(); |
1621 } | 1640 } |
1622 | 1641 |
1623 | 1642 |
1624 } // namespace internal | 1643 } // namespace internal |
1625 } // namespace v8 | 1644 } // namespace v8 |
OLD | NEW |