Chromium Code Reviews| 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 |