| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/compiler/js-native-context-specialization.h" | 5 #include "src/compiler/js-native-context-specialization.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
| 10 #include "src/compiler/access-builder.h" | 10 #include "src/compiler/access-builder.h" |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 Node* receiver = NodeProperties::GetValueInput(node, 0); | 421 Node* receiver = NodeProperties::GetValueInput(node, 0); |
| 422 Node* effect = NodeProperties::GetEffectInput(node); | 422 Node* effect = NodeProperties::GetEffectInput(node); |
| 423 Node* control = NodeProperties::GetControlInput(node); | 423 Node* control = NodeProperties::GetControlInput(node); |
| 424 Node* frame_state = NodeProperties::FindFrameStateBefore(node); | 424 Node* frame_state = NodeProperties::FindFrameStateBefore(node); |
| 425 | 425 |
| 426 // Not much we can do if deoptimization support is disabled. | 426 // Not much we can do if deoptimization support is disabled. |
| 427 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); | 427 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); |
| 428 | 428 |
| 429 // TODO(bmeurer): Add support for non-standard stores. | 429 // TODO(bmeurer): Add support for non-standard stores. |
| 430 if (store_mode != STANDARD_STORE && | 430 if (store_mode != STANDARD_STORE && |
| 431 store_mode != STORE_NO_TRANSITION_HANDLE_COW && | |
| 432 store_mode != STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { | 431 store_mode != STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
| 433 return NoChange(); | 432 return NoChange(); |
| 434 } | 433 } |
| 435 | 434 |
| 436 // Retrieve the native context from the given {node}. | 435 // Retrieve the native context from the given {node}. |
| 437 Handle<Context> native_context; | 436 Handle<Context> native_context; |
| 438 if (!GetNativeContext(node).ToHandle(&native_context)) return NoChange(); | 437 if (!GetNativeContext(node).ToHandle(&native_context)) return NoChange(); |
| 439 | 438 |
| 440 // Compute element access infos for the receiver maps. | 439 // Compute element access infos for the receiver maps. |
| 441 AccessInfoFactory access_info_factory(dependencies(), native_context, | 440 AccessInfoFactory access_info_factory(dependencies(), native_context, |
| (...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 954 ElementsKind elements_kind = access_info.elements_kind(); | 953 ElementsKind elements_kind = access_info.elements_kind(); |
| 955 MapList const& receiver_maps = access_info.receiver_maps(); | 954 MapList const& receiver_maps = access_info.receiver_maps(); |
| 956 | 955 |
| 957 // Load the elements for the {receiver}. | 956 // Load the elements for the {receiver}. |
| 958 Node* elements = effect = graph()->NewNode( | 957 Node* elements = effect = graph()->NewNode( |
| 959 simplified()->LoadField(AccessBuilder::ForJSObjectElements()), receiver, | 958 simplified()->LoadField(AccessBuilder::ForJSObjectElements()), receiver, |
| 960 effect, control); | 959 effect, control); |
| 961 | 960 |
| 962 // Don't try to store to a copy-on-write backing store. | 961 // Don't try to store to a copy-on-write backing store. |
| 963 if (access_mode == AccessMode::kStore && | 962 if (access_mode == AccessMode::kStore && |
| 964 IsFastSmiOrObjectElementsKind(elements_kind) && | 963 IsFastSmiOrObjectElementsKind(elements_kind)) { |
| 965 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { | 964 effect = graph()->NewNode( |
| 966 effect = | 965 simplified()->CheckMaps(1), elements, |
| 967 graph()->NewNode(simplified()->CheckMaps(1), elements, | 966 jsgraph()->HeapConstant(factory()->fixed_array_map()), effect, control); |
| 968 jsgraph()->FixedArrayMapConstant(), effect, control); | |
| 969 } | 967 } |
| 970 | 968 |
| 971 if (IsFixedTypedArrayElementsKind(elements_kind)) { | 969 if (IsFixedTypedArrayElementsKind(elements_kind)) { |
| 972 // Load the {receiver}s length. | 970 // Load the {receiver}s length. |
| 973 Node* length = effect = graph()->NewNode( | 971 Node* length = effect = graph()->NewNode( |
| 974 simplified()->LoadField(AccessBuilder::ForJSTypedArrayLength()), | 972 simplified()->LoadField(AccessBuilder::ForJSTypedArrayLength()), |
| 975 receiver, effect, control); | 973 receiver, effect, control); |
| 976 | 974 |
| 977 // Check if the {receiver}s buffer was neutered. | 975 // Check if the {receiver}s buffer was neutered. |
| 978 Node* buffer = effect = graph()->NewNode( | 976 Node* buffer = effect = graph()->NewNode( |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1062 DCHECK_EQ(STANDARD_STORE, store_mode); | 1060 DCHECK_EQ(STANDARD_STORE, store_mode); |
| 1063 effect = graph()->NewNode( | 1061 effect = graph()->NewNode( |
| 1064 simplified()->StoreTypedElement(external_array_type), buffer, | 1062 simplified()->StoreTypedElement(external_array_type), buffer, |
| 1065 base_pointer, external_pointer, index, value, effect, control); | 1063 base_pointer, external_pointer, index, value, effect, control); |
| 1066 } | 1064 } |
| 1067 break; | 1065 break; |
| 1068 } | 1066 } |
| 1069 } | 1067 } |
| 1070 } else { | 1068 } else { |
| 1071 // TODO(turbofan): Add support for additional store modes. | 1069 // TODO(turbofan): Add support for additional store modes. |
| 1072 DCHECK(store_mode == STANDARD_STORE || | 1070 DCHECK_EQ(STANDARD_STORE, store_mode); |
| 1073 store_mode == STORE_NO_TRANSITION_HANDLE_COW); | |
| 1074 | 1071 |
| 1075 // Load the length of the {receiver}. | 1072 // Load the length of the {receiver}. |
| 1076 Node* length = effect = | 1073 Node* length = effect = |
| 1077 HasOnlyJSArrayMaps(receiver_maps) | 1074 HasOnlyJSArrayMaps(receiver_maps) |
| 1078 ? graph()->NewNode( | 1075 ? graph()->NewNode( |
| 1079 simplified()->LoadField( | 1076 simplified()->LoadField( |
| 1080 AccessBuilder::ForJSArrayLength(elements_kind)), | 1077 AccessBuilder::ForJSArrayLength(elements_kind)), |
| 1081 receiver, effect, control) | 1078 receiver, effect, control) |
| 1082 : graph()->NewNode( | 1079 : graph()->NewNode( |
| 1083 simplified()->LoadField(AccessBuilder::ForFixedArrayLength()), | 1080 simplified()->LoadField(AccessBuilder::ForFixedArrayLength()), |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1143 DCHECK_EQ(AccessMode::kStore, access_mode); | 1140 DCHECK_EQ(AccessMode::kStore, access_mode); |
| 1144 if (IsFastSmiElementsKind(elements_kind)) { | 1141 if (IsFastSmiElementsKind(elements_kind)) { |
| 1145 value = effect = graph()->NewNode(simplified()->CheckTaggedSigned(), | 1142 value = effect = graph()->NewNode(simplified()->CheckTaggedSigned(), |
| 1146 value, effect, control); | 1143 value, effect, control); |
| 1147 } else if (IsFastDoubleElementsKind(elements_kind)) { | 1144 } else if (IsFastDoubleElementsKind(elements_kind)) { |
| 1148 value = effect = graph()->NewNode(simplified()->CheckNumber(), value, | 1145 value = effect = graph()->NewNode(simplified()->CheckNumber(), value, |
| 1149 effect, control); | 1146 effect, control); |
| 1150 // Make sure we do not store signalling NaNs into double arrays. | 1147 // Make sure we do not store signalling NaNs into double arrays. |
| 1151 value = graph()->NewNode(simplified()->NumberSilenceNaN(), value); | 1148 value = graph()->NewNode(simplified()->NumberSilenceNaN(), value); |
| 1152 } | 1149 } |
| 1153 | |
| 1154 // Ensure that copy-on-write backing store is writable. | |
| 1155 if (IsFastSmiOrObjectElementsKind(elements_kind) && | |
| 1156 store_mode == STORE_NO_TRANSITION_HANDLE_COW) { | |
| 1157 elements = effect = | |
| 1158 graph()->NewNode(simplified()->EnsureWritableFastElements(), | |
| 1159 receiver, elements, effect, control); | |
| 1160 } | |
| 1161 | |
| 1162 // Perform the actual element access. | |
| 1163 effect = graph()->NewNode(simplified()->StoreElement(element_access), | 1150 effect = graph()->NewNode(simplified()->StoreElement(element_access), |
| 1164 elements, index, value, effect, control); | 1151 elements, index, value, effect, control); |
| 1165 } | 1152 } |
| 1166 } | 1153 } |
| 1167 | 1154 |
| 1168 return ValueEffectControl(value, effect, control); | 1155 return ValueEffectControl(value, effect, control); |
| 1169 } | 1156 } |
| 1170 | 1157 |
| 1171 Node* JSNativeContextSpecialization::BuildCheckMaps( | 1158 Node* JSNativeContextSpecialization::BuildCheckMaps( |
| 1172 Node* receiver, Node* effect, Node* control, | 1159 Node* receiver, Node* effect, Node* control, |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1396 } | 1383 } |
| 1397 | 1384 |
| 1398 | 1385 |
| 1399 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 1386 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
| 1400 return jsgraph()->simplified(); | 1387 return jsgraph()->simplified(); |
| 1401 } | 1388 } |
| 1402 | 1389 |
| 1403 } // namespace compiler | 1390 } // namespace compiler |
| 1404 } // namespace internal | 1391 } // namespace internal |
| 1405 } // namespace v8 | 1392 } // namespace v8 |
| OLD | NEW |