OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/deoptimizer.h" | 5 #include "src/deoptimizer.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/ast/prettyprinter.h" | 8 #include "src/ast/prettyprinter.h" |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/disasm.h" | 10 #include "src/disasm.h" |
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
756 | 756 |
757 // Translate each output frame. | 757 // Translate each output frame. |
758 for (size_t i = 0; i < count; ++i) { | 758 for (size_t i = 0; i < count; ++i) { |
759 // Read the ast node id, function, and frame height for this output frame. | 759 // Read the ast node id, function, and frame height for this output frame. |
760 int frame_index = static_cast<int>(i); | 760 int frame_index = static_cast<int>(i); |
761 switch (translated_state_.frames()[i].kind()) { | 761 switch (translated_state_.frames()[i].kind()) { |
762 case TranslatedFrame::kFunction: | 762 case TranslatedFrame::kFunction: |
763 DoComputeJSFrame(frame_index); | 763 DoComputeJSFrame(frame_index); |
764 jsframe_count_++; | 764 jsframe_count_++; |
765 break; | 765 break; |
| 766 case TranslatedFrame::kInterpretedFunction: |
| 767 DoComputeInterpretedFrame(frame_index); |
| 768 jsframe_count_++; |
| 769 break; |
766 case TranslatedFrame::kArgumentsAdaptor: | 770 case TranslatedFrame::kArgumentsAdaptor: |
767 DoComputeArgumentsAdaptorFrame(frame_index); | 771 DoComputeArgumentsAdaptorFrame(frame_index); |
768 break; | 772 break; |
769 case TranslatedFrame::kConstructStub: | 773 case TranslatedFrame::kConstructStub: |
770 DoComputeConstructStubFrame(frame_index); | 774 DoComputeConstructStubFrame(frame_index); |
771 break; | 775 break; |
772 case TranslatedFrame::kGetter: | 776 case TranslatedFrame::kGetter: |
773 DoComputeAccessorStubFrame(frame_index, false); | 777 DoComputeAccessorStubFrame(frame_index, false); |
774 break; | 778 break; |
775 case TranslatedFrame::kSetter: | 779 case TranslatedFrame::kSetter: |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 input_index++; | 825 input_index++; |
822 if (trace_scope_ != NULL) { | 826 if (trace_scope_ != NULL) { |
823 PrintF(trace_scope_->file(), " translating frame "); | 827 PrintF(trace_scope_->file(), " translating frame "); |
824 function->PrintName(trace_scope_->file()); | 828 function->PrintName(trace_scope_->file()); |
825 PrintF(trace_scope_->file(), | 829 PrintF(trace_scope_->file(), |
826 " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes); | 830 " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes); |
827 } | 831 } |
828 | 832 |
829 // The 'fixed' part of the frame consists of the incoming parameters and | 833 // The 'fixed' part of the frame consists of the incoming parameters and |
830 // the part described by JavaScriptFrameConstants. | 834 // the part described by JavaScriptFrameConstants. |
831 unsigned fixed_frame_size = ComputeFixedSize(function); | 835 unsigned fixed_frame_size = ComputeJavascriptFixedSize(function); |
832 unsigned input_frame_size = input_->GetFrameSize(); | 836 unsigned input_frame_size = input_->GetFrameSize(); |
833 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 837 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
834 | 838 |
835 // Allocate and store the output frame description. | 839 // Allocate and store the output frame description. |
836 FrameDescription* output_frame = | 840 FrameDescription* output_frame = |
837 new(output_frame_size) FrameDescription(output_frame_size, function); | 841 new(output_frame_size) FrameDescription(output_frame_size, function); |
838 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); | 842 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); |
839 | 843 |
840 bool is_bottommost = (0 == frame_index); | 844 bool is_bottommost = (0 == frame_index); |
841 bool is_topmost = (output_count_ - 1 == frame_index); | 845 bool is_topmost = (output_count_ - 1 == frame_index); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1015 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized); | 1019 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized); |
1016 } else { | 1020 } else { |
1017 CHECK_EQ(bailout_type_, EAGER); | 1021 CHECK_EQ(bailout_type_, EAGER); |
1018 } | 1022 } |
1019 output_frame->SetContinuation( | 1023 output_frame->SetContinuation( |
1020 reinterpret_cast<intptr_t>(continuation->entry())); | 1024 reinterpret_cast<intptr_t>(continuation->entry())); |
1021 } | 1025 } |
1022 } | 1026 } |
1023 | 1027 |
1024 | 1028 |
| 1029 void Deoptimizer::DoComputeInterpretedFrame(int frame_index) { |
| 1030 TranslatedFrame* translated_frame = |
| 1031 &(translated_state_.frames()[frame_index]); |
| 1032 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
| 1033 int input_index = 0; |
| 1034 |
| 1035 BailoutId bytecode_offset = translated_frame->node_id(); |
| 1036 unsigned height = translated_frame->height(); |
| 1037 unsigned height_in_bytes = height * kPointerSize; |
| 1038 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); |
| 1039 value_iterator++; |
| 1040 input_index++; |
| 1041 if (trace_scope_ != NULL) { |
| 1042 PrintF(trace_scope_->file(), " translating interpreted frame "); |
| 1043 function->PrintName(trace_scope_->file()); |
| 1044 PrintF(trace_scope_->file(), " => bytecode_offset=%d, height=%d\n", |
| 1045 bytecode_offset.ToInt(), height_in_bytes); |
| 1046 } |
| 1047 |
| 1048 // The 'fixed' part of the frame consists of the incoming parameters and |
| 1049 // the part described by InterpreterFrameConstants. |
| 1050 unsigned fixed_frame_size = ComputeInterpretedFixedSize(function); |
| 1051 unsigned input_frame_size = input_->GetFrameSize(); |
| 1052 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
| 1053 |
| 1054 // Allocate and store the output frame description. |
| 1055 FrameDescription* output_frame = |
| 1056 new (output_frame_size) FrameDescription(output_frame_size, function); |
| 1057 output_frame->SetFrameType(StackFrame::INTERPRETED); |
| 1058 |
| 1059 bool is_bottommost = (0 == frame_index); |
| 1060 bool is_topmost = (output_count_ - 1 == frame_index); |
| 1061 CHECK(frame_index >= 0 && frame_index < output_count_); |
| 1062 CHECK_NULL(output_[frame_index]); |
| 1063 output_[frame_index] = output_frame; |
| 1064 |
| 1065 // The top address for the bottommost output frame can be computed from |
| 1066 // the input frame pointer and the output frame's height. For all |
| 1067 // subsequent output frames, it can be computed from the previous one's |
| 1068 // top address and the current frame's size. |
| 1069 Register fp_reg = InterpretedFrame::fp_register(); |
| 1070 intptr_t top_address; |
| 1071 if (is_bottommost) { |
| 1072 // Subtract interpreter fixed frame size for the context function slots, |
| 1073 // new,target and bytecode offset. |
| 1074 top_address = input_->GetRegister(fp_reg.code()) - |
| 1075 InterpreterFrameConstants::kFixedFrameSizeFromFp - |
| 1076 height_in_bytes; |
| 1077 } else { |
| 1078 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
| 1079 } |
| 1080 output_frame->SetTop(top_address); |
| 1081 |
| 1082 // Compute the incoming parameter translation. |
| 1083 int parameter_count = |
| 1084 function->shared()->internal_formal_parameter_count() + 1; |
| 1085 unsigned output_offset = output_frame_size; |
| 1086 unsigned input_offset = input_frame_size; |
| 1087 for (int i = 0; i < parameter_count; ++i) { |
| 1088 output_offset -= kPointerSize; |
| 1089 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
| 1090 output_offset); |
| 1091 } |
| 1092 input_offset -= (parameter_count * kPointerSize); |
| 1093 |
| 1094 // There are no translation commands for the caller's pc and fp, the |
| 1095 // context, the function, new.target and the bytecode offset. Synthesize |
| 1096 // their values and set them up |
| 1097 // explicitly. |
| 1098 // |
| 1099 // The caller's pc for the bottommost output frame is the same as in the |
| 1100 // input frame. For all subsequent output frames, it can be read from the |
| 1101 // previous one. This frame's pc can be computed from the non-optimized |
| 1102 // function code and AST id of the bailout. |
| 1103 output_offset -= kPCOnStackSize; |
| 1104 input_offset -= kPCOnStackSize; |
| 1105 intptr_t value; |
| 1106 if (is_bottommost) { |
| 1107 value = input_->GetFrameSlot(input_offset); |
| 1108 } else { |
| 1109 value = output_[frame_index - 1]->GetPc(); |
| 1110 } |
| 1111 output_frame->SetCallerPc(output_offset, value); |
| 1112 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's pc\n"); |
| 1113 |
| 1114 // The caller's frame pointer for the bottommost output frame is the same |
| 1115 // as in the input frame. For all subsequent output frames, it can be |
| 1116 // read from the previous one. Also compute and set this frame's frame |
| 1117 // pointer. |
| 1118 output_offset -= kFPOnStackSize; |
| 1119 input_offset -= kFPOnStackSize; |
| 1120 if (is_bottommost) { |
| 1121 value = input_->GetFrameSlot(input_offset); |
| 1122 } else { |
| 1123 value = output_[frame_index - 1]->GetFp(); |
| 1124 } |
| 1125 output_frame->SetCallerFp(output_offset, value); |
| 1126 intptr_t fp_value = top_address + output_offset; |
| 1127 DCHECK(!is_bottommost || |
| 1128 (input_->GetRegister(fp_reg.code()) + |
| 1129 has_alignment_padding_ * kPointerSize) == fp_value); |
| 1130 output_frame->SetFp(fp_value); |
| 1131 if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value); |
| 1132 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n"); |
| 1133 DCHECK(!is_bottommost || !has_alignment_padding_ || |
| 1134 (fp_value & kPointerSize) != 0); |
| 1135 |
| 1136 if (FLAG_enable_embedded_constant_pool) { |
| 1137 // For the bottommost output frame the constant pool pointer can be gotten |
| 1138 // from the input frame. For subsequent output frames, it can be read from |
| 1139 // the previous frame. |
| 1140 output_offset -= kPointerSize; |
| 1141 input_offset -= kPointerSize; |
| 1142 if (is_bottommost) { |
| 1143 value = input_->GetFrameSlot(input_offset); |
| 1144 } else { |
| 1145 value = output_[frame_index - 1]->GetConstantPool(); |
| 1146 } |
| 1147 output_frame->SetCallerConstantPool(output_offset, value); |
| 1148 DebugPrintOutputSlot(value, frame_index, output_offset, |
| 1149 "caller's constant_pool\n"); |
| 1150 } |
| 1151 |
| 1152 // For the bottommost output frame the context can be gotten from the input |
| 1153 // frame. For all subsequent output frames it can be gotten from the function |
| 1154 // so long as we don't inline functions that need local contexts. |
| 1155 Register context_reg = InterpretedFrame::context_register(); |
| 1156 output_offset -= kPointerSize; |
| 1157 input_offset -= kPointerSize; |
| 1158 // Read the context from the translations. |
| 1159 Object* context = value_iterator->GetRawValue(); |
| 1160 // The context should not be a placeholder for a materialized object. |
| 1161 CHECK(context != isolate_->heap()->arguments_marker()); |
| 1162 value = reinterpret_cast<intptr_t>(context); |
| 1163 output_frame->SetContext(value); |
| 1164 if (is_topmost) output_frame->SetRegister(context_reg.code(), value); |
| 1165 WriteValueToOutput(context, input_index, frame_index, output_offset, |
| 1166 "context "); |
| 1167 value_iterator++; |
| 1168 input_index++; |
| 1169 |
| 1170 // The function was mentioned explicitly in the BEGIN_FRAME. |
| 1171 output_offset -= kPointerSize; |
| 1172 input_offset -= kPointerSize; |
| 1173 value = reinterpret_cast<intptr_t>(function); |
| 1174 // The function for the bottommost output frame should also agree with the |
| 1175 // input frame. |
| 1176 DCHECK(!is_bottommost || input_->GetFrameSlot(input_offset) == value); |
| 1177 WriteValueToOutput(function, 0, frame_index, output_offset, "function "); |
| 1178 |
| 1179 // TODO(rmcilroy): Deal with new.target correctly - currently just set it to |
| 1180 // undefined. |
| 1181 output_offset -= kPointerSize; |
| 1182 input_offset -= kPointerSize; |
| 1183 Object* new_target = isolate_->heap()->undefined_value(); |
| 1184 WriteValueToOutput(new_target, 0, frame_index, output_offset, "new_target "); |
| 1185 |
| 1186 // The bytecode offset was mentioned explicitly in the BEGIN_FRAME. |
| 1187 output_offset -= kPointerSize; |
| 1188 input_offset -= kPointerSize; |
| 1189 int raw_bytecode_offset = |
| 1190 BytecodeArray::kHeaderSize - kHeapObjectTag + bytecode_offset.ToInt(); |
| 1191 Smi* smi_bytecode_offset = Smi::FromInt(raw_bytecode_offset); |
| 1192 WriteValueToOutput(smi_bytecode_offset, 0, frame_index, output_offset, |
| 1193 "bytecode offset "); |
| 1194 |
| 1195 // Translate the rest of the interpreter registers in the frame. |
| 1196 for (unsigned i = 0; i < height; ++i) { |
| 1197 output_offset -= kPointerSize; |
| 1198 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
| 1199 output_offset); |
| 1200 } |
| 1201 CHECK_EQ(0u, output_offset); |
| 1202 |
| 1203 // Set the accumulator register. |
| 1204 output_frame->SetRegister( |
| 1205 kInterpreterAccumulatorRegister.code(), |
| 1206 reinterpret_cast<intptr_t>(value_iterator->GetRawValue())); |
| 1207 value_iterator++; |
| 1208 |
| 1209 Builtins* builtins = isolate_->builtins(); |
| 1210 Code* trampoline = builtins->builtin(Builtins::kInterpreterEntryTrampoline); |
| 1211 output_frame->SetPc(reinterpret_cast<intptr_t>(trampoline->entry())); |
| 1212 output_frame->SetState(0); |
| 1213 |
| 1214 // Update constant pool. |
| 1215 if (FLAG_enable_embedded_constant_pool) { |
| 1216 intptr_t constant_pool_value = |
| 1217 reinterpret_cast<intptr_t>(trampoline->constant_pool()); |
| 1218 output_frame->SetConstantPool(constant_pool_value); |
| 1219 if (is_topmost) { |
| 1220 Register constant_pool_reg = |
| 1221 InterpretedFrame::constant_pool_pointer_register(); |
| 1222 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value); |
| 1223 } |
| 1224 } |
| 1225 |
| 1226 // Set the continuation for the topmost frame. |
| 1227 if (is_topmost && bailout_type_ != DEBUGGER) { |
| 1228 Code* continuation = |
| 1229 builtins->builtin(Builtins::kInterpreterNotifyDeoptimized); |
| 1230 if (bailout_type_ == LAZY) { |
| 1231 continuation = |
| 1232 builtins->builtin(Builtins::kInterpreterNotifyLazyDeoptimized); |
| 1233 } else if (bailout_type_ == SOFT) { |
| 1234 continuation = |
| 1235 builtins->builtin(Builtins::kInterpreterNotifySoftDeoptimized); |
| 1236 } else { |
| 1237 CHECK_EQ(bailout_type_, EAGER); |
| 1238 } |
| 1239 output_frame->SetContinuation( |
| 1240 reinterpret_cast<intptr_t>(continuation->entry())); |
| 1241 } |
| 1242 } |
| 1243 |
| 1244 |
1025 void Deoptimizer::DoComputeArgumentsAdaptorFrame(int frame_index) { | 1245 void Deoptimizer::DoComputeArgumentsAdaptorFrame(int frame_index) { |
1026 TranslatedFrame* translated_frame = | 1246 TranslatedFrame* translated_frame = |
1027 &(translated_state_.frames()[frame_index]); | 1247 &(translated_state_.frames()[frame_index]); |
1028 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 1248 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
1029 int input_index = 0; | 1249 int input_index = 0; |
1030 | 1250 |
1031 unsigned height = translated_frame->height(); | 1251 unsigned height = translated_frame->height(); |
1032 unsigned height_in_bytes = height * kPointerSize; | 1252 unsigned height_in_bytes = height * kPointerSize; |
1033 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); | 1253 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); |
1034 value_iterator++; | 1254 value_iterator++; |
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1749 output_offset; | 1969 output_offset; |
1750 PrintF(trace_scope_->file(), | 1970 PrintF(trace_scope_->file(), |
1751 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s", | 1971 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s", |
1752 reinterpret_cast<intptr_t>(output_address), output_offset, value, | 1972 reinterpret_cast<intptr_t>(output_address), output_offset, value, |
1753 debug_hint_string == nullptr ? "" : debug_hint_string); | 1973 debug_hint_string == nullptr ? "" : debug_hint_string); |
1754 } | 1974 } |
1755 } | 1975 } |
1756 | 1976 |
1757 | 1977 |
1758 unsigned Deoptimizer::ComputeInputFrameSize() const { | 1978 unsigned Deoptimizer::ComputeInputFrameSize() const { |
1759 unsigned fixed_size = ComputeFixedSize(function_); | 1979 unsigned fixed_size = ComputeJavascriptFixedSize(function_); |
1760 // The fp-to-sp delta already takes the context, constant pool pointer and the | 1980 // The fp-to-sp delta already takes the context, constant pool pointer and the |
1761 // function into account so we have to avoid double counting them. | 1981 // function into account so we have to avoid double counting them. |
1762 unsigned result = fixed_size + fp_to_sp_delta_ - | 1982 unsigned result = fixed_size + fp_to_sp_delta_ - |
1763 StandardFrameConstants::kFixedFrameSizeFromFp; | 1983 StandardFrameConstants::kFixedFrameSizeFromFp; |
1764 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { | 1984 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { |
1765 unsigned stack_slots = compiled_code_->stack_slots(); | 1985 unsigned stack_slots = compiled_code_->stack_slots(); |
1766 unsigned outgoing_size = | 1986 unsigned outgoing_size = |
1767 ComputeOutgoingArgumentSize(compiled_code_, bailout_id_); | 1987 ComputeOutgoingArgumentSize(compiled_code_, bailout_id_); |
1768 CHECK(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size); | 1988 CHECK(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size); |
1769 } | 1989 } |
1770 return result; | 1990 return result; |
1771 } | 1991 } |
1772 | 1992 |
1773 | 1993 |
1774 unsigned Deoptimizer::ComputeFixedSize(JSFunction* function) const { | 1994 unsigned Deoptimizer::ComputeJavascriptFixedSize(JSFunction* function) const { |
1775 // The fixed part of the frame consists of the return address, frame | 1995 // The fixed part of the frame consists of the return address, frame |
1776 // pointer, function, context, and all the incoming arguments. | 1996 // pointer, function, context, and all the incoming arguments. |
1777 return ComputeIncomingArgumentSize(function) + | 1997 return ComputeIncomingArgumentSize(function) + |
1778 StandardFrameConstants::kFixedFrameSize; | 1998 StandardFrameConstants::kFixedFrameSize; |
1779 } | 1999 } |
1780 | 2000 |
1781 | 2001 |
| 2002 unsigned Deoptimizer::ComputeInterpretedFixedSize(JSFunction* function) const { |
| 2003 // The fixed part of the frame consists of the return address, frame |
| 2004 // pointer, function, context, new.target, bytecode offset and all the |
| 2005 // incoming arguments. |
| 2006 return ComputeIncomingArgumentSize(function) + |
| 2007 InterpreterFrameConstants::kFixedFrameSize; |
| 2008 } |
| 2009 |
| 2010 |
1782 unsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const { | 2011 unsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const { |
1783 // The incoming arguments is the values for formal parameters and | 2012 // The incoming arguments is the values for formal parameters and |
1784 // the receiver. Every slot contains a pointer. | 2013 // the receiver. Every slot contains a pointer. |
1785 if (function->IsSmi()) { | 2014 if (function->IsSmi()) { |
1786 CHECK_EQ(Smi::cast(function), Smi::FromInt(StackFrame::STUB)); | 2015 CHECK_EQ(Smi::cast(function), Smi::FromInt(StackFrame::STUB)); |
1787 return 0; | 2016 return 0; |
1788 } | 2017 } |
1789 unsigned arguments = | 2018 unsigned arguments = |
1790 function->shared()->internal_formal_parameter_count() + 1; | 2019 function->shared()->internal_formal_parameter_count() + 1; |
1791 return arguments * kPointerSize; | 2020 return arguments * kPointerSize; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1865 } | 2094 } |
1866 | 2095 |
1867 // Zap all the slots. | 2096 // Zap all the slots. |
1868 for (unsigned o = 0; o < frame_size; o += kPointerSize) { | 2097 for (unsigned o = 0; o < frame_size; o += kPointerSize) { |
1869 SetFrameSlot(o, kZapUint32); | 2098 SetFrameSlot(o, kZapUint32); |
1870 } | 2099 } |
1871 } | 2100 } |
1872 | 2101 |
1873 | 2102 |
1874 int FrameDescription::ComputeFixedSize() { | 2103 int FrameDescription::ComputeFixedSize() { |
1875 return StandardFrameConstants::kFixedFrameSize + | 2104 if (type_ == StackFrame::INTERPRETED) { |
1876 (ComputeParametersCount() + 1) * kPointerSize; | 2105 return InterpreterFrameConstants::kFixedFrameSize + |
| 2106 (ComputeParametersCount() + 1) * kPointerSize; |
| 2107 } else { |
| 2108 return StandardFrameConstants::kFixedFrameSize + |
| 2109 (ComputeParametersCount() + 1) * kPointerSize; |
| 2110 } |
1877 } | 2111 } |
1878 | 2112 |
1879 | 2113 |
1880 unsigned FrameDescription::GetOffsetFromSlotIndex(int slot_index) { | 2114 unsigned FrameDescription::GetOffsetFromSlotIndex(int slot_index) { |
1881 if (slot_index >= 0) { | 2115 if (slot_index >= 0) { |
1882 // Local or spill slots. Skip the fixed part of the frame | 2116 // Local or spill slots. Skip the fixed part of the frame |
1883 // including all arguments. | 2117 // including all arguments. |
1884 unsigned base = GetFrameSize() - ComputeFixedSize(); | 2118 unsigned base = GetFrameSize() - ComputeFixedSize(); |
1885 return base - ((slot_index + 1) * kPointerSize); | 2119 return base - ((slot_index + 1) * kPointerSize); |
1886 } else { | 2120 } else { |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2004 void Translation::BeginJSFrame(BailoutId node_id, | 2238 void Translation::BeginJSFrame(BailoutId node_id, |
2005 int literal_id, | 2239 int literal_id, |
2006 unsigned height) { | 2240 unsigned height) { |
2007 buffer_->Add(JS_FRAME, zone()); | 2241 buffer_->Add(JS_FRAME, zone()); |
2008 buffer_->Add(node_id.ToInt(), zone()); | 2242 buffer_->Add(node_id.ToInt(), zone()); |
2009 buffer_->Add(literal_id, zone()); | 2243 buffer_->Add(literal_id, zone()); |
2010 buffer_->Add(height, zone()); | 2244 buffer_->Add(height, zone()); |
2011 } | 2245 } |
2012 | 2246 |
2013 | 2247 |
| 2248 void Translation::BeginInterpretedFrame(BailoutId bytecode_offset, |
| 2249 int literal_id, unsigned height) { |
| 2250 buffer_->Add(INTERPRETED_FRAME, zone()); |
| 2251 buffer_->Add(bytecode_offset.ToInt(), zone()); |
| 2252 buffer_->Add(literal_id, zone()); |
| 2253 buffer_->Add(height, zone()); |
| 2254 } |
| 2255 |
| 2256 |
2014 void Translation::BeginCompiledStubFrame(int height) { | 2257 void Translation::BeginCompiledStubFrame(int height) { |
2015 buffer_->Add(COMPILED_STUB_FRAME, zone()); | 2258 buffer_->Add(COMPILED_STUB_FRAME, zone()); |
2016 buffer_->Add(height, zone()); | 2259 buffer_->Add(height, zone()); |
2017 } | 2260 } |
2018 | 2261 |
2019 | 2262 |
2020 void Translation::BeginArgumentsObject(int args_length) { | 2263 void Translation::BeginArgumentsObject(int args_length) { |
2021 buffer_->Add(ARGUMENTS_OBJECT, zone()); | 2264 buffer_->Add(ARGUMENTS_OBJECT, zone()); |
2022 buffer_->Add(args_length, zone()); | 2265 buffer_->Add(args_length, zone()); |
2023 } | 2266 } |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2136 case BOOL_STACK_SLOT: | 2379 case BOOL_STACK_SLOT: |
2137 case DOUBLE_STACK_SLOT: | 2380 case DOUBLE_STACK_SLOT: |
2138 case LITERAL: | 2381 case LITERAL: |
2139 case COMPILED_STUB_FRAME: | 2382 case COMPILED_STUB_FRAME: |
2140 return 1; | 2383 return 1; |
2141 case BEGIN: | 2384 case BEGIN: |
2142 case ARGUMENTS_ADAPTOR_FRAME: | 2385 case ARGUMENTS_ADAPTOR_FRAME: |
2143 case CONSTRUCT_STUB_FRAME: | 2386 case CONSTRUCT_STUB_FRAME: |
2144 return 2; | 2387 return 2; |
2145 case JS_FRAME: | 2388 case JS_FRAME: |
| 2389 case INTERPRETED_FRAME: |
2146 return 3; | 2390 return 3; |
2147 } | 2391 } |
2148 FATAL("Unexpected translation type"); | 2392 FATAL("Unexpected translation type"); |
2149 return -1; | 2393 return -1; |
2150 } | 2394 } |
2151 | 2395 |
2152 | 2396 |
2153 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) | 2397 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) |
2154 | 2398 |
2155 const char* Translation::StringFor(Opcode opcode) { | 2399 const char* Translation::StringFor(Opcode opcode) { |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2609 TranslatedFrame TranslatedFrame::JSFrame(BailoutId node_id, | 2853 TranslatedFrame TranslatedFrame::JSFrame(BailoutId node_id, |
2610 SharedFunctionInfo* shared_info, | 2854 SharedFunctionInfo* shared_info, |
2611 int height) { | 2855 int height) { |
2612 TranslatedFrame frame(kFunction, shared_info->GetIsolate(), shared_info, | 2856 TranslatedFrame frame(kFunction, shared_info->GetIsolate(), shared_info, |
2613 height); | 2857 height); |
2614 frame.node_id_ = node_id; | 2858 frame.node_id_ = node_id; |
2615 return frame; | 2859 return frame; |
2616 } | 2860 } |
2617 | 2861 |
2618 | 2862 |
| 2863 TranslatedFrame TranslatedFrame::InterpretedFrame( |
| 2864 BailoutId bytecode_offset, SharedFunctionInfo* shared_info, int height) { |
| 2865 TranslatedFrame frame(kInterpretedFunction, shared_info->GetIsolate(), |
| 2866 shared_info, height); |
| 2867 frame.node_id_ = bytecode_offset; |
| 2868 return frame; |
| 2869 } |
| 2870 |
| 2871 |
2619 TranslatedFrame TranslatedFrame::AccessorFrame( | 2872 TranslatedFrame TranslatedFrame::AccessorFrame( |
2620 Kind kind, SharedFunctionInfo* shared_info) { | 2873 Kind kind, SharedFunctionInfo* shared_info) { |
2621 DCHECK(kind == kSetter || kind == kGetter); | 2874 DCHECK(kind == kSetter || kind == kGetter); |
2622 return TranslatedFrame(kind, shared_info->GetIsolate(), shared_info); | 2875 return TranslatedFrame(kind, shared_info->GetIsolate(), shared_info); |
2623 } | 2876 } |
2624 | 2877 |
2625 | 2878 |
2626 TranslatedFrame TranslatedFrame::ArgumentsAdaptorFrame( | 2879 TranslatedFrame TranslatedFrame::ArgumentsAdaptorFrame( |
2627 SharedFunctionInfo* shared_info, int height) { | 2880 SharedFunctionInfo* shared_info, int height) { |
2628 return TranslatedFrame(kArgumentsAdaptor, shared_info->GetIsolate(), | 2881 return TranslatedFrame(kArgumentsAdaptor, shared_info->GetIsolate(), |
2629 shared_info, height); | 2882 shared_info, height); |
2630 } | 2883 } |
2631 | 2884 |
2632 | 2885 |
2633 TranslatedFrame TranslatedFrame::ConstructStubFrame( | 2886 TranslatedFrame TranslatedFrame::ConstructStubFrame( |
2634 SharedFunctionInfo* shared_info, int height) { | 2887 SharedFunctionInfo* shared_info, int height) { |
2635 return TranslatedFrame(kConstructStub, shared_info->GetIsolate(), shared_info, | 2888 return TranslatedFrame(kConstructStub, shared_info->GetIsolate(), shared_info, |
2636 height); | 2889 height); |
2637 } | 2890 } |
2638 | 2891 |
2639 | 2892 |
2640 int TranslatedFrame::GetValueCount() { | 2893 int TranslatedFrame::GetValueCount() { |
2641 switch (kind()) { | 2894 switch (kind()) { |
2642 case kFunction: { | 2895 case kFunction: { |
2643 int parameter_count = | 2896 int parameter_count = |
2644 raw_shared_info_->internal_formal_parameter_count() + 1; | 2897 raw_shared_info_->internal_formal_parameter_count() + 1; |
| 2898 // + 1 for function. |
2645 return height_ + parameter_count + 1; | 2899 return height_ + parameter_count + 1; |
2646 } | 2900 } |
2647 | 2901 |
| 2902 case kInterpretedFunction: { |
| 2903 int parameter_count = |
| 2904 raw_shared_info_->internal_formal_parameter_count() + 1; |
| 2905 // + 3 for function, context and accumulator. |
| 2906 return height_ + parameter_count + 3; |
| 2907 } |
| 2908 |
2648 case kGetter: | 2909 case kGetter: |
2649 return 2; // Function and receiver. | 2910 return 2; // Function and receiver. |
2650 | 2911 |
2651 case kSetter: | 2912 case kSetter: |
2652 return 3; // Function, receiver and the value to set. | 2913 return 3; // Function, receiver and the value to set. |
2653 | 2914 |
2654 case kArgumentsAdaptor: | 2915 case kArgumentsAdaptor: |
2655 case kConstructStub: | 2916 case kConstructStub: |
2656 return 1 + height_; | 2917 return 1 + height_; |
2657 | 2918 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2693 base::SmartArrayPointer<char> name = | 2954 base::SmartArrayPointer<char> name = |
2694 shared_info->DebugName()->ToCString(); | 2955 shared_info->DebugName()->ToCString(); |
2695 PrintF(trace_file, " reading input frame %s", name.get()); | 2956 PrintF(trace_file, " reading input frame %s", name.get()); |
2696 int arg_count = shared_info->internal_formal_parameter_count() + 1; | 2957 int arg_count = shared_info->internal_formal_parameter_count() + 1; |
2697 PrintF(trace_file, " => node=%d, args=%d, height=%d; inputs:\n", | 2958 PrintF(trace_file, " => node=%d, args=%d, height=%d; inputs:\n", |
2698 node_id.ToInt(), arg_count, height); | 2959 node_id.ToInt(), arg_count, height); |
2699 } | 2960 } |
2700 return TranslatedFrame::JSFrame(node_id, shared_info, height); | 2961 return TranslatedFrame::JSFrame(node_id, shared_info, height); |
2701 } | 2962 } |
2702 | 2963 |
| 2964 case Translation::INTERPRETED_FRAME: { |
| 2965 BailoutId bytecode_offset = BailoutId(iterator->Next()); |
| 2966 SharedFunctionInfo* shared_info = |
| 2967 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
| 2968 int height = iterator->Next(); |
| 2969 if (trace_file != nullptr) { |
| 2970 base::SmartArrayPointer<char> name = |
| 2971 shared_info->DebugName()->ToCString(); |
| 2972 PrintF(trace_file, " reading input frame %s", name.get()); |
| 2973 int arg_count = shared_info->internal_formal_parameter_count() + 1; |
| 2974 PrintF(trace_file, |
| 2975 " => bytecode_offset=%d, args=%d, height=%d; inputs:\n", |
| 2976 bytecode_offset.ToInt(), arg_count, height); |
| 2977 } |
| 2978 return TranslatedFrame::InterpretedFrame(bytecode_offset, shared_info, |
| 2979 height); |
| 2980 } |
| 2981 |
2703 case Translation::ARGUMENTS_ADAPTOR_FRAME: { | 2982 case Translation::ARGUMENTS_ADAPTOR_FRAME: { |
2704 SharedFunctionInfo* shared_info = | 2983 SharedFunctionInfo* shared_info = |
2705 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); | 2984 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
2706 int height = iterator->Next(); | 2985 int height = iterator->Next(); |
2707 if (trace_file != nullptr) { | 2986 if (trace_file != nullptr) { |
2708 base::SmartArrayPointer<char> name = | 2987 base::SmartArrayPointer<char> name = |
2709 shared_info->DebugName()->ToCString(); | 2988 shared_info->DebugName()->ToCString(); |
2710 PrintF(trace_file, " reading arguments adaptor frame %s", name.get()); | 2989 PrintF(trace_file, " reading arguments adaptor frame %s", name.get()); |
2711 PrintF(trace_file, " => height=%d; inputs:\n", height); | 2990 PrintF(trace_file, " => height=%d; inputs:\n", height); |
2712 } | 2991 } |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2805 int frame_index, int value_index, TranslationIterator* iterator, | 3084 int frame_index, int value_index, TranslationIterator* iterator, |
2806 FixedArray* literal_array, Address fp, RegisterValues* registers, | 3085 FixedArray* literal_array, Address fp, RegisterValues* registers, |
2807 FILE* trace_file) { | 3086 FILE* trace_file) { |
2808 disasm::NameConverter converter; | 3087 disasm::NameConverter converter; |
2809 | 3088 |
2810 Translation::Opcode opcode = | 3089 Translation::Opcode opcode = |
2811 static_cast<Translation::Opcode>(iterator->Next()); | 3090 static_cast<Translation::Opcode>(iterator->Next()); |
2812 switch (opcode) { | 3091 switch (opcode) { |
2813 case Translation::BEGIN: | 3092 case Translation::BEGIN: |
2814 case Translation::JS_FRAME: | 3093 case Translation::JS_FRAME: |
| 3094 case Translation::INTERPRETED_FRAME: |
2815 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 3095 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
2816 case Translation::CONSTRUCT_STUB_FRAME: | 3096 case Translation::CONSTRUCT_STUB_FRAME: |
2817 case Translation::GETTER_STUB_FRAME: | 3097 case Translation::GETTER_STUB_FRAME: |
2818 case Translation::SETTER_STUB_FRAME: | 3098 case Translation::SETTER_STUB_FRAME: |
2819 case Translation::COMPILED_STUB_FRAME: | 3099 case Translation::COMPILED_STUB_FRAME: |
2820 // Peeled off before getting here. | 3100 // Peeled off before getting here. |
2821 break; | 3101 break; |
2822 | 3102 |
2823 case Translation::DUPLICATED_OBJECT: { | 3103 case Translation::DUPLICATED_OBJECT: { |
2824 int object_id = iterator->Next(); | 3104 int object_id = iterator->Next(); |
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3389 DCHECK(value_info->IsMaterializedObject()); | 3669 DCHECK(value_info->IsMaterializedObject()); |
3390 | 3670 |
3391 value_info->value_ = | 3671 value_info->value_ = |
3392 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 3672 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
3393 } | 3673 } |
3394 } | 3674 } |
3395 } | 3675 } |
3396 | 3676 |
3397 } // namespace internal | 3677 } // namespace internal |
3398 } // namespace v8 | 3678 } // namespace v8 |
OLD | NEW |