| OLD | NEW | 
|     1 // Copyright 2012 the V8 project authors. All rights reserved. |     1 // Copyright 2012 the V8 project authors. All rights reserved. | 
|     2 // Redistribution and use in source and binary forms, with or without |     2 // Redistribution and use in source and binary forms, with or without | 
|     3 // modification, are permitted provided that the following conditions are |     3 // modification, are permitted provided that the following conditions are | 
|     4 // met: |     4 // met: | 
|     5 // |     5 // | 
|     6 //     * Redistributions of source code must retain the above copyright |     6 //     * Redistributions of source code must retain the above copyright | 
|     7 //       notice, this list of conditions and the following disclaimer. |     7 //       notice, this list of conditions and the following disclaimer. | 
|     8 //     * Redistributions in binary form must reproduce the above |     8 //     * Redistributions in binary form must reproduce the above | 
|     9 //       copyright notice, this list of conditions and the following |     9 //       copyright notice, this list of conditions and the following | 
|    10 //       disclaimer in the documentation and/or other materials provided |    10 //       disclaimer in the documentation and/or other materials provided | 
| (...skipping 2065 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2076     for (int i = 0; i < maps->length(); i++) { |  2076     for (int i = 0; i < maps->length(); i++) { | 
|  2077       map_set()->Add(maps->at(i)); |  2077       map_set()->Add(maps->at(i)); | 
|  2078     } |  2078     } | 
|  2079     map_set()->Sort(); |  2079     map_set()->Sort(); | 
|  2080   } |  2080   } | 
|  2081  |  2081  | 
|  2082   static HCheckMaps* NewWithTransitions(HValue* object, Handle<Map> map) { |  2082   static HCheckMaps* NewWithTransitions(HValue* object, Handle<Map> map) { | 
|  2083     HCheckMaps* check_map = new HCheckMaps(object, map); |  2083     HCheckMaps* check_map = new HCheckMaps(object, map); | 
|  2084     SmallMapList* map_set = check_map->map_set(); |  2084     SmallMapList* map_set = check_map->map_set(); | 
|  2085  |  2085  | 
|  2086     // If the map to check has the untransitioned elements, it can be hoisted |  2086     // Since transitioned elements maps of the initial map don't fail the map | 
|  2087     // above TransitionElements instructions. |  2087     // check, the CheckMaps instruction doesn't need to depend on ElementsKinds. | 
|  2088     if (map->has_fast_smi_only_elements()) { |  2088     check_map->ClearGVNFlag(kDependsOnElementsKind); | 
|  2089       check_map->ClearGVNFlag(kDependsOnElementsKind); |  | 
|  2090     } |  | 
|  2091  |  2089  | 
|  2092     Map* transitioned_fast_element_map = |  2090     ElementsKind kind = map->elements_kind(); | 
|  2093         map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL); |  2091     bool packed = IsFastPackedElementsKind(kind); | 
|  2094     ASSERT(transitioned_fast_element_map == NULL || |  2092     while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) { | 
|  2095            map->elements_kind() != FAST_ELEMENTS); |  2093       kind = GetNextMoreGeneralFastElementsKind(kind, packed); | 
|  2096     if (transitioned_fast_element_map != NULL) { |  2094       Map* transitioned_map = | 
|  2097       map_set->Add(Handle<Map>(transitioned_fast_element_map)); |  2095           map->LookupElementsTransitionMap(kind, NULL); | 
|  2098     } |  2096       if (transitioned_map) { | 
|  2099     Map* transitioned_double_map = |  2097         map_set->Add(Handle<Map>(transitioned_map)); | 
|  2100         map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL); |  2098       } | 
|  2101     ASSERT(transitioned_double_map == NULL || |  2099     }; | 
|  2102            map->elements_kind() == FAST_SMI_ONLY_ELEMENTS); |  | 
|  2103     if (transitioned_double_map != NULL) { |  | 
|  2104       map_set->Add(Handle<Map>(transitioned_double_map)); |  | 
|  2105     } |  | 
|  2106     map_set->Sort(); |  2100     map_set->Sort(); | 
|  2107  |  | 
|  2108     return check_map; |  2101     return check_map; | 
|  2109   } |  2102   } | 
|  2110  |  2103  | 
|  2111   virtual Representation RequiredInputRepresentation(int index) { |  2104   virtual Representation RequiredInputRepresentation(int index) { | 
|  2112     return Representation::Tagged(); |  2105     return Representation::Tagged(); | 
|  2113   } |  2106   } | 
|  2114   virtual void PrintDataTo(StringStream* stream); |  2107   virtual void PrintDataTo(StringStream* stream); | 
|  2115   virtual HType CalculateInferredType(); |  2108   virtual HType CalculateInferredType(); | 
|  2116  |  2109  | 
|  2117   HValue* value() { return OperandAt(0); } |  2110   HValue* value() { return OperandAt(0); } | 
| (...skipping 1831 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3949 class ArrayInstructionInterface { |  3942 class ArrayInstructionInterface { | 
|  3950  public: |  3943  public: | 
|  3951   virtual HValue* GetKey() = 0; |  3944   virtual HValue* GetKey() = 0; | 
|  3952   virtual void SetKey(HValue* key) = 0; |  3945   virtual void SetKey(HValue* key) = 0; | 
|  3953   virtual void SetIndexOffset(uint32_t index_offset) = 0; |  3946   virtual void SetIndexOffset(uint32_t index_offset) = 0; | 
|  3954   virtual bool IsDehoisted() = 0; |  3947   virtual bool IsDehoisted() = 0; | 
|  3955   virtual void SetDehoisted(bool is_dehoisted) = 0; |  3948   virtual void SetDehoisted(bool is_dehoisted) = 0; | 
|  3956   virtual ~ArrayInstructionInterface() { }; |  3949   virtual ~ArrayInstructionInterface() { }; | 
|  3957 }; |  3950 }; | 
|  3958  |  3951  | 
 |  3952  | 
 |  3953 enum HoleCheckMode { PERFORM_HOLE_CHECK, OMIT_HOLE_CHECK }; | 
 |  3954  | 
|  3959 class HLoadKeyedFastElement |  3955 class HLoadKeyedFastElement | 
|  3960     : public HTemplateInstruction<2>, public ArrayInstructionInterface { |  3956     : public HTemplateInstruction<2>, public ArrayInstructionInterface { | 
|  3961  public: |  3957  public: | 
|  3962   enum HoleCheckMode { PERFORM_HOLE_CHECK, OMIT_HOLE_CHECK }; |  | 
|  3963  |  | 
|  3964   HLoadKeyedFastElement(HValue* obj, |  3958   HLoadKeyedFastElement(HValue* obj, | 
|  3965                         HValue* key, |  3959                         HValue* key, | 
|  3966                         HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK) |  3960                         HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK) | 
|  3967       : hole_check_mode_(hole_check_mode), |  3961       : hole_check_mode_(hole_check_mode), | 
|  3968         index_offset_(0), |  3962         index_offset_(0), | 
|  3969         is_dehoisted_(false) { |  3963         is_dehoisted_(false) { | 
|  3970     SetOperandAt(0, obj); |  3964     SetOperandAt(0, obj); | 
|  3971     SetOperandAt(1, key); |  3965     SetOperandAt(1, key); | 
|  3972     set_representation(Representation::Tagged()); |  3966     set_representation(Representation::Tagged()); | 
|  3973     SetGVNFlag(kDependsOnArrayElements); |  3967     SetGVNFlag(kDependsOnArrayElements); | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4008  private: |  4002  private: | 
|  4009   HoleCheckMode hole_check_mode_; |  4003   HoleCheckMode hole_check_mode_; | 
|  4010   uint32_t index_offset_; |  4004   uint32_t index_offset_; | 
|  4011   bool is_dehoisted_; |  4005   bool is_dehoisted_; | 
|  4012 }; |  4006 }; | 
|  4013  |  4007  | 
|  4014  |  4008  | 
|  4015 class HLoadKeyedFastDoubleElement |  4009 class HLoadKeyedFastDoubleElement | 
|  4016     : public HTemplateInstruction<2>, public ArrayInstructionInterface { |  4010     : public HTemplateInstruction<2>, public ArrayInstructionInterface { | 
|  4017  public: |  4011  public: | 
|  4018   HLoadKeyedFastDoubleElement(HValue* elements, HValue* key) |  4012   HLoadKeyedFastDoubleElement( | 
|  4019       : index_offset_(0), is_dehoisted_(false) { |  4013     HValue* elements, | 
|  4020     SetOperandAt(0, elements); |  4014     HValue* key, | 
|  4021     SetOperandAt(1, key); |  4015     HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK) | 
|  4022     set_representation(Representation::Double()); |  4016     : index_offset_(0), | 
 |  4017       is_dehoisted_(false), | 
 |  4018       hole_check_mode_(hole_check_mode) { | 
 |  4019         SetOperandAt(0, elements); | 
 |  4020         SetOperandAt(1, key); | 
 |  4021         set_representation(Representation::Double()); | 
|  4023     SetGVNFlag(kDependsOnDoubleArrayElements); |  4022     SetGVNFlag(kDependsOnDoubleArrayElements); | 
|  4024     SetFlag(kUseGVN); |  4023     SetFlag(kUseGVN); | 
|  4025   } |  4024       } | 
|  4026  |  4025  | 
|  4027   HValue* elements() { return OperandAt(0); } |  4026   HValue* elements() { return OperandAt(0); } | 
|  4028   HValue* key() { return OperandAt(1); } |  4027   HValue* key() { return OperandAt(1); } | 
|  4029   uint32_t index_offset() { return index_offset_; } |  4028   uint32_t index_offset() { return index_offset_; } | 
|  4030   void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } |  4029   void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | 
|  4031   HValue* GetKey() { return key(); } |  4030   HValue* GetKey() { return key(); } | 
|  4032   void SetKey(HValue* key) { SetOperandAt(1, key); } |  4031   void SetKey(HValue* key) { SetOperandAt(1, key); } | 
|  4033   bool IsDehoisted() { return is_dehoisted_; } |  4032   bool IsDehoisted() { return is_dehoisted_; } | 
|  4034   void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } |  4033   void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | 
|  4035  |  4034  | 
|  4036   virtual Representation RequiredInputRepresentation(int index) { |  4035   virtual Representation RequiredInputRepresentation(int index) { | 
|  4037     // The key is supposed to be Integer32. |  4036     // The key is supposed to be Integer32. | 
|  4038     return index == 0 |  4037     return index == 0 | 
|  4039       ? Representation::Tagged() |  4038       ? Representation::Tagged() | 
|  4040       : Representation::Integer32(); |  4039       : Representation::Integer32(); | 
|  4041   } |  4040   } | 
|  4042  |  4041  | 
 |  4042   bool RequiresHoleCheck() { | 
 |  4043     return hole_check_mode_ == PERFORM_HOLE_CHECK; | 
 |  4044   } | 
 |  4045  | 
|  4043   virtual void PrintDataTo(StringStream* stream); |  4046   virtual void PrintDataTo(StringStream* stream); | 
|  4044  |  4047  | 
|  4045   DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement) |  4048   DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement) | 
|  4046  |  4049  | 
|  4047  protected: |  4050  protected: | 
|  4048   virtual bool DataEquals(HValue* other) { return true; } |  4051   virtual bool DataEquals(HValue* other) { | 
 |  4052     if (!other->IsLoadKeyedFastDoubleElement()) return false; | 
 |  4053     HLoadKeyedFastDoubleElement* other_load = | 
 |  4054         HLoadKeyedFastDoubleElement::cast(other); | 
 |  4055     return hole_check_mode_ == other_load->hole_check_mode_; | 
 |  4056   } | 
|  4049  |  4057  | 
|  4050  private: |  4058  private: | 
|  4051   uint32_t index_offset_; |  4059   uint32_t index_offset_; | 
|  4052   bool is_dehoisted_; |  4060   bool is_dehoisted_; | 
 |  4061   HoleCheckMode hole_check_mode_; | 
|  4053 }; |  4062 }; | 
|  4054  |  4063  | 
|  4055  |  4064  | 
|  4056 class HLoadKeyedSpecializedArrayElement |  4065 class HLoadKeyedSpecializedArrayElement | 
|  4057     : public HTemplateInstruction<2>, public ArrayInstructionInterface { |  4066     : public HTemplateInstruction<2>, public ArrayInstructionInterface { | 
|  4058  public: |  4067  public: | 
|  4059   HLoadKeyedSpecializedArrayElement(HValue* external_elements, |  4068   HLoadKeyedSpecializedArrayElement(HValue* external_elements, | 
|  4060                                     HValue* key, |  4069                                     HValue* key, | 
|  4061                                     ElementsKind elements_kind) |  4070                                     ElementsKind elements_kind) | 
|  4062       :  elements_kind_(elements_kind), |  4071       :  elements_kind_(elements_kind), | 
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4249     // The key is supposed to be Integer32. |  4258     // The key is supposed to be Integer32. | 
|  4250     return index == 1 |  4259     return index == 1 | 
|  4251         ? Representation::Integer32() |  4260         ? Representation::Integer32() | 
|  4252         : Representation::Tagged(); |  4261         : Representation::Tagged(); | 
|  4253   } |  4262   } | 
|  4254  |  4263  | 
|  4255   HValue* object() { return OperandAt(0); } |  4264   HValue* object() { return OperandAt(0); } | 
|  4256   HValue* key() { return OperandAt(1); } |  4265   HValue* key() { return OperandAt(1); } | 
|  4257   HValue* value() { return OperandAt(2); } |  4266   HValue* value() { return OperandAt(2); } | 
|  4258   bool value_is_smi() { |  4267   bool value_is_smi() { | 
|  4259     return elements_kind_ == FAST_SMI_ONLY_ELEMENTS; |  4268     return IsFastSmiElementsKind(elements_kind_); | 
|  4260   } |  4269   } | 
|  4261   uint32_t index_offset() { return index_offset_; } |  4270   uint32_t index_offset() { return index_offset_; } | 
|  4262   void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } |  4271   void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | 
|  4263   HValue* GetKey() { return key(); } |  4272   HValue* GetKey() { return key(); } | 
|  4264   void SetKey(HValue* key) { SetOperandAt(1, key); } |  4273   void SetKey(HValue* key) { SetOperandAt(1, key); } | 
|  4265   bool IsDehoisted() { return is_dehoisted_; } |  4274   bool IsDehoisted() { return is_dehoisted_; } | 
|  4266   void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } |  4275   void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | 
|  4267  |  4276  | 
|  4268   bool NeedsWriteBarrier() { |  4277   bool NeedsWriteBarrier() { | 
|  4269     if (value_is_smi()) { |  4278     if (value_is_smi()) { | 
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4420  |  4429  | 
|  4421 class HTransitionElementsKind: public HTemplateInstruction<1> { |  4430 class HTransitionElementsKind: public HTemplateInstruction<1> { | 
|  4422  public: |  4431  public: | 
|  4423   HTransitionElementsKind(HValue* object, |  4432   HTransitionElementsKind(HValue* object, | 
|  4424                           Handle<Map> original_map, |  4433                           Handle<Map> original_map, | 
|  4425                           Handle<Map> transitioned_map) |  4434                           Handle<Map> transitioned_map) | 
|  4426       : original_map_(original_map), |  4435       : original_map_(original_map), | 
|  4427         transitioned_map_(transitioned_map) { |  4436         transitioned_map_(transitioned_map) { | 
|  4428     SetOperandAt(0, object); |  4437     SetOperandAt(0, object); | 
|  4429     SetFlag(kUseGVN); |  4438     SetFlag(kUseGVN); | 
 |  4439     // Don't set GVN DependOn flags here. That would defeat GVN's detection of | 
 |  4440     // congruent HTransitionElementsKind instructions. Instruction hoisting | 
 |  4441     // handles HTransitionElementsKind instruction specially, explicitly adding | 
 |  4442     // DependsOn flags during its dependency calculations. | 
|  4430     SetGVNFlag(kChangesElementsKind); |  4443     SetGVNFlag(kChangesElementsKind); | 
|  4431     SetGVNFlag(kChangesElementsPointer); |  4444     if (original_map->has_fast_double_elements()) { | 
|  4432     SetGVNFlag(kChangesNewSpacePromotion); |  4445       SetGVNFlag(kChangesElementsPointer); | 
 |  4446       SetGVNFlag(kChangesNewSpacePromotion); | 
 |  4447     } | 
 |  4448     if (transitioned_map->has_fast_double_elements()) { | 
 |  4449       SetGVNFlag(kChangesElementsPointer); | 
 |  4450       SetGVNFlag(kChangesNewSpacePromotion); | 
 |  4451     } | 
|  4433     set_representation(Representation::Tagged()); |  4452     set_representation(Representation::Tagged()); | 
|  4434   } |  4453   } | 
|  4435  |  4454  | 
|  4436   virtual Representation RequiredInputRepresentation(int index) { |  4455   virtual Representation RequiredInputRepresentation(int index) { | 
|  4437     return Representation::Tagged(); |  4456     return Representation::Tagged(); | 
|  4438   } |  4457   } | 
|  4439  |  4458  | 
|  4440   HValue* object() { return OperandAt(0); } |  4459   HValue* object() { return OperandAt(0); } | 
|  4441   Handle<Map> original_map() { return original_map_; } |  4460   Handle<Map> original_map() { return original_map_; } | 
|  4442   Handle<Map> transitioned_map() { return transitioned_map_; } |  4461   Handle<Map> transitioned_map() { return transitioned_map_; } | 
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4660       : HMaterializedLiteral<1>(literal_index, depth), |  4679       : HMaterializedLiteral<1>(literal_index, depth), | 
|  4661         length_(length), |  4680         length_(length), | 
|  4662         boilerplate_object_(boilerplate_object) { |  4681         boilerplate_object_(boilerplate_object) { | 
|  4663     SetOperandAt(0, context); |  4682     SetOperandAt(0, context); | 
|  4664     SetGVNFlag(kChangesNewSpacePromotion); |  4683     SetGVNFlag(kChangesNewSpacePromotion); | 
|  4665   } |  4684   } | 
|  4666  |  4685  | 
|  4667   HValue* context() { return OperandAt(0); } |  4686   HValue* context() { return OperandAt(0); } | 
|  4668   ElementsKind boilerplate_elements_kind() const { |  4687   ElementsKind boilerplate_elements_kind() const { | 
|  4669     if (!boilerplate_object_->IsJSObject()) { |  4688     if (!boilerplate_object_->IsJSObject()) { | 
|  4670       return FAST_ELEMENTS; |  4689       return TERMINAL_FAST_ELEMENTS_KIND; | 
|  4671     } |  4690     } | 
|  4672     return Handle<JSObject>::cast(boilerplate_object_)->GetElementsKind(); |  4691     return Handle<JSObject>::cast(boilerplate_object_)->GetElementsKind(); | 
|  4673   } |  4692   } | 
|  4674   Handle<HeapObject> boilerplate_object() const { return boilerplate_object_; } |  4693   Handle<HeapObject> boilerplate_object() const { return boilerplate_object_; } | 
|  4675   int length() const { return length_; } |  4694   int length() const { return length_; } | 
|  4676  |  4695  | 
|  4677   bool IsCopyOnWrite() const; |  4696   bool IsCopyOnWrite() const; | 
|  4678  |  4697  | 
|  4679   virtual Representation RequiredInputRepresentation(int index) { |  4698   virtual Representation RequiredInputRepresentation(int index) { | 
|  4680     return Representation::Tagged(); |  4699     return Representation::Tagged(); | 
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5034   DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); |  5053   DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); | 
|  5035 }; |  5054 }; | 
|  5036  |  5055  | 
|  5037  |  5056  | 
|  5038 #undef DECLARE_INSTRUCTION |  5057 #undef DECLARE_INSTRUCTION | 
|  5039 #undef DECLARE_CONCRETE_INSTRUCTION |  5058 #undef DECLARE_CONCRETE_INSTRUCTION | 
|  5040  |  5059  | 
|  5041 } }  // namespace v8::internal |  5060 } }  // namespace v8::internal | 
|  5042  |  5061  | 
|  5043 #endif  // V8_HYDROGEN_INSTRUCTIONS_H_ |  5062 #endif  // V8_HYDROGEN_INSTRUCTIONS_H_ | 
| OLD | NEW |