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