| 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 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 794 | 794 |
| 795 | 795 |
| 796 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) const { | 796 void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) const { |
| 797 DCHECK(functions->length() == 0); | 797 DCHECK(functions->length() == 0); |
| 798 functions->Add(function()); | 798 functions->Add(function()); |
| 799 } | 799 } |
| 800 | 800 |
| 801 | 801 |
| 802 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) { | 802 void JavaScriptFrame::Summarize(List<FrameSummary>* functions) { |
| 803 DCHECK(functions->length() == 0); | 803 DCHECK(functions->length() == 0); |
| 804 Code* code_pointer = LookupCode(); | 804 Code* code = LookupCode(); |
| 805 int offset = static_cast<int>(pc() - code_pointer->address()); | 805 int offset = static_cast<int>(pc() - code->instruction_start()); |
| 806 FrameSummary summary(receiver(), | 806 AbstractCode* abstract_code = AbstractCode::cast(code); |
| 807 function(), | 807 FrameSummary summary(receiver(), function(), abstract_code, offset, |
| 808 code_pointer, | |
| 809 offset, | |
| 810 IsConstructor()); | 808 IsConstructor()); |
| 811 functions->Add(summary); | 809 functions->Add(summary); |
| 812 } | 810 } |
| 813 | 811 |
| 814 | 812 |
| 815 int JavaScriptFrame::LookupExceptionHandlerInTable( | 813 int JavaScriptFrame::LookupExceptionHandlerInTable( |
| 816 int* stack_slots, HandlerTable::CatchPrediction* prediction) { | 814 int* stack_slots, HandlerTable::CatchPrediction* prediction) { |
| 817 Code* code = LookupCode(); | 815 Code* code = LookupCode(); |
| 818 DCHECK(!code->is_optimized_code()); | 816 DCHECK(!code->is_optimized_code()); |
| 819 HandlerTable* table = HandlerTable::cast(code->handler_table()); | 817 HandlerTable* table = HandlerTable::cast(code->handler_table()); |
| 820 int pc_offset = static_cast<int>(pc() - code->entry()); | 818 int pc_offset = static_cast<int>(pc() - code->entry()); |
| 821 return table->LookupRange(pc_offset, stack_slots, prediction); | 819 return table->LookupRange(pc_offset, stack_slots, prediction); |
| 822 } | 820 } |
| 823 | 821 |
| 824 | 822 |
| 825 void JavaScriptFrame::PrintFunctionAndOffset(JSFunction* function, Code* code, | 823 void JavaScriptFrame::PrintFunctionAndOffset(JSFunction* function, Code* code, |
| 826 Address pc, FILE* file, | 824 Address pc, FILE* file, |
| 827 bool print_line_number) { | 825 bool print_line_number) { |
| 828 PrintF(file, "%s", function->IsOptimized() ? "*" : "~"); | 826 PrintF(file, "%s", function->IsOptimized() ? "*" : "~"); |
| 829 function->PrintName(file); | 827 function->PrintName(file); |
| 830 int code_offset = static_cast<int>(pc - code->instruction_start()); | 828 int code_offset = static_cast<int>(pc - code->instruction_start()); |
| 831 PrintF(file, "+%d", code_offset); | 829 PrintF(file, "+%d", code_offset); |
| 832 if (print_line_number) { | 830 if (print_line_number) { |
| 833 SharedFunctionInfo* shared = function->shared(); | 831 SharedFunctionInfo* shared = function->shared(); |
| 834 int source_pos = code->SourcePosition(pc); | 832 int source_pos = code->SourcePosition(code_offset); |
| 835 Object* maybe_script = shared->script(); | 833 Object* maybe_script = shared->script(); |
| 836 if (maybe_script->IsScript()) { | 834 if (maybe_script->IsScript()) { |
| 837 Script* script = Script::cast(maybe_script); | 835 Script* script = Script::cast(maybe_script); |
| 838 int line = script->GetLineNumber(source_pos) + 1; | 836 int line = script->GetLineNumber(source_pos) + 1; |
| 839 Object* script_name_raw = script->name(); | 837 Object* script_name_raw = script->name(); |
| 840 if (script_name_raw->IsString()) { | 838 if (script_name_raw->IsString()) { |
| 841 String* script_name = String::cast(script->name()); | 839 String* script_name = String::cast(script->name()); |
| 842 base::SmartArrayPointer<char> c_script_name = | 840 base::SmartArrayPointer<char> c_script_name = |
| 843 script_name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 841 script_name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 844 PrintF(file, " at %s:%d", c_script_name.get(), line); | 842 PrintF(file, " at %s:%d", c_script_name.get(), line); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 894 | 892 |
| 895 void JavaScriptFrame::RestoreOperandStack(FixedArray* store) { | 893 void JavaScriptFrame::RestoreOperandStack(FixedArray* store) { |
| 896 int operands_count = store->length(); | 894 int operands_count = store->length(); |
| 897 DCHECK_LE(operands_count, ComputeOperandsCount()); | 895 DCHECK_LE(operands_count, ComputeOperandsCount()); |
| 898 for (int i = 0; i < operands_count; i++) { | 896 for (int i = 0; i < operands_count; i++) { |
| 899 DCHECK_EQ(GetOperand(i), isolate()->heap()->the_hole_value()); | 897 DCHECK_EQ(GetOperand(i), isolate()->heap()->the_hole_value()); |
| 900 Memory::Object_at(GetOperandSlot(i)) = store->get(i); | 898 Memory::Object_at(GetOperandSlot(i)) = store->get(i); |
| 901 } | 899 } |
| 902 } | 900 } |
| 903 | 901 |
| 904 | 902 FrameSummary::FrameSummary(Object* receiver, JSFunction* function, |
| 905 FrameSummary::FrameSummary(Object* receiver, JSFunction* function, Code* code, | 903 AbstractCode* abstract_code, int code_offset, |
| 906 int offset, bool is_constructor) | 904 bool is_constructor) |
| 907 : receiver_(receiver, function->GetIsolate()), | 905 : receiver_(receiver, function->GetIsolate()), |
| 908 function_(function), | 906 function_(function), |
| 909 code_(code), | 907 abstract_code_(abstract_code), |
| 910 offset_(offset), | 908 code_offset_(code_offset), |
| 911 is_constructor_(is_constructor) {} | 909 is_constructor_(is_constructor) {} |
| 912 | 910 |
| 913 | |
| 914 void FrameSummary::Print() { | 911 void FrameSummary::Print() { |
| 915 PrintF("receiver: "); | 912 PrintF("receiver: "); |
| 916 receiver_->ShortPrint(); | 913 receiver_->ShortPrint(); |
| 917 PrintF("\nfunction: "); | 914 PrintF("\nfunction: "); |
| 918 function_->shared()->DebugName()->ShortPrint(); | 915 function_->shared()->DebugName()->ShortPrint(); |
| 919 PrintF("\ncode: "); | 916 PrintF("\ncode: "); |
| 920 code_->ShortPrint(); | 917 abstract_code_->ShortPrint(); |
| 921 if (code_->kind() == Code::FUNCTION) PrintF(" NON-OPT"); | 918 if (abstract_code_->IsCode()) { |
| 922 if (code_->kind() == Code::OPTIMIZED_FUNCTION) PrintF(" OPT"); | 919 Code* code = abstract_code_->GetCode(); |
| 923 PrintF("\npc: %d\n", offset_); | 920 if (code->kind() == Code::FUNCTION) PrintF(" UNOPT "); |
| 921 if (code->kind() == Code::OPTIMIZED_FUNCTION) PrintF(" OPT "); |
| 922 } else { |
| 923 PrintF(" BYTECODE "); |
| 924 } |
| 925 PrintF("\npc: %d\n", code_offset_); |
| 924 } | 926 } |
| 925 | 927 |
| 926 | 928 |
| 927 void OptimizedFrame::Summarize(List<FrameSummary>* frames) { | 929 void OptimizedFrame::Summarize(List<FrameSummary>* frames) { |
| 928 DCHECK(frames->length() == 0); | 930 DCHECK(frames->length() == 0); |
| 929 DCHECK(is_optimized()); | 931 DCHECK(is_optimized()); |
| 930 | 932 |
| 931 // Delegate to JS frame in absence of turbofan deoptimization. | 933 // Delegate to JS frame in absence of turbofan deoptimization. |
| 932 // TODO(turbofan): Revisit once we support deoptimization across the board. | 934 // TODO(turbofan): Revisit once we support deoptimization across the board. |
| 933 if (LookupCode()->is_turbofanned() && function()->shared()->asm_function() && | 935 if (LookupCode()->is_turbofanned() && function()->shared()->asm_function() && |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 992 } else { | 994 } else { |
| 993 // The receiver is not in a stack slot nor in a literal. We give up. | 995 // The receiver is not in a stack slot nor in a literal. We give up. |
| 994 it.Skip(Translation::NumberOfOperandsFor(opcode)); | 996 it.Skip(Translation::NumberOfOperandsFor(opcode)); |
| 995 // TODO(3029): Materializing a captured object (or duplicated | 997 // TODO(3029): Materializing a captured object (or duplicated |
| 996 // object) is hard, we return undefined for now. This breaks the | 998 // object) is hard, we return undefined for now. This breaks the |
| 997 // produced stack trace, as constructor frames aren't marked as | 999 // produced stack trace, as constructor frames aren't marked as |
| 998 // such anymore. | 1000 // such anymore. |
| 999 receiver = isolate()->heap()->undefined_value(); | 1001 receiver = isolate()->heap()->undefined_value(); |
| 1000 } | 1002 } |
| 1001 | 1003 |
| 1002 Code* const code = shared_info->code(); | 1004 AbstractCode* abstract_code; |
| 1003 | 1005 |
| 1004 unsigned pc_offset; | 1006 unsigned code_offset; |
| 1005 if (frame_opcode == Translation::JS_FRAME) { | 1007 if (frame_opcode == Translation::JS_FRAME) { |
| 1008 Code* code = shared_info->code(); |
| 1006 DeoptimizationOutputData* const output_data = | 1009 DeoptimizationOutputData* const output_data = |
| 1007 DeoptimizationOutputData::cast(code->deoptimization_data()); | 1010 DeoptimizationOutputData::cast(code->deoptimization_data()); |
| 1008 unsigned const entry = | 1011 unsigned const entry = |
| 1009 Deoptimizer::GetOutputInfo(output_data, ast_id, shared_info); | 1012 Deoptimizer::GetOutputInfo(output_data, ast_id, shared_info); |
| 1010 pc_offset = | 1013 code_offset = FullCodeGenerator::PcField::decode(entry); |
| 1011 FullCodeGenerator::PcField::decode(entry) + Code::kHeaderSize; | 1014 abstract_code = AbstractCode::cast(code); |
| 1012 DCHECK_NE(0U, pc_offset); | |
| 1013 } else { | 1015 } else { |
| 1014 // TODO(rmcilroy): Modify FrameSummary to enable us to summarize | 1016 // TODO(rmcilroy): Modify FrameSummary to enable us to summarize |
| 1015 // based on the BytecodeArray and bytecode offset. | 1017 // based on the BytecodeArray and bytecode offset. |
| 1016 DCHECK_EQ(frame_opcode, Translation::INTERPRETED_FRAME); | 1018 DCHECK_EQ(frame_opcode, Translation::INTERPRETED_FRAME); |
| 1017 pc_offset = 0; | 1019 code_offset = 0; |
| 1020 abstract_code = AbstractCode::cast(shared_info->bytecode_array()); |
| 1018 } | 1021 } |
| 1019 FrameSummary summary(receiver, function, code, pc_offset, is_constructor); | 1022 FrameSummary summary(receiver, function, abstract_code, code_offset, |
| 1023 is_constructor); |
| 1020 frames->Add(summary); | 1024 frames->Add(summary); |
| 1021 is_constructor = false; | 1025 is_constructor = false; |
| 1022 } else if (frame_opcode == Translation::CONSTRUCT_STUB_FRAME) { | 1026 } else if (frame_opcode == Translation::CONSTRUCT_STUB_FRAME) { |
| 1023 // The next encountered JS_FRAME will be marked as a constructor call. | 1027 // The next encountered JS_FRAME will be marked as a constructor call. |
| 1024 it.Skip(Translation::NumberOfOperandsFor(frame_opcode)); | 1028 it.Skip(Translation::NumberOfOperandsFor(frame_opcode)); |
| 1025 DCHECK(!is_constructor); | 1029 DCHECK(!is_constructor); |
| 1026 is_constructor = true; | 1030 is_constructor = true; |
| 1027 } else { | 1031 } else { |
| 1028 // Skip over operands to advance to the next opcode. | 1032 // Skip over operands to advance to the next opcode. |
| 1029 it.Skip(Translation::NumberOfOperandsFor(frame_opcode)); | 1033 it.Skip(Translation::NumberOfOperandsFor(frame_opcode)); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1152 | 1156 |
| 1153 | 1157 |
| 1154 void InterpretedFrame::PatchBytecodeOffset(int new_offset) { | 1158 void InterpretedFrame::PatchBytecodeOffset(int new_offset) { |
| 1155 const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex; | 1159 const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex; |
| 1156 DCHECK_EQ(InterpreterFrameConstants::kBytecodeOffsetFromFp, | 1160 DCHECK_EQ(InterpreterFrameConstants::kBytecodeOffsetFromFp, |
| 1157 StandardFrameConstants::kExpressionsOffset - index * kPointerSize); | 1161 StandardFrameConstants::kExpressionsOffset - index * kPointerSize); |
| 1158 int raw_offset = new_offset + BytecodeArray::kHeaderSize - kHeapObjectTag; | 1162 int raw_offset = new_offset + BytecodeArray::kHeaderSize - kHeapObjectTag; |
| 1159 SetExpression(index, Smi::FromInt(raw_offset)); | 1163 SetExpression(index, Smi::FromInt(raw_offset)); |
| 1160 } | 1164 } |
| 1161 | 1165 |
| 1166 void InterpretedFrame::Summarize(List<FrameSummary>* functions) { |
| 1167 DCHECK(functions->length() == 0); |
| 1168 AbstractCode* abstract_code = |
| 1169 AbstractCode::cast(function()->shared()->bytecode_array()); |
| 1170 FrameSummary summary(receiver(), function(), abstract_code, |
| 1171 GetBytecodeOffset(), IsConstructor()); |
| 1172 functions->Add(summary); |
| 1173 } |
| 1162 | 1174 |
| 1163 int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const { | 1175 int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const { |
| 1164 return Smi::cast(GetExpression(0))->value(); | 1176 return Smi::cast(GetExpression(0))->value(); |
| 1165 } | 1177 } |
| 1166 | 1178 |
| 1167 | 1179 |
| 1168 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const { | 1180 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const { |
| 1169 return fp() + StandardFrameConstants::kCallerSPOffset; | 1181 return fp() + StandardFrameConstants::kCallerSPOffset; |
| 1170 } | 1182 } |
| 1171 | 1183 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1237 ScopeInfo* scope_info = shared->scope_info(); | 1249 ScopeInfo* scope_info = shared->scope_info(); |
| 1238 Object* script_obj = shared->script(); | 1250 Object* script_obj = shared->script(); |
| 1239 if (script_obj->IsScript()) { | 1251 if (script_obj->IsScript()) { |
| 1240 Script* script = Script::cast(script_obj); | 1252 Script* script = Script::cast(script_obj); |
| 1241 accumulator->Add(" ["); | 1253 accumulator->Add(" ["); |
| 1242 accumulator->PrintName(script->name()); | 1254 accumulator->PrintName(script->name()); |
| 1243 | 1255 |
| 1244 Address pc = this->pc(); | 1256 Address pc = this->pc(); |
| 1245 if (code != NULL && code->kind() == Code::FUNCTION && | 1257 if (code != NULL && code->kind() == Code::FUNCTION && |
| 1246 pc >= code->instruction_start() && pc < code->instruction_end()) { | 1258 pc >= code->instruction_start() && pc < code->instruction_end()) { |
| 1247 int source_pos = code->SourcePosition(pc); | 1259 int offset = static_cast<int>(pc - code->instruction_start()); |
| 1260 int source_pos = code->SourcePosition(offset); |
| 1248 int line = script->GetLineNumber(source_pos) + 1; | 1261 int line = script->GetLineNumber(source_pos) + 1; |
| 1249 accumulator->Add(":%d", line); | 1262 accumulator->Add(":%d", line); |
| 1250 } else { | 1263 } else { |
| 1251 int function_start_pos = shared->start_position(); | 1264 int function_start_pos = shared->start_position(); |
| 1252 int line = script->GetLineNumber(function_start_pos) + 1; | 1265 int line = script->GetLineNumber(function_start_pos) + 1; |
| 1253 accumulator->Add(":~%d", line); | 1266 accumulator->Add(":~%d", line); |
| 1254 } | 1267 } |
| 1255 | 1268 |
| 1256 accumulator->Add("] [pc=%p] ", pc); | 1269 accumulator->Add("] [pc=%p] ", pc); |
| 1257 } | 1270 } |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1621 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { | 1634 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { |
| 1622 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); | 1635 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); |
| 1623 list.Add(frame, zone); | 1636 list.Add(frame, zone); |
| 1624 } | 1637 } |
| 1625 return list.ToVector(); | 1638 return list.ToVector(); |
| 1626 } | 1639 } |
| 1627 | 1640 |
| 1628 | 1641 |
| 1629 } // namespace internal | 1642 } // namespace internal |
| 1630 } // namespace v8 | 1643 } // namespace v8 |
| OLD | NEW |