| 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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   118   // Check if {receiver} may be a number. |   118   // Check if {receiver} may be a number. | 
|   119   bool receiverissmi_possible = false; |   119   bool receiverissmi_possible = false; | 
|   120   for (PropertyAccessInfo const& access_info : access_infos) { |   120   for (PropertyAccessInfo const& access_info : access_infos) { | 
|   121     if (access_info.receiver_type()->Is(Type::Number())) { |   121     if (access_info.receiver_type()->Is(Type::Number())) { | 
|   122       receiverissmi_possible = true; |   122       receiverissmi_possible = true; | 
|   123       break; |   123       break; | 
|   124     } |   124     } | 
|   125   } |   125   } | 
|   126  |   126  | 
|   127   // Ensure that {receiver} is a heap object. |   127   // Ensure that {receiver} is a heap object. | 
|   128   Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), receiver); |  | 
|   129   Node* receiverissmi_control = nullptr; |   128   Node* receiverissmi_control = nullptr; | 
|   130   Node* receiverissmi_effect = effect; |   129   Node* receiverissmi_effect = effect; | 
|   131   if (receiverissmi_possible) { |   130   if (receiverissmi_possible) { | 
 |   131     Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), receiver); | 
|   132     Node* branch = graph()->NewNode(common()->Branch(), check, control); |   132     Node* branch = graph()->NewNode(common()->Branch(), check, control); | 
|   133     control = graph()->NewNode(common()->IfFalse(), branch); |   133     control = graph()->NewNode(common()->IfFalse(), branch); | 
|   134     receiverissmi_control = graph()->NewNode(common()->IfTrue(), branch); |   134     receiverissmi_control = graph()->NewNode(common()->IfTrue(), branch); | 
|   135     receiverissmi_effect = effect; |   135     receiverissmi_effect = effect; | 
|   136   } else { |   136   } else { | 
|   137     control = effect = graph()->NewNode(common()->DeoptimizeIf(), check, |   137     receiver = effect = graph()->NewNode(simplified()->CheckTaggedPointer(), | 
|   138                                         frame_state, effect, control); |   138                                          receiver, effect, control); | 
|   139   } |   139   } | 
|   140  |   140  | 
|   141   // Load the {receiver} map. The resulting effect is the dominating effect for |   141   // Load the {receiver} map. The resulting effect is the dominating effect for | 
|   142   // all (polymorphic) branches. |   142   // all (polymorphic) branches. | 
|   143   Node* receiver_map = effect = |   143   Node* receiver_map = effect = | 
|   144       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |   144       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), | 
|   145                        receiver, effect, control); |   145                        receiver, effect, control); | 
|   146  |   146  | 
|   147   // Generate code for the various different property access patterns. |   147   // Generate code for the various different property access patterns. | 
|   148   Node* fallthrough_control = control; |   148   Node* fallthrough_control = control; | 
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   281           this_control = this_effect = |   281           this_control = this_effect = | 
|   282               graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state, |   282               graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state, | 
|   283                                this_effect, this_control); |   283                                this_effect, this_control); | 
|   284           this_value = graph()->NewNode(simplified()->TypeGuard(Type::Number()), |   284           this_value = graph()->NewNode(simplified()->TypeGuard(Type::Number()), | 
|   285                                         this_value, this_control); |   285                                         this_value, this_control); | 
|   286  |   286  | 
|   287           if (!field_index.is_inobject() || field_index.is_hidden_field() || |   287           if (!field_index.is_inobject() || field_index.is_hidden_field() || | 
|   288               !FLAG_unbox_double_fields) { |   288               !FLAG_unbox_double_fields) { | 
|   289             if (access_info.HasTransitionMap()) { |   289             if (access_info.HasTransitionMap()) { | 
|   290               // Allocate a MutableHeapNumber for the new property. |   290               // Allocate a MutableHeapNumber for the new property. | 
|   291               this_effect = |   291               this_effect = graph()->NewNode( | 
|   292                   graph()->NewNode(common()->BeginRegion(), this_effect); |   292                   common()->BeginRegion(RegionObservability::kNotObservable), | 
 |   293                   this_effect); | 
|   293               Node* this_box = this_effect = |   294               Node* this_box = this_effect = | 
|   294                   graph()->NewNode(simplified()->Allocate(NOT_TENURED), |   295                   graph()->NewNode(simplified()->Allocate(NOT_TENURED), | 
|   295                                    jsgraph()->Constant(HeapNumber::kSize), |   296                                    jsgraph()->Constant(HeapNumber::kSize), | 
|   296                                    this_effect, this_control); |   297                                    this_effect, this_control); | 
|   297               this_effect = graph()->NewNode( |   298               this_effect = graph()->NewNode( | 
|   298                   simplified()->StoreField(AccessBuilder::ForMap()), this_box, |   299                   simplified()->StoreField(AccessBuilder::ForMap()), this_box, | 
|   299                   jsgraph()->HeapConstant(factory()->mutable_heap_number_map()), |   300                   jsgraph()->HeapConstant(factory()->mutable_heap_number_map()), | 
|   300                   this_effect, this_control); |   301                   this_effect, this_control); | 
|   301               this_effect = graph()->NewNode( |   302               this_effect = graph()->NewNode( | 
|   302                   simplified()->StoreField(AccessBuilder::ForHeapNumberValue()), |   303                   simplified()->StoreField(AccessBuilder::ForHeapNumberValue()), | 
|   303                   this_box, this_value, this_effect, this_control); |   304                   this_box, this_value, this_effect, this_control); | 
|   304               this_value = this_effect = graph()->NewNode( |   305               this_value = this_effect = graph()->NewNode( | 
|   305                   common()->FinishRegion(), this_box, this_effect); |   306                   common()->FinishRegion(), this_box, this_effect); | 
|   306  |   307  | 
|   307               field_access.type = Type::TaggedPointer(); |   308               field_access.type = Type::TaggedPointer(); | 
|   308             } else { |   309             } else { | 
|   309               // We just store directly to the MutableHeapNumber. |   310               // We just store directly to the MutableHeapNumber. | 
|   310               this_storage = this_effect = |   311               this_storage = this_effect = | 
|   311                   graph()->NewNode(simplified()->LoadField(field_access), |   312                   graph()->NewNode(simplified()->LoadField(field_access), | 
|   312                                    this_storage, this_effect, this_control); |   313                                    this_storage, this_effect, this_control); | 
|   313               field_access.offset = HeapNumber::kValueOffset; |   314               field_access.offset = HeapNumber::kValueOffset; | 
|   314               field_access.name = MaybeHandle<Name>(); |   315               field_access.name = MaybeHandle<Name>(); | 
|   315               field_access.machine_type = MachineType::Float64(); |   316               field_access.machine_type = MachineType::Float64(); | 
|   316             } |   317             } | 
|   317           } else { |   318           } else { | 
|   318             // Unboxed double field, we store directly to the field. |   319             // Unboxed double field, we store directly to the field. | 
|   319             field_access.machine_type = MachineType::Float64(); |   320             field_access.machine_type = MachineType::Float64(); | 
|   320           } |   321           } | 
|   321         } else if (field_type->Is(Type::TaggedSigned())) { |   322         } else if (field_type->Is(Type::TaggedSigned())) { | 
|   322           Node* check = |   323           this_value = this_effect = | 
|   323               graph()->NewNode(simplified()->ObjectIsSmi(), this_value); |   324               graph()->NewNode(simplified()->CheckTaggedSigned(), this_value, | 
|   324           this_control = this_effect = |  | 
|   325               graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state, |  | 
|   326                                this_effect, this_control); |   325                                this_effect, this_control); | 
|   327           this_value = |  | 
|   328               graph()->NewNode(simplified()->TypeGuard(type_cache_.kSmi), |  | 
|   329                                this_value, this_control); |  | 
|   330         } else if (field_type->Is(Type::TaggedPointer())) { |   326         } else if (field_type->Is(Type::TaggedPointer())) { | 
|   331           Node* check = |   327           this_value = this_effect = | 
|   332               graph()->NewNode(simplified()->ObjectIsSmi(), this_value); |   328               graph()->NewNode(simplified()->CheckTaggedPointer(), this_value, | 
|   333           this_control = this_effect = |  | 
|   334               graph()->NewNode(common()->DeoptimizeIf(), check, frame_state, |  | 
|   335                                this_effect, this_control); |   329                                this_effect, this_control); | 
|   336           if (field_type->NumClasses() == 1) { |   330           if (field_type->NumClasses() == 1) { | 
|   337             // Emit a map check for the value. |   331             // Emit a map check for the value. | 
|   338             Node* this_value_map = this_effect = graph()->NewNode( |   332             Node* this_value_map = this_effect = graph()->NewNode( | 
|   339                 simplified()->LoadField(AccessBuilder::ForMap()), this_value, |   333                 simplified()->LoadField(AccessBuilder::ForMap()), this_value, | 
|   340                 this_effect, this_control); |   334                 this_effect, this_control); | 
|   341             Node* check = graph()->NewNode( |   335             Node* check = graph()->NewNode( | 
|   342                 simplified()->ReferenceEqual(Type::Internal()), this_value_map, |   336                 simplified()->ReferenceEqual(Type::Internal()), this_value_map, | 
|   343                 jsgraph()->Constant(field_type->Classes().Current())); |   337                 jsgraph()->Constant(field_type->Classes().Current())); | 
|   344             this_control = this_effect = |   338             this_control = this_effect = | 
|   345                 graph()->NewNode(common()->DeoptimizeUnless(), check, |   339                 graph()->NewNode(common()->DeoptimizeUnless(), check, | 
|   346                                  frame_state, this_effect, this_control); |   340                                  frame_state, this_effect, this_control); | 
|   347           } else { |   341           } else { | 
|   348             DCHECK_EQ(0, field_type->NumClasses()); |   342             DCHECK_EQ(0, field_type->NumClasses()); | 
|   349           } |   343           } | 
|   350         } else { |   344         } else { | 
|   351           DCHECK(field_type->Is(Type::Tagged())); |   345           DCHECK(field_type->Is(Type::Tagged())); | 
|   352         } |   346         } | 
|   353         Handle<Map> transition_map; |   347         Handle<Map> transition_map; | 
|   354         if (access_info.transition_map().ToHandle(&transition_map)) { |   348         if (access_info.transition_map().ToHandle(&transition_map)) { | 
|   355           this_effect = graph()->NewNode(common()->BeginRegion(), this_effect); |   349           this_effect = graph()->NewNode( | 
 |   350               common()->BeginRegion(RegionObservability::kObservable), | 
 |   351               this_effect); | 
|   356           this_effect = graph()->NewNode( |   352           this_effect = graph()->NewNode( | 
|   357               simplified()->StoreField(AccessBuilder::ForMap()), this_receiver, |   353               simplified()->StoreField(AccessBuilder::ForMap()), this_receiver, | 
|   358               jsgraph()->Constant(transition_map), this_effect, this_control); |   354               jsgraph()->Constant(transition_map), this_effect, this_control); | 
|   359         } |   355         } | 
|   360         this_effect = graph()->NewNode(simplified()->StoreField(field_access), |   356         this_effect = graph()->NewNode(simplified()->StoreField(field_access), | 
|   361                                        this_storage, this_value, this_effect, |   357                                        this_storage, this_value, this_effect, | 
|   362                                        this_control); |   358                                        this_control); | 
|   363         if (access_info.HasTransitionMap()) { |   359         if (access_info.HasTransitionMap()) { | 
|   364           this_effect = |   360           this_effect = | 
|   365               graph()->NewNode(common()->FinishRegion(), |   361               graph()->NewNode(common()->FinishRegion(), | 
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   524   // Nothing to do if we have no non-deprecated maps. |   520   // Nothing to do if we have no non-deprecated maps. | 
|   525   if (access_infos.empty()) return NoChange(); |   521   if (access_infos.empty()) return NoChange(); | 
|   526  |   522  | 
|   527   // The final states for every polymorphic branch. We join them with |   523   // The final states for every polymorphic branch. We join them with | 
|   528   // Merge+Phi+EffectPhi at the bottom. |   524   // Merge+Phi+EffectPhi at the bottom. | 
|   529   ZoneVector<Node*> values(zone()); |   525   ZoneVector<Node*> values(zone()); | 
|   530   ZoneVector<Node*> effects(zone()); |   526   ZoneVector<Node*> effects(zone()); | 
|   531   ZoneVector<Node*> controls(zone()); |   527   ZoneVector<Node*> controls(zone()); | 
|   532  |   528  | 
|   533   // Ensure that {receiver} is a heap object. |   529   // Ensure that {receiver} is a heap object. | 
|   534   Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), receiver); |   530   receiver = effect = graph()->NewNode(simplified()->CheckTaggedPointer(), | 
|   535   control = effect = graph()->NewNode(common()->DeoptimizeIf(), check, |   531                                        receiver, effect, control); | 
|   536                                       frame_state, effect, control); |  | 
|   537  |   532  | 
|   538   // Load the {receiver} map. The resulting effect is the dominating effect for |   533   // Load the {receiver} map. The resulting effect is the dominating effect for | 
|   539   // all (polymorphic) branches. |   534   // all (polymorphic) branches. | 
|   540   Node* receiver_map = effect = |   535   Node* receiver_map = effect = | 
|   541       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |   536       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), | 
|   542                        receiver, effect, control); |   537                        receiver, effect, control); | 
|   543  |   538  | 
|   544   // Generate code for the various different element access patterns. |   539   // Generate code for the various different element access patterns. | 
|   545   Node* fallthrough_control = control; |   540   Node* fallthrough_control = control; | 
|   546   for (size_t j = 0; j < access_infos.size(); ++j) { |   541   for (size_t j = 0; j < access_infos.size(); ++j) { | 
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   778           // Return the signaling NaN hole directly if all uses are truncating. |   773           // Return the signaling NaN hole directly if all uses are truncating. | 
|   779           mode = CheckFloat64HoleMode::kAllowReturnHole; |   774           mode = CheckFloat64HoleMode::kAllowReturnHole; | 
|   780         } |   775         } | 
|   781         this_value = this_effect = |   776         this_value = this_effect = | 
|   782             graph()->NewNode(simplified()->CheckFloat64Hole(mode), this_value, |   777             graph()->NewNode(simplified()->CheckFloat64Hole(mode), this_value, | 
|   783                              this_effect, this_control); |   778                              this_effect, this_control); | 
|   784       } |   779       } | 
|   785     } else { |   780     } else { | 
|   786       DCHECK_EQ(AccessMode::kStore, access_mode); |   781       DCHECK_EQ(AccessMode::kStore, access_mode); | 
|   787       if (IsFastSmiElementsKind(elements_kind)) { |   782       if (IsFastSmiElementsKind(elements_kind)) { | 
|   788         Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), this_value); |   783         this_value = this_effect = | 
|   789         this_control = this_effect = |   784             graph()->NewNode(simplified()->CheckTaggedSigned(), this_value, | 
|   790             graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state, |  | 
|   791                              this_effect, this_control); |   785                              this_effect, this_control); | 
|   792         this_value = graph()->NewNode(simplified()->TypeGuard(type_cache_.kSmi), |  | 
|   793                                       this_value, this_control); |  | 
|   794       } else if (IsFastDoubleElementsKind(elements_kind)) { |   786       } else if (IsFastDoubleElementsKind(elements_kind)) { | 
|   795         Node* check = |   787         Node* check = | 
|   796             graph()->NewNode(simplified()->ObjectIsNumber(), this_value); |   788             graph()->NewNode(simplified()->ObjectIsNumber(), this_value); | 
|   797         this_control = this_effect = |   789         this_control = this_effect = | 
|   798             graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state, |   790             graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state, | 
|   799                              this_effect, this_control); |   791                              this_effect, this_control); | 
|   800         this_value = graph()->NewNode(simplified()->TypeGuard(Type::Number()), |   792         this_value = graph()->NewNode(simplified()->TypeGuard(Type::Number()), | 
|   801                                       this_value, this_control); |   793                                       this_value, this_control); | 
|   802         // Make sure we do not store signalling NaNs into holey double arrays. |   794         // Make sure we do not store signalling NaNs into holey double arrays. | 
|   803         if (elements_kind == FAST_HOLEY_DOUBLE_ELEMENTS) { |   795         if (elements_kind == FAST_HOLEY_DOUBLE_ELEMENTS) { | 
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1091 } |  1083 } | 
|  1092  |  1084  | 
|  1093  |  1085  | 
|  1094 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |  1086 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 
|  1095   return jsgraph()->simplified(); |  1087   return jsgraph()->simplified(); | 
|  1096 } |  1088 } | 
|  1097  |  1089  | 
|  1098 }  // namespace compiler |  1090 }  // namespace compiler | 
|  1099 }  // namespace internal |  1091 }  // namespace internal | 
|  1100 }  // namespace v8 |  1092 }  // namespace v8 | 
| OLD | NEW |