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 919 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
930 return JavaScriptFrame::Summarize(frames); | 930 return JavaScriptFrame::Summarize(frames); |
931 } | 931 } |
932 | 932 |
933 DisallowHeapAllocation no_gc; | 933 DisallowHeapAllocation no_gc; |
934 int deopt_index = Safepoint::kNoDeoptimizationIndex; | 934 int deopt_index = Safepoint::kNoDeoptimizationIndex; |
935 DeoptimizationInputData* const data = GetDeoptimizationData(&deopt_index); | 935 DeoptimizationInputData* const data = GetDeoptimizationData(&deopt_index); |
936 FixedArray* const literal_array = data->LiteralArray(); | 936 FixedArray* const literal_array = data->LiteralArray(); |
937 | 937 |
938 TranslationIterator it(data->TranslationByteArray(), | 938 TranslationIterator it(data->TranslationByteArray(), |
939 data->TranslationIndex(deopt_index)->value()); | 939 data->TranslationIndex(deopt_index)->value()); |
940 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); | 940 Translation::Opcode frame_opcode = |
941 DCHECK_EQ(Translation::BEGIN, opcode); | 941 static_cast<Translation::Opcode>(it.Next()); |
| 942 DCHECK_EQ(Translation::BEGIN, frame_opcode); |
942 it.Next(); // Drop frame count. | 943 it.Next(); // Drop frame count. |
943 int jsframe_count = it.Next(); | 944 int jsframe_count = it.Next(); |
944 | 945 |
945 // We create the summary in reverse order because the frames | 946 // We create the summary in reverse order because the frames |
946 // in the deoptimization translation are ordered bottom-to-top. | 947 // in the deoptimization translation are ordered bottom-to-top. |
947 bool is_constructor = IsConstructor(); | 948 bool is_constructor = IsConstructor(); |
948 while (jsframe_count != 0) { | 949 while (jsframe_count != 0) { |
949 opcode = static_cast<Translation::Opcode>(it.Next()); | 950 frame_opcode = static_cast<Translation::Opcode>(it.Next()); |
950 if (opcode == Translation::JS_FRAME) { | 951 if (frame_opcode == Translation::JS_FRAME || |
| 952 frame_opcode == Translation::INTERPRETED_FRAME) { |
951 jsframe_count--; | 953 jsframe_count--; |
952 BailoutId const ast_id = BailoutId(it.Next()); | 954 BailoutId const ast_id = BailoutId(it.Next()); |
953 SharedFunctionInfo* const shared_info = | 955 SharedFunctionInfo* const shared_info = |
954 SharedFunctionInfo::cast(literal_array->get(it.Next())); | 956 SharedFunctionInfo::cast(literal_array->get(it.Next())); |
955 it.Next(); // Skip height. | 957 it.Next(); // Skip height. |
956 | 958 |
957 // The translation commands are ordered and the function is always | 959 // The translation commands are ordered and the function is always |
958 // at the first position, and the receiver is next. | 960 // at the first position, and the receiver is next. |
959 opcode = static_cast<Translation::Opcode>(it.Next()); | 961 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); |
960 | 962 |
961 // Get the correct function in the optimized frame. | 963 // Get the correct function in the optimized frame. |
962 JSFunction* function; | 964 JSFunction* function; |
963 if (opcode == Translation::LITERAL) { | 965 if (opcode == Translation::LITERAL) { |
964 function = JSFunction::cast(literal_array->get(it.Next())); | 966 function = JSFunction::cast(literal_array->get(it.Next())); |
965 } else if (opcode == Translation::STACK_SLOT) { | 967 } else if (opcode == Translation::STACK_SLOT) { |
966 function = JSFunction::cast(StackSlotAt(it.Next())); | 968 function = JSFunction::cast(StackSlotAt(it.Next())); |
967 } else { | 969 } else { |
968 CHECK_EQ(Translation::JS_FRAME_FUNCTION, opcode); | 970 CHECK_EQ(Translation::JS_FRAME_FUNCTION, opcode); |
969 function = this->function(); | 971 function = this->function(); |
(...skipping 16 matching lines...) Expand all Loading... |
986 // The receiver is not in a stack slot nor in a literal. We give up. | 988 // The receiver is not in a stack slot nor in a literal. We give up. |
987 it.Skip(Translation::NumberOfOperandsFor(opcode)); | 989 it.Skip(Translation::NumberOfOperandsFor(opcode)); |
988 // TODO(3029): Materializing a captured object (or duplicated | 990 // TODO(3029): Materializing a captured object (or duplicated |
989 // object) is hard, we return undefined for now. This breaks the | 991 // object) is hard, we return undefined for now. This breaks the |
990 // produced stack trace, as constructor frames aren't marked as | 992 // produced stack trace, as constructor frames aren't marked as |
991 // such anymore. | 993 // such anymore. |
992 receiver = isolate()->heap()->undefined_value(); | 994 receiver = isolate()->heap()->undefined_value(); |
993 } | 995 } |
994 | 996 |
995 Code* const code = shared_info->code(); | 997 Code* const code = shared_info->code(); |
996 DeoptimizationOutputData* const output_data = | |
997 DeoptimizationOutputData::cast(code->deoptimization_data()); | |
998 unsigned const entry = | |
999 Deoptimizer::GetOutputInfo(output_data, ast_id, shared_info); | |
1000 unsigned const pc_offset = | |
1001 FullCodeGenerator::PcField::decode(entry) + Code::kHeaderSize; | |
1002 DCHECK_NE(0U, pc_offset); | |
1003 | 998 |
| 999 unsigned pc_offset; |
| 1000 if (frame_opcode == Translation::JS_FRAME) { |
| 1001 DeoptimizationOutputData* const output_data = |
| 1002 DeoptimizationOutputData::cast(code->deoptimization_data()); |
| 1003 unsigned const entry = |
| 1004 Deoptimizer::GetOutputInfo(output_data, ast_id, shared_info); |
| 1005 pc_offset = |
| 1006 FullCodeGenerator::PcField::decode(entry) + Code::kHeaderSize; |
| 1007 DCHECK_NE(0U, pc_offset); |
| 1008 } else { |
| 1009 // TODO(rmcilroy): Modify FrameSummary to enable us to summarize |
| 1010 // based on the BytecodeArray and bytecode offset. |
| 1011 DCHECK_EQ(frame_opcode, Translation::INTERPRETED_FRAME); |
| 1012 pc_offset = 0; |
| 1013 } |
1004 FrameSummary summary(receiver, function, code, pc_offset, is_constructor); | 1014 FrameSummary summary(receiver, function, code, pc_offset, is_constructor); |
1005 frames->Add(summary); | 1015 frames->Add(summary); |
1006 is_constructor = false; | 1016 is_constructor = false; |
1007 } else if (opcode == Translation::CONSTRUCT_STUB_FRAME) { | 1017 } else if (frame_opcode == Translation::CONSTRUCT_STUB_FRAME) { |
1008 // The next encountered JS_FRAME will be marked as a constructor call. | 1018 // The next encountered JS_FRAME will be marked as a constructor call. |
1009 it.Skip(Translation::NumberOfOperandsFor(opcode)); | 1019 it.Skip(Translation::NumberOfOperandsFor(frame_opcode)); |
1010 DCHECK(!is_constructor); | 1020 DCHECK(!is_constructor); |
1011 is_constructor = true; | 1021 is_constructor = true; |
1012 } else { | 1022 } else { |
1013 // Skip over operands to advance to the next opcode. | 1023 // Skip over operands to advance to the next opcode. |
1014 it.Skip(Translation::NumberOfOperandsFor(opcode)); | 1024 it.Skip(Translation::NumberOfOperandsFor(frame_opcode)); |
1015 } | 1025 } |
1016 } | 1026 } |
1017 DCHECK(!is_constructor); | 1027 DCHECK(!is_constructor); |
1018 } | 1028 } |
1019 | 1029 |
1020 | 1030 |
1021 int OptimizedFrame::LookupExceptionHandlerInTable( | 1031 int OptimizedFrame::LookupExceptionHandlerInTable( |
1022 int* stack_slots, HandlerTable::CatchPrediction* prediction) { | 1032 int* stack_slots, HandlerTable::CatchPrediction* prediction) { |
1023 Code* code = LookupCode(); | 1033 Code* code = LookupCode(); |
1024 DCHECK(code->is_optimized_code()); | 1034 DCHECK(code->is_optimized_code()); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1076 DCHECK_EQ(Translation::BEGIN, opcode); | 1086 DCHECK_EQ(Translation::BEGIN, opcode); |
1077 it.Next(); // Skip frame count. | 1087 it.Next(); // Skip frame count. |
1078 int jsframe_count = it.Next(); | 1088 int jsframe_count = it.Next(); |
1079 | 1089 |
1080 // We insert the frames in reverse order because the frames | 1090 // We insert the frames in reverse order because the frames |
1081 // in the deoptimization translation are ordered bottom-to-top. | 1091 // in the deoptimization translation are ordered bottom-to-top. |
1082 while (jsframe_count != 0) { | 1092 while (jsframe_count != 0) { |
1083 opcode = static_cast<Translation::Opcode>(it.Next()); | 1093 opcode = static_cast<Translation::Opcode>(it.Next()); |
1084 // Skip over operands to advance to the next opcode. | 1094 // Skip over operands to advance to the next opcode. |
1085 it.Skip(Translation::NumberOfOperandsFor(opcode)); | 1095 it.Skip(Translation::NumberOfOperandsFor(opcode)); |
1086 if (opcode == Translation::JS_FRAME) { | 1096 if (opcode == Translation::JS_FRAME || |
| 1097 opcode == Translation::INTERPRETED_FRAME) { |
1087 jsframe_count--; | 1098 jsframe_count--; |
1088 | 1099 |
1089 // The translation commands are ordered and the function is always at the | 1100 // The translation commands are ordered and the function is always at the |
1090 // first position. | 1101 // first position. |
1091 opcode = static_cast<Translation::Opcode>(it.Next()); | 1102 opcode = static_cast<Translation::Opcode>(it.Next()); |
1092 | 1103 |
1093 // Get the correct function in the optimized frame. | 1104 // Get the correct function in the optimized frame. |
1094 Object* function; | 1105 Object* function; |
1095 if (opcode == Translation::LITERAL) { | 1106 if (opcode == Translation::LITERAL) { |
1096 function = literal_array->get(it.Next()); | 1107 function = literal_array->get(it.Next()); |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1579 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { | 1590 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { |
1580 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); | 1591 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); |
1581 list.Add(frame, zone); | 1592 list.Add(frame, zone); |
1582 } | 1593 } |
1583 return list.ToVector(); | 1594 return list.ToVector(); |
1584 } | 1595 } |
1585 | 1596 |
1586 | 1597 |
1587 } // namespace internal | 1598 } // namespace internal |
1588 } // namespace v8 | 1599 } // namespace v8 |
OLD | NEW |