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 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 graph()->NewNode(simplified()->LoadField(field_access), | 298 graph()->NewNode(simplified()->LoadField(field_access), |
299 this_storage, this_effect, this_control); | 299 this_storage, this_effect, this_control); |
300 } else { | 300 } else { |
301 DCHECK_EQ(AccessMode::kStore, access_mode); | 301 DCHECK_EQ(AccessMode::kStore, access_mode); |
302 if (field_type->Is(Type::UntaggedFloat64())) { | 302 if (field_type->Is(Type::UntaggedFloat64())) { |
303 Node* check = | 303 Node* check = |
304 graph()->NewNode(simplified()->ObjectIsNumber(), this_value); | 304 graph()->NewNode(simplified()->ObjectIsNumber(), this_value); |
305 this_control = | 305 this_control = |
306 graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state, | 306 graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state, |
307 this_effect, this_control); | 307 this_effect, this_control); |
308 this_value = graph()->NewNode(common()->Guard(Type::Number()), | 308 this_value = graph()->NewNode(simplified()->TypeGuard(Type::Number()), |
309 this_value, this_control); | 309 this_value, this_control); |
310 | 310 |
311 if (!field_index.is_inobject() || field_index.is_hidden_field() || | 311 if (!field_index.is_inobject() || field_index.is_hidden_field() || |
312 !FLAG_unbox_double_fields) { | 312 !FLAG_unbox_double_fields) { |
313 if (access_info.HasTransitionMap()) { | 313 if (access_info.HasTransitionMap()) { |
314 // Allocate a MutableHeapNumber for the new property. | 314 // Allocate a MutableHeapNumber for the new property. |
315 this_effect = | 315 this_effect = |
316 graph()->NewNode(common()->BeginRegion(), this_effect); | 316 graph()->NewNode(common()->BeginRegion(), this_effect); |
317 Node* this_box = this_effect = | 317 Node* this_box = this_effect = |
318 graph()->NewNode(simplified()->Allocate(NOT_TENURED), | 318 graph()->NewNode(simplified()->Allocate(NOT_TENURED), |
(...skipping 22 matching lines...) Expand all Loading... |
341 } else { | 341 } else { |
342 // Unboxed double field, we store directly to the field. | 342 // Unboxed double field, we store directly to the field. |
343 field_access.machine_type = MachineType::Float64(); | 343 field_access.machine_type = MachineType::Float64(); |
344 } | 344 } |
345 } else if (field_type->Is(Type::TaggedSigned())) { | 345 } else if (field_type->Is(Type::TaggedSigned())) { |
346 Node* check = | 346 Node* check = |
347 graph()->NewNode(simplified()->ObjectIsSmi(), this_value); | 347 graph()->NewNode(simplified()->ObjectIsSmi(), this_value); |
348 this_control = | 348 this_control = |
349 graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state, | 349 graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state, |
350 this_effect, this_control); | 350 this_effect, this_control); |
351 this_value = graph()->NewNode(common()->Guard(type_cache_.kSmi), | 351 this_value = |
352 this_value, this_control); | 352 graph()->NewNode(simplified()->TypeGuard(type_cache_.kSmi), |
| 353 this_value, this_control); |
353 } else if (field_type->Is(Type::TaggedPointer())) { | 354 } else if (field_type->Is(Type::TaggedPointer())) { |
354 Node* check = | 355 Node* check = |
355 graph()->NewNode(simplified()->ObjectIsSmi(), this_value); | 356 graph()->NewNode(simplified()->ObjectIsSmi(), this_value); |
356 this_control = | 357 this_control = |
357 graph()->NewNode(common()->DeoptimizeIf(), check, frame_state, | 358 graph()->NewNode(common()->DeoptimizeIf(), check, frame_state, |
358 this_effect, this_control); | 359 this_effect, this_control); |
359 if (field_type->NumClasses() == 1) { | 360 if (field_type->NumClasses() == 1) { |
360 // Emit a map check for the value. | 361 // Emit a map check for the value. |
361 Node* this_value_map = this_effect = graph()->NewNode( | 362 Node* this_value_map = this_effect = graph()->NewNode( |
362 simplified()->LoadField(AccessBuilder::ForMap()), this_value, | 363 simplified()->LoadField(AccessBuilder::ForMap()), this_value, |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 if (access_info.holder().ToHandle(&holder)) { | 684 if (access_info.holder().ToHandle(&holder)) { |
684 AssumePrototypesStable(receiver_type, native_context, holder); | 685 AssumePrototypesStable(receiver_type, native_context, holder); |
685 } | 686 } |
686 | 687 |
687 // Check that the {index} is actually a Number. | 688 // Check that the {index} is actually a Number. |
688 if (!NumberMatcher(this_index).HasValue()) { | 689 if (!NumberMatcher(this_index).HasValue()) { |
689 Node* check = | 690 Node* check = |
690 graph()->NewNode(simplified()->ObjectIsNumber(), this_index); | 691 graph()->NewNode(simplified()->ObjectIsNumber(), this_index); |
691 this_control = graph()->NewNode(common()->DeoptimizeUnless(), check, | 692 this_control = graph()->NewNode(common()->DeoptimizeUnless(), check, |
692 frame_state, this_effect, this_control); | 693 frame_state, this_effect, this_control); |
693 this_index = graph()->NewNode(common()->Guard(Type::Number()), this_index, | 694 this_index = graph()->NewNode(simplified()->TypeGuard(Type::Number()), |
694 this_control); | 695 this_index, this_control); |
695 } | 696 } |
696 | 697 |
697 // Convert the {index} to an unsigned32 value and check if the result is | 698 // Convert the {index} to an unsigned32 value and check if the result is |
698 // equal to the original {index}. | 699 // equal to the original {index}. |
699 if (!NumberMatcher(this_index).IsInRange(0.0, kMaxUInt32)) { | 700 if (!NumberMatcher(this_index).IsInRange(0.0, kMaxUInt32)) { |
700 Node* this_index32 = | 701 Node* this_index32 = |
701 graph()->NewNode(simplified()->NumberToUint32(), this_index); | 702 graph()->NewNode(simplified()->NumberToUint32(), this_index); |
702 Node* check = graph()->NewNode(simplified()->NumberEqual(), this_index32, | 703 Node* check = graph()->NewNode(simplified()->NumberEqual(), this_index32, |
703 this_index); | 704 this_index); |
704 this_control = graph()->NewNode(common()->DeoptimizeUnless(), check, | 705 this_control = graph()->NewNode(common()->DeoptimizeUnless(), check, |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
806 element_type = | 807 element_type = |
807 Type::Union(element_type, Type::Undefined(), graph()->zone()); | 808 Type::Union(element_type, Type::Undefined(), graph()->zone()); |
808 } else { | 809 } else { |
809 // Deoptimize in case of the hole. | 810 // Deoptimize in case of the hole. |
810 this_control = | 811 this_control = |
811 graph()->NewNode(common()->DeoptimizeIf(), check, frame_state, | 812 graph()->NewNode(common()->DeoptimizeIf(), check, frame_state, |
812 this_effect, this_control); | 813 this_effect, this_control); |
813 } | 814 } |
814 // Rename the result to represent the actual type (not polluted by the | 815 // Rename the result to represent the actual type (not polluted by the |
815 // hole). | 816 // hole). |
816 this_value = graph()->NewNode(common()->Guard(element_type), this_value, | 817 this_value = graph()->NewNode(simplified()->TypeGuard(element_type), |
817 this_control); | 818 this_value, this_control); |
818 } else if (elements_kind == FAST_HOLEY_DOUBLE_ELEMENTS) { | 819 } else if (elements_kind == FAST_HOLEY_DOUBLE_ELEMENTS) { |
819 // Perform the hole check on the result. | 820 // Perform the hole check on the result. |
820 Node* check = | 821 Node* check = |
821 graph()->NewNode(simplified()->NumberIsHoleNaN(), this_value); | 822 graph()->NewNode(simplified()->NumberIsHoleNaN(), this_value); |
822 // Check if we are allowed to return the hole directly. | 823 // Check if we are allowed to return the hole directly. |
823 Type* initial_holey_array_type = Type::Class( | 824 Type* initial_holey_array_type = Type::Class( |
824 handle(isolate()->get_initial_js_array_map(elements_kind)), | 825 handle(isolate()->get_initial_js_array_map(elements_kind)), |
825 graph()->zone()); | 826 graph()->zone()); |
826 if (receiver_type->NowIs(initial_holey_array_type) && | 827 if (receiver_type->NowIs(initial_holey_array_type) && |
827 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { | 828 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { |
(...skipping 12 matching lines...) Expand all Loading... |
840 graph()->NewNode(common()->DeoptimizeIf(), check, frame_state, | 841 graph()->NewNode(common()->DeoptimizeIf(), check, frame_state, |
841 this_effect, this_control); | 842 this_effect, this_control); |
842 } | 843 } |
843 } | 844 } |
844 } else { | 845 } else { |
845 DCHECK_EQ(AccessMode::kStore, access_mode); | 846 DCHECK_EQ(AccessMode::kStore, access_mode); |
846 if (IsFastSmiElementsKind(elements_kind)) { | 847 if (IsFastSmiElementsKind(elements_kind)) { |
847 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), this_value); | 848 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), this_value); |
848 this_control = graph()->NewNode(common()->DeoptimizeUnless(), check, | 849 this_control = graph()->NewNode(common()->DeoptimizeUnless(), check, |
849 frame_state, this_effect, this_control); | 850 frame_state, this_effect, this_control); |
850 this_value = graph()->NewNode(common()->Guard(type_cache_.kSmi), | 851 this_value = graph()->NewNode(simplified()->TypeGuard(type_cache_.kSmi), |
851 this_value, this_control); | 852 this_value, this_control); |
852 } else if (IsFastDoubleElementsKind(elements_kind)) { | 853 } else if (IsFastDoubleElementsKind(elements_kind)) { |
853 Node* check = | 854 Node* check = |
854 graph()->NewNode(simplified()->ObjectIsNumber(), this_value); | 855 graph()->NewNode(simplified()->ObjectIsNumber(), this_value); |
855 this_control = graph()->NewNode(common()->DeoptimizeUnless(), check, | 856 this_control = graph()->NewNode(common()->DeoptimizeUnless(), check, |
856 frame_state, this_effect, this_control); | 857 frame_state, this_effect, this_control); |
857 this_value = graph()->NewNode(common()->Guard(Type::Number()), | 858 this_value = graph()->NewNode(simplified()->TypeGuard(Type::Number()), |
858 this_value, this_control); | 859 this_value, this_control); |
859 } | 860 } |
860 this_effect = graph()->NewNode(simplified()->StoreElement(element_access), | 861 this_effect = graph()->NewNode(simplified()->StoreElement(element_access), |
861 this_elements, this_index, this_value, | 862 this_elements, this_index, this_value, |
862 this_effect, this_control); | 863 this_effect, this_control); |
863 } | 864 } |
864 | 865 |
865 // Remember the final state for this element access. | 866 // Remember the final state for this element access. |
866 values.push_back(this_value); | 867 values.push_back(this_value); |
867 effects.push_back(this_effect); | 868 effects.push_back(this_effect); |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1143 } | 1144 } |
1144 | 1145 |
1145 | 1146 |
1146 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 1147 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
1147 return jsgraph()->simplified(); | 1148 return jsgraph()->simplified(); |
1148 } | 1149 } |
1149 | 1150 |
1150 } // namespace compiler | 1151 } // namespace compiler |
1151 } // namespace internal | 1152 } // namespace internal |
1152 } // namespace v8 | 1153 } // namespace v8 |
OLD | NEW |