Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(758)

Side by Side Diff: src/deoptimizer.cc

Issue 1528913003: [Interpreter] Add basic deoptimization support from TurboFan to Ignition. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@int_deopt_1
Patch Set: Add basic support to OptimizedFrame::Summarize() for interpreted_frame deopt data. Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/deoptimizer.h ('k') | src/frames.h » ('j') | src/frames.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/deoptimizer.h ('k') | src/frames.h » ('j') | src/frames.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698