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