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 = |
836 ComputeFixedSize(function, StackFrame::JAVA_SCRIPT); | |
832 unsigned input_frame_size = input_->GetFrameSize(); | 837 unsigned input_frame_size = input_->GetFrameSize(); |
833 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 838 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
834 | 839 |
835 // Allocate and store the output frame description. | 840 // Allocate and store the output frame description. |
836 FrameDescription* output_frame = | 841 FrameDescription* output_frame = |
837 new(output_frame_size) FrameDescription(output_frame_size, function); | 842 new(output_frame_size) FrameDescription(output_frame_size, function); |
838 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); | 843 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); |
839 | 844 |
840 bool is_bottommost = (0 == frame_index); | 845 bool is_bottommost = (0 == frame_index); |
841 bool is_topmost = (output_count_ - 1 == frame_index); | 846 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); | 1020 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized); |
1016 } else { | 1021 } else { |
1017 CHECK_EQ(bailout_type_, EAGER); | 1022 CHECK_EQ(bailout_type_, EAGER); |
1018 } | 1023 } |
1019 output_frame->SetContinuation( | 1024 output_frame->SetContinuation( |
1020 reinterpret_cast<intptr_t>(continuation->entry())); | 1025 reinterpret_cast<intptr_t>(continuation->entry())); |
1021 } | 1026 } |
1022 } | 1027 } |
1023 | 1028 |
1024 | 1029 |
1030 void Deoptimizer::DoComputeInterpretedFrame(int frame_index) { | |
1031 TranslatedFrame* translated_frame = | |
1032 &(translated_state_.frames()[frame_index]); | |
1033 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | |
1034 int input_index = 0; | |
1035 | |
1036 BailoutId bytecode_offset = translated_frame->node_id(); | |
1037 unsigned height = translated_frame->height(); | |
1038 unsigned height_in_bytes = height * kPointerSize; | |
1039 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); | |
1040 value_iterator++; | |
1041 input_index++; | |
1042 if (trace_scope_ != NULL) { | |
1043 PrintF(trace_scope_->file(), " translating interpreted frame "); | |
1044 function->PrintName(trace_scope_->file()); | |
1045 PrintF(trace_scope_->file(), " => bytecode_offset=%d, height=%d\n", | |
1046 bytecode_offset.ToInt(), height_in_bytes); | |
1047 } | |
1048 | |
1049 // The 'fixed' part of the frame consists of the incoming parameters and | |
1050 // the part described by JavaScriptFrameConstants. | |
1051 unsigned fixed_frame_size = | |
1052 ComputeFixedSize(function, StackFrame::INTERPRETED); | |
1053 unsigned input_frame_size = input_->GetFrameSize(); | |
1054 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | |
1055 | |
1056 // Allocate and store the output frame description. | |
1057 FrameDescription* output_frame = | |
1058 new (output_frame_size) FrameDescription(output_frame_size, function); | |
1059 output_frame->SetFrameType(StackFrame::INTERPRETED); | |
1060 | |
1061 bool is_bottommost = (0 == frame_index); | |
1062 bool is_topmost = (output_count_ - 1 == frame_index); | |
1063 CHECK(frame_index >= 0 && frame_index < output_count_); | |
1064 CHECK_NULL(output_[frame_index]); | |
1065 output_[frame_index] = output_frame; | |
1066 | |
1067 // The top address for the bottommost output frame can be computed from | |
1068 // the input frame pointer and the output frame's height. For all | |
1069 // subsequent output frames, it can be computed from the previous one's | |
1070 // top address and the current frame's size. | |
1071 Register fp_reg = InterpretedFrame::fp_register(); | |
1072 intptr_t top_address; | |
1073 if (is_bottommost) { | |
1074 // Determine whether the input frame contains alignment padding. | |
1075 has_alignment_padding_ = | |
1076 (!compiled_code_->is_turbofanned() && HasAlignmentPadding(function)) | |
1077 ? 1 | |
1078 : 0; | |
1079 // 2 = context and function in the frame. | |
1080 // If the optimized frame had alignment padding, adjust the frame pointer | |
1081 // to point to the new position of the old frame pointer after padding | |
1082 // is removed. Subtract 2 * kPointerSize for the context and function slots. | |
1083 top_address = input_->GetRegister(fp_reg.code()) - | |
1084 InterpreterFrameConstants::kFixedFrameSizeFromFp - | |
1085 height_in_bytes + has_alignment_padding_ * kPointerSize; | |
1086 } else { | |
1087 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | |
1088 } | |
1089 output_frame->SetTop(top_address); | |
1090 | |
1091 // Compute the incoming parameter translation. | |
1092 int parameter_count = | |
1093 function->shared()->internal_formal_parameter_count() + 1; | |
1094 unsigned output_offset = output_frame_size; | |
1095 unsigned input_offset = input_frame_size; | |
1096 for (int i = 0; i < parameter_count; ++i) { | |
1097 output_offset -= kPointerSize; | |
1098 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, | |
1099 output_offset); | |
1100 } | |
1101 input_offset -= (parameter_count * kPointerSize); | |
1102 | |
1103 // There are no translation commands for the caller's pc and fp, the | |
1104 // context, the function, new.target and the bytecode offset. Synthesize | |
1105 // their values and set them up | |
1106 // explicitly. | |
1107 // | |
1108 // The caller's pc for the bottommost output frame is the same as in the | |
1109 // input frame. For all subsequent output frames, it can be read from the | |
1110 // previous one. This frame's pc can be computed from the non-optimized | |
1111 // function code and AST id of the bailout. | |
1112 output_offset -= kPCOnStackSize; | |
1113 input_offset -= kPCOnStackSize; | |
1114 intptr_t value; | |
1115 if (is_bottommost) { | |
1116 value = input_->GetFrameSlot(input_offset); | |
1117 } else { | |
1118 value = output_[frame_index - 1]->GetPc(); | |
1119 } | |
1120 output_frame->SetCallerPc(output_offset, value); | |
1121 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's pc\n"); | |
1122 | |
1123 // The caller's frame pointer for the bottommost output frame is the same | |
1124 // as in the input frame. For all subsequent output frames, it can be | |
1125 // read from the previous one. Also compute and set this frame's frame | |
1126 // pointer. | |
1127 output_offset -= kFPOnStackSize; | |
1128 input_offset -= kFPOnStackSize; | |
1129 if (is_bottommost) { | |
1130 value = input_->GetFrameSlot(input_offset); | |
1131 } else { | |
1132 value = output_[frame_index - 1]->GetFp(); | |
1133 } | |
1134 output_frame->SetCallerFp(output_offset, value); | |
1135 intptr_t fp_value = top_address + output_offset; | |
1136 DCHECK(!is_bottommost || | |
1137 (input_->GetRegister(fp_reg.code()) + | |
1138 has_alignment_padding_ * kPointerSize) == fp_value); | |
1139 output_frame->SetFp(fp_value); | |
1140 if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value); | |
1141 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n"); | |
1142 DCHECK(!is_bottommost || !has_alignment_padding_ || | |
1143 (fp_value & kPointerSize) != 0); | |
1144 | |
1145 if (FLAG_enable_embedded_constant_pool) { | |
1146 // For the bottommost output frame the constant pool pointer can be gotten | |
1147 // from the input frame. For subsequent output frames, it can be read from | |
1148 // the previous frame. | |
1149 output_offset -= kPointerSize; | |
1150 input_offset -= kPointerSize; | |
1151 if (is_bottommost) { | |
1152 value = input_->GetFrameSlot(input_offset); | |
1153 } else { | |
1154 value = output_[frame_index - 1]->GetConstantPool(); | |
1155 } | |
1156 output_frame->SetCallerConstantPool(output_offset, value); | |
1157 DebugPrintOutputSlot(value, frame_index, output_offset, | |
1158 "caller's constant_pool\n"); | |
1159 } | |
1160 | |
1161 // For the bottommost output frame the context can be gotten from the input | |
1162 // frame. For all subsequent output frames it can be gotten from the function | |
1163 // so long as we don't inline functions that need local contexts. | |
1164 Register context_reg = InterpretedFrame::context_register(); | |
1165 output_offset -= kPointerSize; | |
1166 input_offset -= kPointerSize; | |
1167 // Read the context from the translations. | |
1168 Object* context = value_iterator->GetRawValue(); | |
1169 // The context should not be a placeholder for a materialized object. | |
1170 CHECK(context != isolate_->heap()->arguments_marker()); | |
1171 if (context == isolate_->heap()->undefined_value()) { | |
Jarin
2015/12/17 13:35:09
You should not need this case, that is only for cr
rmcilroy
2015/12/17 23:49:54
Good point, removed! Also removed the "!compiled_c
| |
1172 // If the context was optimized away, just use the context from | |
1173 // the activation. This should only apply to Crankshaft code. | |
1174 CHECK(!compiled_code_->is_turbofanned()); | |
1175 context = | |
1176 is_bottommost | |
1177 ? reinterpret_cast<Object*>(input_->GetFrameSlot(input_offset)) | |
1178 : function->context(); | |
1179 } | |
1180 value = reinterpret_cast<intptr_t>(context); | |
1181 output_frame->SetContext(value); | |
1182 if (is_topmost) output_frame->SetRegister(context_reg.code(), value); | |
1183 WriteValueToOutput(context, input_index, frame_index, output_offset, | |
1184 "context "); | |
1185 value_iterator++; | |
1186 input_index++; | |
1187 | |
1188 // The function was mentioned explicitly in the BEGIN_FRAME. | |
1189 output_offset -= kPointerSize; | |
1190 input_offset -= kPointerSize; | |
1191 value = reinterpret_cast<intptr_t>(function); | |
1192 // The function for the bottommost output frame should also agree with the | |
1193 // input frame. | |
1194 DCHECK(!is_bottommost || input_->GetFrameSlot(input_offset) == value); | |
1195 WriteValueToOutput(function, 0, frame_index, output_offset, "function "); | |
1196 | |
1197 // TODO(rmcilroy): Deal with new.target correctly - currently just set it to | |
1198 // undefined. | |
1199 output_offset -= kPointerSize; | |
1200 input_offset -= kPointerSize; | |
1201 Object* new_target = isolate_->heap()->undefined_value(); | |
1202 WriteValueToOutput(new_target, 0, frame_index, output_offset, "new_target "); | |
1203 | |
1204 // The bytecode offset was mentioned explicitly in the BEGIN_FRAME. | |
1205 output_offset -= kPointerSize; | |
1206 input_offset -= kPointerSize; | |
1207 int raw_bytecode_offset = | |
1208 BytecodeArray::kHeaderSize - kHeapObjectTag + bytecode_offset.ToInt(); | |
1209 Smi* smi_bytecode_offset = Smi::FromInt(raw_bytecode_offset); | |
1210 WriteValueToOutput(smi_bytecode_offset, 0, frame_index, output_offset, | |
1211 "bytecode offset "); | |
1212 | |
1213 // Translate the rest of the interpreter registers in the frame. | |
1214 for (unsigned i = 0; i < height; ++i) { | |
1215 output_offset -= kPointerSize; | |
1216 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, | |
1217 output_offset); | |
1218 } | |
1219 CHECK_EQ(0u, output_offset); | |
1220 | |
1221 // Set the accumulator register. | |
1222 output_frame->SetRegister( | |
1223 kInterpreterAccumulatorRegister.code(), | |
1224 reinterpret_cast<intptr_t>(value_iterator->GetRawValue())); | |
1225 value_iterator++; | |
1226 | |
1227 Builtins* builtins = isolate_->builtins(); | |
1228 Code* trampoline = builtins->builtin(Builtins::kInterpreterEntryTrampoline); | |
1229 output_frame->SetPc(reinterpret_cast<intptr_t>(trampoline->entry())); | |
1230 output_frame->SetState(0); | |
1231 | |
1232 // Update constant pool. | |
1233 if (FLAG_enable_embedded_constant_pool) { | |
1234 intptr_t constant_pool_value = | |
1235 reinterpret_cast<intptr_t>(trampoline->constant_pool()); | |
1236 output_frame->SetConstantPool(constant_pool_value); | |
1237 if (is_topmost) { | |
1238 Register constant_pool_reg = | |
1239 InterpretedFrame::constant_pool_pointer_register(); | |
1240 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value); | |
1241 } | |
1242 } | |
1243 | |
1244 // Set the continuation for the topmost frame. | |
1245 if (is_topmost && bailout_type_ != DEBUGGER) { | |
1246 Code* continuation = | |
1247 builtins->builtin(Builtins::kInterpreterNotifyDeoptimized); | |
1248 if (bailout_type_ == LAZY) { | |
1249 continuation = | |
1250 builtins->builtin(Builtins::kInterpreterNotifyLazyDeoptimized); | |
1251 } else if (bailout_type_ == SOFT) { | |
1252 continuation = | |
1253 builtins->builtin(Builtins::kInterpreterNotifySoftDeoptimized); | |
1254 } else { | |
1255 CHECK_EQ(bailout_type_, EAGER); | |
1256 } | |
1257 output_frame->SetContinuation( | |
1258 reinterpret_cast<intptr_t>(continuation->entry())); | |
1259 } | |
1260 } | |
1261 | |
1262 | |
1025 void Deoptimizer::DoComputeArgumentsAdaptorFrame(int frame_index) { | 1263 void Deoptimizer::DoComputeArgumentsAdaptorFrame(int frame_index) { |
1026 TranslatedFrame* translated_frame = | 1264 TranslatedFrame* translated_frame = |
1027 &(translated_state_.frames()[frame_index]); | 1265 &(translated_state_.frames()[frame_index]); |
1028 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 1266 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
1029 int input_index = 0; | 1267 int input_index = 0; |
1030 | 1268 |
1031 unsigned height = translated_frame->height(); | 1269 unsigned height = translated_frame->height(); |
1032 unsigned height_in_bytes = height * kPointerSize; | 1270 unsigned height_in_bytes = height * kPointerSize; |
1033 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); | 1271 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); |
1034 value_iterator++; | 1272 value_iterator++; |
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1749 output_offset; | 1987 output_offset; |
1750 PrintF(trace_scope_->file(), | 1988 PrintF(trace_scope_->file(), |
1751 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s", | 1989 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s", |
1752 reinterpret_cast<intptr_t>(output_address), output_offset, value, | 1990 reinterpret_cast<intptr_t>(output_address), output_offset, value, |
1753 debug_hint_string == nullptr ? "" : debug_hint_string); | 1991 debug_hint_string == nullptr ? "" : debug_hint_string); |
1754 } | 1992 } |
1755 } | 1993 } |
1756 | 1994 |
1757 | 1995 |
1758 unsigned Deoptimizer::ComputeInputFrameSize() const { | 1996 unsigned Deoptimizer::ComputeInputFrameSize() const { |
1759 unsigned fixed_size = ComputeFixedSize(function_); | 1997 StackFrame::Type type = compiled_code_->kind() == Code::OPTIMIZED_FUNCTION |
1998 ? StackFrame::OPTIMIZED | |
1999 : StackFrame::JAVA_SCRIPT; | |
2000 unsigned fixed_size = ComputeFixedSize(function_, type); | |
Jarin
2015/12/17 13:35:09
I am a bit confused here. Input frame should be al
rmcilroy
2015/12/17 23:49:54
I agree, I always see OPTIMZED here, I was just co
Jarin
2015/12/18 08:58:21
I am not completely sure, but I think it is there
rmcilroy
2015/12/18 15:18:10
Ahh that makes sense. I didn't think they could de
| |
1760 // The fp-to-sp delta already takes the context, constant pool pointer and the | 2001 // 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. | 2002 // function into account so we have to avoid double counting them. |
1762 unsigned result = fixed_size + fp_to_sp_delta_ - | 2003 unsigned result = fixed_size + fp_to_sp_delta_ - |
1763 StandardFrameConstants::kFixedFrameSizeFromFp; | 2004 StandardFrameConstants::kFixedFrameSizeFromFp; |
1764 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { | 2005 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { |
1765 unsigned stack_slots = compiled_code_->stack_slots(); | 2006 unsigned stack_slots = compiled_code_->stack_slots(); |
1766 unsigned outgoing_size = | 2007 unsigned outgoing_size = |
1767 ComputeOutgoingArgumentSize(compiled_code_, bailout_id_); | 2008 ComputeOutgoingArgumentSize(compiled_code_, bailout_id_); |
1768 CHECK(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size); | 2009 CHECK(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size); |
1769 } | 2010 } |
1770 return result; | 2011 return result; |
1771 } | 2012 } |
1772 | 2013 |
1773 | 2014 |
1774 unsigned Deoptimizer::ComputeFixedSize(JSFunction* function) const { | 2015 unsigned Deoptimizer::ComputeFixedSize(JSFunction* function, |
2016 StackFrame::Type type) const { | |
Jarin
2015/12/17 13:35:09
As far as I can see all callers statically know wh
rmcilroy
2015/12/17 23:49:54
Done.
| |
1775 // The fixed part of the frame consists of the return address, frame | 2017 // The fixed part of the frame consists of the return address, frame |
1776 // pointer, function, context, and all the incoming arguments. | 2018 // pointer, function, context, and all the incoming arguments. |
1777 return ComputeIncomingArgumentSize(function) + | 2019 return ComputeIncomingArgumentSize(function) + |
1778 StandardFrameConstants::kFixedFrameSize; | 2020 (type == StackFrame::INTERPRETED |
2021 ? InterpreterFrameConstants::kFixedFrameSize | |
2022 : StandardFrameConstants::kFixedFrameSize); | |
1779 } | 2023 } |
1780 | 2024 |
1781 | 2025 |
1782 unsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const { | 2026 unsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const { |
1783 // The incoming arguments is the values for formal parameters and | 2027 // The incoming arguments is the values for formal parameters and |
1784 // the receiver. Every slot contains a pointer. | 2028 // the receiver. Every slot contains a pointer. |
1785 if (function->IsSmi()) { | 2029 if (function->IsSmi()) { |
1786 CHECK_EQ(Smi::cast(function), Smi::FromInt(StackFrame::STUB)); | 2030 CHECK_EQ(Smi::cast(function), Smi::FromInt(StackFrame::STUB)); |
1787 return 0; | 2031 return 0; |
1788 } | 2032 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1865 } | 2109 } |
1866 | 2110 |
1867 // Zap all the slots. | 2111 // Zap all the slots. |
1868 for (unsigned o = 0; o < frame_size; o += kPointerSize) { | 2112 for (unsigned o = 0; o < frame_size; o += kPointerSize) { |
1869 SetFrameSlot(o, kZapUint32); | 2113 SetFrameSlot(o, kZapUint32); |
1870 } | 2114 } |
1871 } | 2115 } |
1872 | 2116 |
1873 | 2117 |
1874 int FrameDescription::ComputeFixedSize() { | 2118 int FrameDescription::ComputeFixedSize() { |
1875 return StandardFrameConstants::kFixedFrameSize + | 2119 if (type_ == StackFrame::INTERPRETED) { |
1876 (ComputeParametersCount() + 1) * kPointerSize; | 2120 return InterpreterFrameConstants::kFixedFrameSize + |
2121 (ComputeParametersCount() + 1) * kPointerSize; | |
2122 } else { | |
2123 return StandardFrameConstants::kFixedFrameSize + | |
2124 (ComputeParametersCount() + 1) * kPointerSize; | |
2125 } | |
1877 } | 2126 } |
1878 | 2127 |
1879 | 2128 |
1880 unsigned FrameDescription::GetOffsetFromSlotIndex(int slot_index) { | 2129 unsigned FrameDescription::GetOffsetFromSlotIndex(int slot_index) { |
1881 if (slot_index >= 0) { | 2130 if (slot_index >= 0) { |
1882 // Local or spill slots. Skip the fixed part of the frame | 2131 // Local or spill slots. Skip the fixed part of the frame |
1883 // including all arguments. | 2132 // including all arguments. |
1884 unsigned base = GetFrameSize() - ComputeFixedSize(); | 2133 unsigned base = GetFrameSize() - ComputeFixedSize(); |
1885 return base - ((slot_index + 1) * kPointerSize); | 2134 return base - ((slot_index + 1) * kPointerSize); |
1886 } else { | 2135 } else { |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2004 void Translation::BeginJSFrame(BailoutId node_id, | 2253 void Translation::BeginJSFrame(BailoutId node_id, |
2005 int literal_id, | 2254 int literal_id, |
2006 unsigned height) { | 2255 unsigned height) { |
2007 buffer_->Add(JS_FRAME, zone()); | 2256 buffer_->Add(JS_FRAME, zone()); |
2008 buffer_->Add(node_id.ToInt(), zone()); | 2257 buffer_->Add(node_id.ToInt(), zone()); |
2009 buffer_->Add(literal_id, zone()); | 2258 buffer_->Add(literal_id, zone()); |
2010 buffer_->Add(height, zone()); | 2259 buffer_->Add(height, zone()); |
2011 } | 2260 } |
2012 | 2261 |
2013 | 2262 |
2263 void Translation::BeginInterpretedFrame(BailoutId bytecode_offset, | |
2264 int literal_id, unsigned height) { | |
2265 buffer_->Add(INTERPRETED_FRAME, zone()); | |
2266 buffer_->Add(bytecode_offset.ToInt(), zone()); | |
2267 buffer_->Add(literal_id, zone()); | |
2268 buffer_->Add(height, zone()); | |
2269 } | |
2270 | |
2271 | |
2014 void Translation::BeginCompiledStubFrame(int height) { | 2272 void Translation::BeginCompiledStubFrame(int height) { |
2015 buffer_->Add(COMPILED_STUB_FRAME, zone()); | 2273 buffer_->Add(COMPILED_STUB_FRAME, zone()); |
2016 buffer_->Add(height, zone()); | 2274 buffer_->Add(height, zone()); |
2017 } | 2275 } |
2018 | 2276 |
2019 | 2277 |
2020 void Translation::BeginArgumentsObject(int args_length) { | 2278 void Translation::BeginArgumentsObject(int args_length) { |
2021 buffer_->Add(ARGUMENTS_OBJECT, zone()); | 2279 buffer_->Add(ARGUMENTS_OBJECT, zone()); |
2022 buffer_->Add(args_length, zone()); | 2280 buffer_->Add(args_length, zone()); |
2023 } | 2281 } |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2136 case BOOL_STACK_SLOT: | 2394 case BOOL_STACK_SLOT: |
2137 case DOUBLE_STACK_SLOT: | 2395 case DOUBLE_STACK_SLOT: |
2138 case LITERAL: | 2396 case LITERAL: |
2139 case COMPILED_STUB_FRAME: | 2397 case COMPILED_STUB_FRAME: |
2140 return 1; | 2398 return 1; |
2141 case BEGIN: | 2399 case BEGIN: |
2142 case ARGUMENTS_ADAPTOR_FRAME: | 2400 case ARGUMENTS_ADAPTOR_FRAME: |
2143 case CONSTRUCT_STUB_FRAME: | 2401 case CONSTRUCT_STUB_FRAME: |
2144 return 2; | 2402 return 2; |
2145 case JS_FRAME: | 2403 case JS_FRAME: |
2404 case INTERPRETED_FRAME: | |
2146 return 3; | 2405 return 3; |
2147 } | 2406 } |
2148 FATAL("Unexpected translation type"); | 2407 FATAL("Unexpected translation type"); |
2149 return -1; | 2408 return -1; |
2150 } | 2409 } |
2151 | 2410 |
2152 | 2411 |
2153 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) | 2412 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) |
2154 | 2413 |
2155 const char* Translation::StringFor(Opcode opcode) { | 2414 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, | 2868 TranslatedFrame TranslatedFrame::JSFrame(BailoutId node_id, |
2610 SharedFunctionInfo* shared_info, | 2869 SharedFunctionInfo* shared_info, |
2611 int height) { | 2870 int height) { |
2612 TranslatedFrame frame(kFunction, shared_info->GetIsolate(), shared_info, | 2871 TranslatedFrame frame(kFunction, shared_info->GetIsolate(), shared_info, |
2613 height); | 2872 height); |
2614 frame.node_id_ = node_id; | 2873 frame.node_id_ = node_id; |
2615 return frame; | 2874 return frame; |
2616 } | 2875 } |
2617 | 2876 |
2618 | 2877 |
2878 TranslatedFrame TranslatedFrame::InterpretedFrame( | |
2879 BailoutId bytecode_offset, SharedFunctionInfo* shared_info, int height) { | |
2880 TranslatedFrame frame(kInterpretedFunction, shared_info->GetIsolate(), | |
2881 shared_info, height); | |
2882 frame.node_id_ = bytecode_offset; | |
2883 return frame; | |
2884 } | |
2885 | |
2886 | |
2619 TranslatedFrame TranslatedFrame::AccessorFrame( | 2887 TranslatedFrame TranslatedFrame::AccessorFrame( |
2620 Kind kind, SharedFunctionInfo* shared_info) { | 2888 Kind kind, SharedFunctionInfo* shared_info) { |
2621 DCHECK(kind == kSetter || kind == kGetter); | 2889 DCHECK(kind == kSetter || kind == kGetter); |
2622 return TranslatedFrame(kind, shared_info->GetIsolate(), shared_info); | 2890 return TranslatedFrame(kind, shared_info->GetIsolate(), shared_info); |
2623 } | 2891 } |
2624 | 2892 |
2625 | 2893 |
2626 TranslatedFrame TranslatedFrame::ArgumentsAdaptorFrame( | 2894 TranslatedFrame TranslatedFrame::ArgumentsAdaptorFrame( |
2627 SharedFunctionInfo* shared_info, int height) { | 2895 SharedFunctionInfo* shared_info, int height) { |
2628 return TranslatedFrame(kArgumentsAdaptor, shared_info->GetIsolate(), | 2896 return TranslatedFrame(kArgumentsAdaptor, shared_info->GetIsolate(), |
2629 shared_info, height); | 2897 shared_info, height); |
2630 } | 2898 } |
2631 | 2899 |
2632 | 2900 |
2633 TranslatedFrame TranslatedFrame::ConstructStubFrame( | 2901 TranslatedFrame TranslatedFrame::ConstructStubFrame( |
2634 SharedFunctionInfo* shared_info, int height) { | 2902 SharedFunctionInfo* shared_info, int height) { |
2635 return TranslatedFrame(kConstructStub, shared_info->GetIsolate(), shared_info, | 2903 return TranslatedFrame(kConstructStub, shared_info->GetIsolate(), shared_info, |
2636 height); | 2904 height); |
2637 } | 2905 } |
2638 | 2906 |
2639 | 2907 |
2640 int TranslatedFrame::GetValueCount() { | 2908 int TranslatedFrame::GetValueCount() { |
2641 switch (kind()) { | 2909 switch (kind()) { |
2642 case kFunction: { | 2910 case kFunction: { |
2643 int parameter_count = | 2911 int parameter_count = |
2644 raw_shared_info_->internal_formal_parameter_count() + 1; | 2912 raw_shared_info_->internal_formal_parameter_count() + 1; |
2645 return height_ + parameter_count + 1; | 2913 return height_ + parameter_count + 1; |
2646 } | 2914 } |
2647 | 2915 |
2916 case kInterpretedFunction: { | |
2917 int parameter_count = | |
2918 raw_shared_info_->internal_formal_parameter_count() + 1; | |
2919 return height_ + parameter_count + 3; | |
Jarin
2015/12/17 13:35:09
Could you possibly add a comment, which explains w
rmcilroy
2015/12/17 23:49:54
Done. Also for kFunction above.
| |
2920 } | |
2921 | |
2648 case kGetter: | 2922 case kGetter: |
2649 return 2; // Function and receiver. | 2923 return 2; // Function and receiver. |
2650 | 2924 |
2651 case kSetter: | 2925 case kSetter: |
2652 return 3; // Function, receiver and the value to set. | 2926 return 3; // Function, receiver and the value to set. |
2653 | 2927 |
2654 case kArgumentsAdaptor: | 2928 case kArgumentsAdaptor: |
2655 case kConstructStub: | 2929 case kConstructStub: |
2656 return 1 + height_; | 2930 return 1 + height_; |
2657 | 2931 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2693 base::SmartArrayPointer<char> name = | 2967 base::SmartArrayPointer<char> name = |
2694 shared_info->DebugName()->ToCString(); | 2968 shared_info->DebugName()->ToCString(); |
2695 PrintF(trace_file, " reading input frame %s", name.get()); | 2969 PrintF(trace_file, " reading input frame %s", name.get()); |
2696 int arg_count = shared_info->internal_formal_parameter_count() + 1; | 2970 int arg_count = shared_info->internal_formal_parameter_count() + 1; |
2697 PrintF(trace_file, " => node=%d, args=%d, height=%d; inputs:\n", | 2971 PrintF(trace_file, " => node=%d, args=%d, height=%d; inputs:\n", |
2698 node_id.ToInt(), arg_count, height); | 2972 node_id.ToInt(), arg_count, height); |
2699 } | 2973 } |
2700 return TranslatedFrame::JSFrame(node_id, shared_info, height); | 2974 return TranslatedFrame::JSFrame(node_id, shared_info, height); |
2701 } | 2975 } |
2702 | 2976 |
2977 case Translation::INTERPRETED_FRAME: { | |
2978 BailoutId bytecode_offset = BailoutId(iterator->Next()); | |
2979 SharedFunctionInfo* shared_info = | |
2980 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); | |
2981 int height = iterator->Next(); | |
2982 if (trace_file != nullptr) { | |
2983 base::SmartArrayPointer<char> name = | |
2984 shared_info->DebugName()->ToCString(); | |
2985 PrintF(trace_file, " reading input frame %s", name.get()); | |
2986 int arg_count = shared_info->internal_formal_parameter_count() + 1; | |
2987 PrintF(trace_file, | |
2988 " => bytecode_offset=%d, args=%d, height=%d; inputs:\n", | |
2989 bytecode_offset.ToInt(), arg_count, height); | |
2990 } | |
2991 return TranslatedFrame::InterpretedFrame(bytecode_offset, shared_info, | |
2992 height); | |
2993 } | |
2994 | |
2703 case Translation::ARGUMENTS_ADAPTOR_FRAME: { | 2995 case Translation::ARGUMENTS_ADAPTOR_FRAME: { |
2704 SharedFunctionInfo* shared_info = | 2996 SharedFunctionInfo* shared_info = |
2705 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); | 2997 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
2706 int height = iterator->Next(); | 2998 int height = iterator->Next(); |
2707 if (trace_file != nullptr) { | 2999 if (trace_file != nullptr) { |
2708 base::SmartArrayPointer<char> name = | 3000 base::SmartArrayPointer<char> name = |
2709 shared_info->DebugName()->ToCString(); | 3001 shared_info->DebugName()->ToCString(); |
2710 PrintF(trace_file, " reading arguments adaptor frame %s", name.get()); | 3002 PrintF(trace_file, " reading arguments adaptor frame %s", name.get()); |
2711 PrintF(trace_file, " => height=%d; inputs:\n", height); | 3003 PrintF(trace_file, " => height=%d; inputs:\n", height); |
2712 } | 3004 } |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2805 int frame_index, int value_index, TranslationIterator* iterator, | 3097 int frame_index, int value_index, TranslationIterator* iterator, |
2806 FixedArray* literal_array, Address fp, RegisterValues* registers, | 3098 FixedArray* literal_array, Address fp, RegisterValues* registers, |
2807 FILE* trace_file) { | 3099 FILE* trace_file) { |
2808 disasm::NameConverter converter; | 3100 disasm::NameConverter converter; |
2809 | 3101 |
2810 Translation::Opcode opcode = | 3102 Translation::Opcode opcode = |
2811 static_cast<Translation::Opcode>(iterator->Next()); | 3103 static_cast<Translation::Opcode>(iterator->Next()); |
2812 switch (opcode) { | 3104 switch (opcode) { |
2813 case Translation::BEGIN: | 3105 case Translation::BEGIN: |
2814 case Translation::JS_FRAME: | 3106 case Translation::JS_FRAME: |
3107 case Translation::INTERPRETED_FRAME: | |
2815 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 3108 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
2816 case Translation::CONSTRUCT_STUB_FRAME: | 3109 case Translation::CONSTRUCT_STUB_FRAME: |
2817 case Translation::GETTER_STUB_FRAME: | 3110 case Translation::GETTER_STUB_FRAME: |
2818 case Translation::SETTER_STUB_FRAME: | 3111 case Translation::SETTER_STUB_FRAME: |
2819 case Translation::COMPILED_STUB_FRAME: | 3112 case Translation::COMPILED_STUB_FRAME: |
2820 // Peeled off before getting here. | 3113 // Peeled off before getting here. |
2821 break; | 3114 break; |
2822 | 3115 |
2823 case Translation::DUPLICATED_OBJECT: { | 3116 case Translation::DUPLICATED_OBJECT: { |
2824 int object_id = iterator->Next(); | 3117 int object_id = iterator->Next(); |
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3389 DCHECK(value_info->IsMaterializedObject()); | 3682 DCHECK(value_info->IsMaterializedObject()); |
3390 | 3683 |
3391 value_info->value_ = | 3684 value_info->value_ = |
3392 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 3685 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
3393 } | 3686 } |
3394 } | 3687 } |
3395 } | 3688 } |
3396 | 3689 |
3397 } // namespace internal | 3690 } // namespace internal |
3398 } // namespace v8 | 3691 } // namespace v8 |
OLD | NEW |