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 1095 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1106 | 1106 |
1107 return value; | 1107 return value; |
1108 } | 1108 } |
1109 | 1109 |
1110 | 1110 |
1111 Handle<Code> ElementsTransitionAndStoreStub::GenerateCode() { | 1111 Handle<Code> ElementsTransitionAndStoreStub::GenerateCode() { |
1112 return DoGenerateCode(this); | 1112 return DoGenerateCode(this); |
1113 } | 1113 } |
1114 | 1114 |
1115 | 1115 |
| 1116 template <> |
| 1117 HValue* CodeStubGraphBuilder<ArrayShiftStub>::BuildCodeStub() { |
| 1118 HValue* receiver = GetParameter(ArrayShiftStub::kReceiver); |
| 1119 ElementsKind kind = casted_stub()->kind(); |
| 1120 |
| 1121 // We may use double registers for copying. |
| 1122 if (IsFastDoubleElementsKind(kind)) info()->MarkAsSavesCallerDoubles(); |
| 1123 |
| 1124 HValue* length = Add<HLoadNamedField>( |
| 1125 receiver, static_cast<HValue*>(NULL), |
| 1126 HObjectAccess::ForArrayLength(kind)); |
| 1127 |
| 1128 IfBuilder if_lengthiszero(this); |
| 1129 HValue* lengthiszero = if_lengthiszero.If<HCompareNumericAndBranch>( |
| 1130 length, graph()->GetConstant0(), Token::EQ); |
| 1131 if_lengthiszero.Then(); |
| 1132 { |
| 1133 Push(graph()->GetConstantUndefined()); |
| 1134 } |
| 1135 if_lengthiszero.Else(); |
| 1136 { |
| 1137 // Check if array length is below threshold. |
| 1138 IfBuilder if_inline(this); |
| 1139 if_inline.If<HCompareNumericAndBranch>( |
| 1140 length, Add<HConstant>(ArrayShiftStub::kInlineThreshold), Token::LTE); |
| 1141 if_inline.Then(); |
| 1142 if_inline.ElseDeopt("Array length exceeds threshold"); |
| 1143 if_inline.End(); |
| 1144 |
| 1145 // We cannot handle copy-on-write backing stores here. |
| 1146 HValue* elements = AddLoadElements(receiver); |
| 1147 if (IsFastSmiOrObjectElementsKind(kind)) { |
| 1148 Add<HCheckMaps>(elements, isolate()->factory()->fixed_array_map()); |
| 1149 } |
| 1150 |
| 1151 // Remember the result. |
| 1152 Push(AddElementAccess(elements, graph()->GetConstant0(), NULL, |
| 1153 lengthiszero, kind, LOAD)); |
| 1154 |
| 1155 // Compute the new length. |
| 1156 HValue* new_length = AddUncasted<HSub>(length, graph()->GetConstant1()); |
| 1157 new_length->ClearFlag(HValue::kCanOverflow); |
| 1158 |
| 1159 // Copy the remaining elements. |
| 1160 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); |
| 1161 { |
| 1162 HValue* new_key = loop.BeginBody( |
| 1163 graph()->GetConstant0(), new_length, Token::LT); |
| 1164 HValue* key = AddUncasted<HAdd>(new_key, graph()->GetConstant1()); |
| 1165 key->ClearFlag(HValue::kCanOverflow); |
| 1166 HValue* element = AddUncasted<HLoadKeyed>( |
| 1167 elements, key, lengthiszero, kind, ALLOW_RETURN_HOLE); |
| 1168 HStoreKeyed* store = Add<HStoreKeyed>(elements, new_key, element, kind); |
| 1169 store->SetFlag(HValue::kAllowUndefinedAsNaN); |
| 1170 } |
| 1171 loop.EndBody(); |
| 1172 |
| 1173 // Put a hole at the end. |
| 1174 HValue* hole = IsFastSmiOrObjectElementsKind(kind) |
| 1175 ? Add<HConstant>(isolate()->factory()->the_hole_value()) |
| 1176 : Add<HConstant>(FixedDoubleArray::hole_nan_as_double()); |
| 1177 if (IsFastSmiOrObjectElementsKind(kind)) kind = FAST_HOLEY_ELEMENTS; |
| 1178 Add<HStoreKeyed>(elements, new_length, hole, kind, INITIALIZING_STORE); |
| 1179 |
| 1180 // Remember new length. |
| 1181 Add<HStoreNamedField>( |
| 1182 receiver, HObjectAccess::ForArrayLength(kind), |
| 1183 new_length, STORE_TO_INITIALIZED_ENTRY); |
| 1184 } |
| 1185 if_lengthiszero.End(); |
| 1186 |
| 1187 return Pop(); |
| 1188 } |
| 1189 |
| 1190 |
| 1191 Handle<Code> ArrayShiftStub::GenerateCode() { |
| 1192 return DoGenerateCode(this); |
| 1193 } |
| 1194 |
| 1195 |
1116 void CodeStubGraphBuilderBase::BuildCheckAndInstallOptimizedCode( | 1196 void CodeStubGraphBuilderBase::BuildCheckAndInstallOptimizedCode( |
1117 HValue* js_function, | 1197 HValue* js_function, |
1118 HValue* native_context, | 1198 HValue* native_context, |
1119 IfBuilder* builder, | 1199 IfBuilder* builder, |
1120 HValue* optimized_map, | 1200 HValue* optimized_map, |
1121 HValue* map_index) { | 1201 HValue* map_index) { |
1122 HValue* osr_ast_id_none = Add<HConstant>(BailoutId::None().ToInt()); | 1202 HValue* osr_ast_id_none = Add<HConstant>(BailoutId::None().ToInt()); |
1123 HValue* context_slot = LoadFromOptimizedCodeMap( | 1203 HValue* context_slot = LoadFromOptimizedCodeMap( |
1124 optimized_map, map_index, SharedFunctionInfo::kContextOffset); | 1204 optimized_map, map_index, SharedFunctionInfo::kContextOffset); |
1125 HValue* osr_ast_slot = LoadFromOptimizedCodeMap( | 1205 HValue* osr_ast_slot = LoadFromOptimizedCodeMap( |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1404 return BuildRegExpConstructResult(length, index, input); | 1484 return BuildRegExpConstructResult(length, index, input); |
1405 } | 1485 } |
1406 | 1486 |
1407 | 1487 |
1408 Handle<Code> RegExpConstructResultStub::GenerateCode() { | 1488 Handle<Code> RegExpConstructResultStub::GenerateCode() { |
1409 return DoGenerateCode(this); | 1489 return DoGenerateCode(this); |
1410 } | 1490 } |
1411 | 1491 |
1412 | 1492 |
1413 } } // namespace v8::internal | 1493 } } // namespace v8::internal |
OLD | NEW |