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 |