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 <memory> | 7 #include <memory> |
8 #include <sstream> | 8 #include <sstream> |
9 | 9 |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 } | 978 } |
979 | 979 |
980 int JavaScriptFrame::LookupExceptionHandlerInTable( | 980 int JavaScriptFrame::LookupExceptionHandlerInTable( |
981 int* stack_depth, HandlerTable::CatchPrediction* prediction) { | 981 int* stack_depth, HandlerTable::CatchPrediction* prediction) { |
982 Code* code = LookupCode(); | 982 Code* code = LookupCode(); |
983 DCHECK(!code->is_optimized_code()); | 983 DCHECK(!code->is_optimized_code()); |
984 int pc_offset = static_cast<int>(pc() - code->entry()); | 984 int pc_offset = static_cast<int>(pc() - code->entry()); |
985 return code->LookupRangeInHandlerTable(pc_offset, stack_depth, prediction); | 985 return code->LookupRangeInHandlerTable(pc_offset, stack_depth, prediction); |
986 } | 986 } |
987 | 987 |
988 void JavaScriptFrame::PrintFunctionAndOffset(JSFunction* function, Code* code, | 988 void JavaScriptFrame::PrintFunctionAndOffset(JSFunction* function, |
989 Address pc, FILE* file, | 989 AbstractCode* code, |
| 990 int code_offset, FILE* file, |
990 bool print_line_number) { | 991 bool print_line_number) { |
991 PrintF(file, "%s", function->IsOptimized() ? "*" : "~"); | 992 PrintF(file, "%s", function->IsOptimized() ? "*" : "~"); |
992 function->PrintName(file); | 993 function->PrintName(file); |
993 int code_offset = static_cast<int>(pc - code->instruction_start()); | |
994 PrintF(file, "+%d", code_offset); | 994 PrintF(file, "+%d", code_offset); |
995 if (print_line_number) { | 995 if (print_line_number) { |
996 SharedFunctionInfo* shared = function->shared(); | 996 SharedFunctionInfo* shared = function->shared(); |
997 int source_pos = AbstractCode::cast(code)->SourcePosition(code_offset); | 997 int source_pos = code->SourcePosition(code_offset); |
998 Object* maybe_script = shared->script(); | 998 Object* maybe_script = shared->script(); |
999 if (maybe_script->IsScript()) { | 999 if (maybe_script->IsScript()) { |
1000 Script* script = Script::cast(maybe_script); | 1000 Script* script = Script::cast(maybe_script); |
1001 int line = script->GetLineNumber(source_pos) + 1; | 1001 int line = script->GetLineNumber(source_pos) + 1; |
1002 Object* script_name_raw = script->name(); | 1002 Object* script_name_raw = script->name(); |
1003 if (script_name_raw->IsString()) { | 1003 if (script_name_raw->IsString()) { |
1004 String* script_name = String::cast(script->name()); | 1004 String* script_name = String::cast(script->name()); |
1005 std::unique_ptr<char[]> c_script_name = | 1005 std::unique_ptr<char[]> c_script_name = |
1006 script_name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 1006 script_name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
1007 PrintF(file, " at %s:%d", c_script_name.get(), line); | 1007 PrintF(file, " at %s:%d", c_script_name.get(), line); |
1008 } else { | 1008 } else { |
1009 PrintF(file, " at <unknown>:%d", line); | 1009 PrintF(file, " at <unknown>:%d", line); |
1010 } | 1010 } |
1011 } else { | 1011 } else { |
1012 PrintF(file, " at <unknown>:<unknown>"); | 1012 PrintF(file, " at <unknown>:<unknown>"); |
1013 } | 1013 } |
1014 } | 1014 } |
1015 } | 1015 } |
1016 | 1016 |
1017 | 1017 |
1018 void JavaScriptFrame::PrintTop(Isolate* isolate, FILE* file, bool print_args, | 1018 void JavaScriptFrame::PrintTop(Isolate* isolate, FILE* file, bool print_args, |
1019 bool print_line_number) { | 1019 bool print_line_number) { |
1020 // constructor calls | 1020 // constructor calls |
1021 DisallowHeapAllocation no_allocation; | 1021 DisallowHeapAllocation no_allocation; |
1022 JavaScriptFrameIterator it(isolate); | 1022 JavaScriptFrameIterator it(isolate); |
1023 while (!it.done()) { | 1023 while (!it.done()) { |
1024 if (it.frame()->is_java_script()) { | 1024 if (it.frame()->is_java_script()) { |
1025 JavaScriptFrame* frame = it.frame(); | 1025 JavaScriptFrame* frame = it.frame(); |
1026 if (frame->IsConstructor()) PrintF(file, "new "); | 1026 if (frame->IsConstructor()) PrintF(file, "new "); |
1027 PrintFunctionAndOffset(frame->function(), frame->unchecked_code(), | 1027 JSFunction* function = frame->function(); |
1028 frame->pc(), file, print_line_number); | 1028 int code_offset = 0; |
| 1029 if (frame->is_interpreted()) { |
| 1030 InterpretedFrame* iframe = reinterpret_cast<InterpretedFrame*>(frame); |
| 1031 code_offset = iframe->GetBytecodeOffset(); |
| 1032 } else { |
| 1033 Code* code = frame->unchecked_code(); |
| 1034 code_offset = static_cast<int>(frame->pc() - code->instruction_start()); |
| 1035 } |
| 1036 PrintFunctionAndOffset(function, function->abstract_code(), code_offset, |
| 1037 file, print_line_number); |
1029 if (print_args) { | 1038 if (print_args) { |
1030 // function arguments | 1039 // function arguments |
1031 // (we are intentionally only printing the actually | 1040 // (we are intentionally only printing the actually |
1032 // supplied parameters, not all parameters required) | 1041 // supplied parameters, not all parameters required) |
1033 PrintF(file, "(this="); | 1042 PrintF(file, "(this="); |
1034 frame->receiver()->ShortPrint(file); | 1043 frame->receiver()->ShortPrint(file); |
1035 const int length = frame->ComputeParametersCount(); | 1044 const int length = frame->ComputeParametersCount(); |
1036 for (int i = 0; i < length; i++) { | 1045 for (int i = 0; i < length; i++) { |
1037 PrintF(file, ", "); | 1046 PrintF(file, ", "); |
1038 frame->GetParameter(i)->ShortPrint(file); | 1047 frame->GetParameter(i)->ShortPrint(file); |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1344 | 1353 |
1345 int InterpretedFrame::GetBytecodeOffset() const { | 1354 int InterpretedFrame::GetBytecodeOffset() const { |
1346 const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex; | 1355 const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex; |
1347 DCHECK_EQ( | 1356 DCHECK_EQ( |
1348 InterpreterFrameConstants::kBytecodeOffsetFromFp, | 1357 InterpreterFrameConstants::kBytecodeOffsetFromFp, |
1349 InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize); | 1358 InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize); |
1350 int raw_offset = Smi::cast(GetExpression(index))->value(); | 1359 int raw_offset = Smi::cast(GetExpression(index))->value(); |
1351 return raw_offset - BytecodeArray::kHeaderSize + kHeapObjectTag; | 1360 return raw_offset - BytecodeArray::kHeaderSize + kHeapObjectTag; |
1352 } | 1361 } |
1353 | 1362 |
| 1363 int InterpretedFrame::GetBytecodeOffset(Address fp) { |
| 1364 const int offset = InterpreterFrameConstants::kExpressionsOffset; |
| 1365 const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex; |
| 1366 DCHECK_EQ( |
| 1367 InterpreterFrameConstants::kBytecodeOffsetFromFp, |
| 1368 InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize); |
| 1369 Address expression_offset = fp + offset - index * kPointerSize; |
| 1370 int raw_offset = Smi::cast(Memory::Object_at(expression_offset))->value(); |
| 1371 return raw_offset - BytecodeArray::kHeaderSize + kHeapObjectTag; |
| 1372 } |
| 1373 |
1354 void InterpretedFrame::PatchBytecodeOffset(int new_offset) { | 1374 void InterpretedFrame::PatchBytecodeOffset(int new_offset) { |
1355 const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex; | 1375 const int index = InterpreterFrameConstants::kBytecodeOffsetExpressionIndex; |
1356 DCHECK_EQ( | 1376 DCHECK_EQ( |
1357 InterpreterFrameConstants::kBytecodeOffsetFromFp, | 1377 InterpreterFrameConstants::kBytecodeOffsetFromFp, |
1358 InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize); | 1378 InterpreterFrameConstants::kExpressionsOffset - index * kPointerSize); |
1359 int raw_offset = new_offset + BytecodeArray::kHeaderSize - kHeapObjectTag; | 1379 int raw_offset = new_offset + BytecodeArray::kHeaderSize - kHeapObjectTag; |
1360 SetExpression(index, Smi::FromInt(raw_offset)); | 1380 SetExpression(index, Smi::FromInt(raw_offset)); |
1361 } | 1381 } |
1362 | 1382 |
1363 BytecodeArray* InterpretedFrame::GetBytecodeArray() const { | 1383 BytecodeArray* InterpretedFrame::GetBytecodeArray() const { |
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1918 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { | 1938 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { |
1919 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); | 1939 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); |
1920 list.Add(frame, zone); | 1940 list.Add(frame, zone); |
1921 } | 1941 } |
1922 return list.ToVector(); | 1942 return list.ToVector(); |
1923 } | 1943 } |
1924 | 1944 |
1925 | 1945 |
1926 } // namespace internal | 1946 } // namespace internal |
1927 } // namespace v8 | 1947 } // namespace v8 |
OLD | NEW |