| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #include "code-stubs.h" | 7 #include "code-stubs.h" |
| 8 #include "hydrogen.h" | 8 #include "hydrogen.h" |
| 9 #include "lithium.h" | 9 #include "lithium.h" |
| 10 | 10 |
| (...skipping 1102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1113 | 1113 |
| 1114 return value; | 1114 return value; |
| 1115 } | 1115 } |
| 1116 | 1116 |
| 1117 | 1117 |
| 1118 Handle<Code> ElementsTransitionAndStoreStub::GenerateCode() { | 1118 Handle<Code> ElementsTransitionAndStoreStub::GenerateCode() { |
| 1119 return DoGenerateCode(this); | 1119 return DoGenerateCode(this); |
| 1120 } | 1120 } |
| 1121 | 1121 |
| 1122 | 1122 |
| 1123 template <> | |
| 1124 HValue* CodeStubGraphBuilder<ArrayShiftStub>::BuildCodeStub() { | |
| 1125 HValue* receiver = GetParameter(ArrayShiftStub::kReceiver); | |
| 1126 ElementsKind kind = casted_stub()->kind(); | |
| 1127 | |
| 1128 // We may use double registers for copying. | |
| 1129 if (IsFastDoubleElementsKind(kind)) info()->MarkAsSavesCallerDoubles(); | |
| 1130 | |
| 1131 HValue* length = Add<HLoadNamedField>( | |
| 1132 receiver, static_cast<HValue*>(NULL), | |
| 1133 HObjectAccess::ForArrayLength(kind)); | |
| 1134 | |
| 1135 IfBuilder if_lengthiszero(this); | |
| 1136 HValue* lengthiszero = if_lengthiszero.If<HCompareNumericAndBranch>( | |
| 1137 length, graph()->GetConstant0(), Token::EQ); | |
| 1138 if_lengthiszero.Then(); | |
| 1139 { | |
| 1140 Push(graph()->GetConstantUndefined()); | |
| 1141 } | |
| 1142 if_lengthiszero.Else(); | |
| 1143 { | |
| 1144 // Check if array length is below threshold. | |
| 1145 IfBuilder if_inline(this); | |
| 1146 if_inline.If<HCompareNumericAndBranch>( | |
| 1147 length, Add<HConstant>(ArrayShiftStub::kInlineThreshold), Token::LTE); | |
| 1148 if_inline.Then(); | |
| 1149 if_inline.ElseDeopt("Array length exceeds threshold"); | |
| 1150 if_inline.End(); | |
| 1151 | |
| 1152 // We cannot handle copy-on-write backing stores here. | |
| 1153 HValue* elements = AddLoadElements(receiver); | |
| 1154 if (IsFastSmiOrObjectElementsKind(kind)) { | |
| 1155 Add<HCheckMaps>(elements, isolate()->factory()->fixed_array_map()); | |
| 1156 } | |
| 1157 | |
| 1158 // Remember the result. | |
| 1159 Push(AddElementAccess(elements, graph()->GetConstant0(), NULL, | |
| 1160 lengthiszero, kind, LOAD)); | |
| 1161 | |
| 1162 // Compute the new length. | |
| 1163 HValue* new_length = AddUncasted<HSub>(length, graph()->GetConstant1()); | |
| 1164 new_length->ClearFlag(HValue::kCanOverflow); | |
| 1165 | |
| 1166 // Copy the remaining elements. | |
| 1167 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); | |
| 1168 { | |
| 1169 HValue* new_key = loop.BeginBody( | |
| 1170 graph()->GetConstant0(), new_length, Token::LT); | |
| 1171 HValue* key = AddUncasted<HAdd>(new_key, graph()->GetConstant1()); | |
| 1172 key->ClearFlag(HValue::kCanOverflow); | |
| 1173 HValue* element = AddUncasted<HLoadKeyed>( | |
| 1174 elements, key, lengthiszero, kind, ALLOW_RETURN_HOLE); | |
| 1175 HStoreKeyed* store = Add<HStoreKeyed>(elements, new_key, element, kind); | |
| 1176 store->SetFlag(HValue::kAllowUndefinedAsNaN); | |
| 1177 } | |
| 1178 loop.EndBody(); | |
| 1179 | |
| 1180 // Put a hole at the end. | |
| 1181 HValue* hole = IsFastSmiOrObjectElementsKind(kind) | |
| 1182 ? Add<HConstant>(isolate()->factory()->the_hole_value()) | |
| 1183 : Add<HConstant>(FixedDoubleArray::hole_nan_as_double()); | |
| 1184 if (IsFastSmiOrObjectElementsKind(kind)) kind = FAST_HOLEY_ELEMENTS; | |
| 1185 Add<HStoreKeyed>(elements, new_length, hole, kind, INITIALIZING_STORE); | |
| 1186 | |
| 1187 // Remember new length. | |
| 1188 Add<HStoreNamedField>( | |
| 1189 receiver, HObjectAccess::ForArrayLength(kind), | |
| 1190 new_length, STORE_TO_INITIALIZED_ENTRY); | |
| 1191 } | |
| 1192 if_lengthiszero.End(); | |
| 1193 | |
| 1194 return Pop(); | |
| 1195 } | |
| 1196 | |
| 1197 | |
| 1198 Handle<Code> ArrayShiftStub::GenerateCode() { | |
| 1199 return DoGenerateCode(this); | |
| 1200 } | |
| 1201 | |
| 1202 | |
| 1203 void CodeStubGraphBuilderBase::BuildCheckAndInstallOptimizedCode( | 1123 void CodeStubGraphBuilderBase::BuildCheckAndInstallOptimizedCode( |
| 1204 HValue* js_function, | 1124 HValue* js_function, |
| 1205 HValue* native_context, | 1125 HValue* native_context, |
| 1206 IfBuilder* builder, | 1126 IfBuilder* builder, |
| 1207 HValue* optimized_map, | 1127 HValue* optimized_map, |
| 1208 HValue* map_index) { | 1128 HValue* map_index) { |
| 1209 HValue* osr_ast_id_none = Add<HConstant>(BailoutId::None().ToInt()); | 1129 HValue* osr_ast_id_none = Add<HConstant>(BailoutId::None().ToInt()); |
| 1210 HValue* context_slot = LoadFromOptimizedCodeMap( | 1130 HValue* context_slot = LoadFromOptimizedCodeMap( |
| 1211 optimized_map, map_index, SharedFunctionInfo::kContextOffset); | 1131 optimized_map, map_index, SharedFunctionInfo::kContextOffset); |
| 1212 HValue* osr_ast_slot = LoadFromOptimizedCodeMap( | 1132 HValue* osr_ast_slot = LoadFromOptimizedCodeMap( |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1493 return BuildRegExpConstructResult(length, index, input); | 1413 return BuildRegExpConstructResult(length, index, input); |
| 1494 } | 1414 } |
| 1495 | 1415 |
| 1496 | 1416 |
| 1497 Handle<Code> RegExpConstructResultStub::GenerateCode() { | 1417 Handle<Code> RegExpConstructResultStub::GenerateCode() { |
| 1498 return DoGenerateCode(this); | 1418 return DoGenerateCode(this); |
| 1499 } | 1419 } |
| 1500 | 1420 |
| 1501 | 1421 |
| 1502 } } // namespace v8::internal | 1422 } } // namespace v8::internal |
| OLD | NEW |