| 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 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 static GVNFlag ChangesFlagFromInt(int x) { | 559 static GVNFlag ChangesFlagFromInt(int x) { |
| 560 return static_cast<GVNFlag>(x * 2); | 560 return static_cast<GVNFlag>(x * 2); |
| 561 } | 561 } |
| 562 static GVNFlag DependsOnFlagFromInt(int x) { | 562 static GVNFlag DependsOnFlagFromInt(int x) { |
| 563 return static_cast<GVNFlag>(x * 2 + 1); | 563 return static_cast<GVNFlag>(x * 2 + 1); |
| 564 } | 564 } |
| 565 static GVNFlagSet ConvertChangesToDependsFlags(GVNFlagSet flags) { | 565 static GVNFlagSet ConvertChangesToDependsFlags(GVNFlagSet flags) { |
| 566 return GVNFlagSet(flags.ToIntegral() << kChangesToDependsFlagsLeftShift); | 566 return GVNFlagSet(flags.ToIntegral() << kChangesToDependsFlagsLeftShift); |
| 567 } | 567 } |
| 568 | 568 |
| 569 static GVNFlagSet ConvertDependsToChangesFlags(GVNFlagSet flags) { |
| 570 return GVNFlagSet(flags.ToIntegral() >> kChangesToDependsFlagsLeftShift); |
| 571 } |
| 572 |
| 569 static HValue* cast(HValue* value) { return value; } | 573 static HValue* cast(HValue* value) { return value; } |
| 570 | 574 |
| 571 enum Opcode { | 575 enum Opcode { |
| 572 // Declare a unique enum value for each hydrogen instruction. | 576 // Declare a unique enum value for each hydrogen instruction. |
| 573 #define DECLARE_OPCODE(type) k##type, | 577 #define DECLARE_OPCODE(type) k##type, |
| 574 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE) | 578 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE) |
| 575 kPhi | 579 kPhi |
| 576 #undef DECLARE_OPCODE | 580 #undef DECLARE_OPCODE |
| 577 }; | 581 }; |
| 578 virtual Opcode opcode() const = 0; | 582 virtual Opcode opcode() const = 0; |
| (...skipping 1499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2078 } | 2082 } |
| 2079 map_set()->Sort(); | 2083 map_set()->Sort(); |
| 2080 } | 2084 } |
| 2081 | 2085 |
| 2082 static HCheckMaps* NewWithTransitions(HValue* object, Handle<Map> map) { | 2086 static HCheckMaps* NewWithTransitions(HValue* object, Handle<Map> map) { |
| 2083 HCheckMaps* check_map = new HCheckMaps(object, map); | 2087 HCheckMaps* check_map = new HCheckMaps(object, map); |
| 2084 SmallMapList* map_set = check_map->map_set(); | 2088 SmallMapList* map_set = check_map->map_set(); |
| 2085 | 2089 |
| 2086 // If the map to check has the untransitioned elements, it can be hoisted | 2090 // If the map to check has the untransitioned elements, it can be hoisted |
| 2087 // above TransitionElements instructions. | 2091 // above TransitionElements instructions. |
| 2088 if (map->has_fast_smi_only_elements()) { | 2092 // if (map->has_fast_smi_elements()) { |
| 2089 check_map->ClearGVNFlag(kDependsOnElementsKind); | 2093 check_map->ClearGVNFlag(kDependsOnElementsKind); |
| 2090 } | 2094 // } |
| 2091 | 2095 |
| 2092 Map* transitioned_fast_element_map = | 2096 ElementsKind kind = map->elements_kind(); |
| 2093 map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL); | 2097 bool packed = IsFastPackedElementsKind(kind); |
| 2094 ASSERT(transitioned_fast_element_map == NULL || | 2098 while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) { |
| 2095 map->elements_kind() != FAST_ELEMENTS); | 2099 kind = GetNextMoreGeneralFastElementsKind(kind, packed); |
| 2096 if (transitioned_fast_element_map != NULL) { | 2100 Map* transitioned_map = |
| 2097 map_set->Add(Handle<Map>(transitioned_fast_element_map)); | 2101 map->LookupElementsTransitionMap(kind, NULL); |
| 2098 } | 2102 if (transitioned_map) { |
| 2099 Map* transitioned_double_map = | 2103 map_set->Add(Handle<Map>(transitioned_map)); |
| 2100 map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL); | 2104 } |
| 2101 ASSERT(transitioned_double_map == NULL || | 2105 }; |
| 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(); | 2106 map_set->Sort(); |
| 2107 | |
| 2108 return check_map; | 2107 return check_map; |
| 2109 } | 2108 } |
| 2110 | 2109 |
| 2111 virtual Representation RequiredInputRepresentation(int index) { | 2110 virtual Representation RequiredInputRepresentation(int index) { |
| 2112 return Representation::Tagged(); | 2111 return Representation::Tagged(); |
| 2113 } | 2112 } |
| 2114 virtual void PrintDataTo(StringStream* stream); | 2113 virtual void PrintDataTo(StringStream* stream); |
| 2115 virtual HType CalculateInferredType(); | 2114 virtual HType CalculateInferredType(); |
| 2116 | 2115 |
| 2117 HValue* value() { return OperandAt(0); } | 2116 HValue* value() { return OperandAt(0); } |
| (...skipping 1822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3940 return Representation::Tagged(); | 3939 return Representation::Tagged(); |
| 3941 } | 3940 } |
| 3942 | 3941 |
| 3943 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype) | 3942 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype) |
| 3944 | 3943 |
| 3945 protected: | 3944 protected: |
| 3946 virtual bool DataEquals(HValue* other) { return true; } | 3945 virtual bool DataEquals(HValue* other) { return true; } |
| 3947 }; | 3946 }; |
| 3948 | 3947 |
| 3949 | 3948 |
| 3949 enum HoleCheckMode { PERFORM_HOLE_CHECK, OMIT_HOLE_CHECK }; |
| 3950 |
| 3951 |
| 3950 class HLoadKeyedFastElement: public HTemplateInstruction<2> { | 3952 class HLoadKeyedFastElement: public HTemplateInstruction<2> { |
| 3951 public: | 3953 public: |
| 3952 enum HoleCheckMode { PERFORM_HOLE_CHECK, OMIT_HOLE_CHECK }; | |
| 3953 | |
| 3954 HLoadKeyedFastElement(HValue* obj, | 3954 HLoadKeyedFastElement(HValue* obj, |
| 3955 HValue* key, | 3955 HValue* key, |
| 3956 HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK) | 3956 HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK) |
| 3957 : hole_check_mode_(hole_check_mode) { | 3957 : hole_check_mode_(hole_check_mode) { |
| 3958 SetOperandAt(0, obj); | 3958 SetOperandAt(0, obj); |
| 3959 SetOperandAt(1, key); | 3959 SetOperandAt(1, key); |
| 3960 set_representation(Representation::Tagged()); | 3960 set_representation(Representation::Tagged()); |
| 3961 SetGVNFlag(kDependsOnArrayElements); | 3961 SetGVNFlag(kDependsOnArrayElements); |
| 3962 SetFlag(kUseGVN); | 3962 SetFlag(kUseGVN); |
| 3963 } | 3963 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 3985 return hole_check_mode_ == other_load->hole_check_mode_; | 3985 return hole_check_mode_ == other_load->hole_check_mode_; |
| 3986 } | 3986 } |
| 3987 | 3987 |
| 3988 private: | 3988 private: |
| 3989 HoleCheckMode hole_check_mode_; | 3989 HoleCheckMode hole_check_mode_; |
| 3990 }; | 3990 }; |
| 3991 | 3991 |
| 3992 | 3992 |
| 3993 class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> { | 3993 class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> { |
| 3994 public: | 3994 public: |
| 3995 HLoadKeyedFastDoubleElement(HValue* elements, HValue* key) { | 3995 HLoadKeyedFastDoubleElement( |
| 3996 HValue* elements, |
| 3997 HValue* key, |
| 3998 HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK) |
| 3999 : hole_check_mode_(hole_check_mode) { |
| 3996 SetOperandAt(0, elements); | 4000 SetOperandAt(0, elements); |
| 3997 SetOperandAt(1, key); | 4001 SetOperandAt(1, key); |
| 3998 set_representation(Representation::Double()); | 4002 set_representation(Representation::Double()); |
| 3999 SetGVNFlag(kDependsOnDoubleArrayElements); | 4003 SetGVNFlag(kDependsOnDoubleArrayElements); |
| 4000 SetFlag(kUseGVN); | 4004 SetFlag(kUseGVN); |
| 4001 } | 4005 } |
| 4002 | 4006 |
| 4003 HValue* elements() { return OperandAt(0); } | 4007 HValue* elements() { return OperandAt(0); } |
| 4004 HValue* key() { return OperandAt(1); } | 4008 HValue* key() { return OperandAt(1); } |
| 4005 | 4009 |
| 4006 virtual Representation RequiredInputRepresentation(int index) { | 4010 virtual Representation RequiredInputRepresentation(int index) { |
| 4007 // The key is supposed to be Integer32. | 4011 // The key is supposed to be Integer32. |
| 4008 return index == 0 | 4012 return index == 0 |
| 4009 ? Representation::Tagged() | 4013 ? Representation::Tagged() |
| 4010 : Representation::Integer32(); | 4014 : Representation::Integer32(); |
| 4011 } | 4015 } |
| 4012 | 4016 |
| 4017 bool RequiresHoleCheck() { |
| 4018 return hole_check_mode_ == PERFORM_HOLE_CHECK; |
| 4019 } |
| 4020 |
| 4013 virtual void PrintDataTo(StringStream* stream); | 4021 virtual void PrintDataTo(StringStream* stream); |
| 4014 | 4022 |
| 4015 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement) | 4023 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement) |
| 4016 | 4024 |
| 4017 protected: | 4025 protected: |
| 4018 virtual bool DataEquals(HValue* other) { return true; } | 4026 virtual bool DataEquals(HValue* other) { |
| 4027 if (!other->IsLoadKeyedFastElement()) return false; |
| 4028 HLoadKeyedFastDoubleElement* other_load = |
| 4029 HLoadKeyedFastDoubleElement::cast(other); |
| 4030 return hole_check_mode_ == other_load->hole_check_mode_; |
| 4031 } |
| 4032 |
| 4033 private: |
| 4034 HoleCheckMode hole_check_mode_; |
| 4019 }; | 4035 }; |
| 4020 | 4036 |
| 4021 | 4037 |
| 4022 class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> { | 4038 class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> { |
| 4023 public: | 4039 public: |
| 4024 HLoadKeyedSpecializedArrayElement(HValue* external_elements, | 4040 HLoadKeyedSpecializedArrayElement(HValue* external_elements, |
| 4025 HValue* key, | 4041 HValue* key, |
| 4026 ElementsKind elements_kind) | 4042 ElementsKind elements_kind) |
| 4027 : elements_kind_(elements_kind) { | 4043 : elements_kind_(elements_kind) { |
| 4028 SetOperandAt(0, external_elements); | 4044 SetOperandAt(0, external_elements); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4203 // The key is supposed to be Integer32. | 4219 // The key is supposed to be Integer32. |
| 4204 return index == 1 | 4220 return index == 1 |
| 4205 ? Representation::Integer32() | 4221 ? Representation::Integer32() |
| 4206 : Representation::Tagged(); | 4222 : Representation::Tagged(); |
| 4207 } | 4223 } |
| 4208 | 4224 |
| 4209 HValue* object() { return OperandAt(0); } | 4225 HValue* object() { return OperandAt(0); } |
| 4210 HValue* key() { return OperandAt(1); } | 4226 HValue* key() { return OperandAt(1); } |
| 4211 HValue* value() { return OperandAt(2); } | 4227 HValue* value() { return OperandAt(2); } |
| 4212 bool value_is_smi() { | 4228 bool value_is_smi() { |
| 4213 return elements_kind_ == FAST_SMI_ONLY_ELEMENTS; | 4229 return IsFastSmiElementsKind(elements_kind_); |
| 4214 } | 4230 } |
| 4215 | 4231 |
| 4216 bool NeedsWriteBarrier() { | 4232 bool NeedsWriteBarrier() { |
| 4217 if (value_is_smi()) { | 4233 if (value_is_smi()) { |
| 4218 return false; | 4234 return false; |
| 4219 } else { | 4235 } else { |
| 4220 return StoringValueNeedsWriteBarrier(value()); | 4236 return StoringValueNeedsWriteBarrier(value()); |
| 4221 } | 4237 } |
| 4222 } | 4238 } |
| 4223 | 4239 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4345 | 4361 |
| 4346 class HTransitionElementsKind: public HTemplateInstruction<1> { | 4362 class HTransitionElementsKind: public HTemplateInstruction<1> { |
| 4347 public: | 4363 public: |
| 4348 HTransitionElementsKind(HValue* object, | 4364 HTransitionElementsKind(HValue* object, |
| 4349 Handle<Map> original_map, | 4365 Handle<Map> original_map, |
| 4350 Handle<Map> transitioned_map) | 4366 Handle<Map> transitioned_map) |
| 4351 : original_map_(original_map), | 4367 : original_map_(original_map), |
| 4352 transitioned_map_(transitioned_map) { | 4368 transitioned_map_(transitioned_map) { |
| 4353 SetOperandAt(0, object); | 4369 SetOperandAt(0, object); |
| 4354 SetFlag(kUseGVN); | 4370 SetFlag(kUseGVN); |
| 4371 // Don't set GVN DependOn flags here, that defeats GVN detection of |
| 4372 // congruent HTransitionElementsKind instructions. DependsOn flags are |
| 4373 // considered explicitly during hoisting of HTransitionElementsKind |
| 4374 // instructions to prevent them from moving before instructions that change |
| 4375 // something they depend on. |
| 4355 SetGVNFlag(kChangesElementsKind); | 4376 SetGVNFlag(kChangesElementsKind); |
| 4356 SetGVNFlag(kChangesElementsPointer); | 4377 if (original_map->has_fast_double_elements()) { |
| 4357 SetGVNFlag(kChangesNewSpacePromotion); | 4378 SetGVNFlag(kChangesElementsPointer); |
| 4379 SetGVNFlag(kChangesNewSpacePromotion); |
| 4380 } |
| 4381 if (transitioned_map->has_fast_double_elements()) { |
| 4382 SetGVNFlag(kChangesElementsPointer); |
| 4383 SetGVNFlag(kChangesNewSpacePromotion); |
| 4384 } |
| 4358 set_representation(Representation::Tagged()); | 4385 set_representation(Representation::Tagged()); |
| 4359 } | 4386 } |
| 4360 | 4387 |
| 4361 virtual Representation RequiredInputRepresentation(int index) { | 4388 virtual Representation RequiredInputRepresentation(int index) { |
| 4362 return Representation::Tagged(); | 4389 return Representation::Tagged(); |
| 4363 } | 4390 } |
| 4364 | 4391 |
| 4365 HValue* object() { return OperandAt(0); } | 4392 HValue* object() { return OperandAt(0); } |
| 4366 Handle<Map> original_map() { return original_map_; } | 4393 Handle<Map> original_map() { return original_map_; } |
| 4367 Handle<Map> transitioned_map() { return transitioned_map_; } | 4394 Handle<Map> transitioned_map() { return transitioned_map_; } |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4585 : HMaterializedLiteral<1>(literal_index, depth), | 4612 : HMaterializedLiteral<1>(literal_index, depth), |
| 4586 length_(length), | 4613 length_(length), |
| 4587 boilerplate_object_(boilerplate_object) { | 4614 boilerplate_object_(boilerplate_object) { |
| 4588 SetOperandAt(0, context); | 4615 SetOperandAt(0, context); |
| 4589 SetGVNFlag(kChangesNewSpacePromotion); | 4616 SetGVNFlag(kChangesNewSpacePromotion); |
| 4590 } | 4617 } |
| 4591 | 4618 |
| 4592 HValue* context() { return OperandAt(0); } | 4619 HValue* context() { return OperandAt(0); } |
| 4593 ElementsKind boilerplate_elements_kind() const { | 4620 ElementsKind boilerplate_elements_kind() const { |
| 4594 if (!boilerplate_object_->IsJSObject()) { | 4621 if (!boilerplate_object_->IsJSObject()) { |
| 4595 return FAST_ELEMENTS; | 4622 return TERMINAL_FAST_ELEMENTS_KIND; |
| 4596 } | 4623 } |
| 4597 return Handle<JSObject>::cast(boilerplate_object_)->GetElementsKind(); | 4624 return Handle<JSObject>::cast(boilerplate_object_)->GetElementsKind(); |
| 4598 } | 4625 } |
| 4599 Handle<HeapObject> boilerplate_object() const { return boilerplate_object_; } | 4626 Handle<HeapObject> boilerplate_object() const { return boilerplate_object_; } |
| 4600 int length() const { return length_; } | 4627 int length() const { return length_; } |
| 4601 | 4628 |
| 4602 bool IsCopyOnWrite() const; | 4629 bool IsCopyOnWrite() const; |
| 4603 | 4630 |
| 4604 virtual Representation RequiredInputRepresentation(int index) { | 4631 virtual Representation RequiredInputRepresentation(int index) { |
| 4605 return Representation::Tagged(); | 4632 return Representation::Tagged(); |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4959 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); | 4986 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); |
| 4960 }; | 4987 }; |
| 4961 | 4988 |
| 4962 | 4989 |
| 4963 #undef DECLARE_INSTRUCTION | 4990 #undef DECLARE_INSTRUCTION |
| 4964 #undef DECLARE_CONCRETE_INSTRUCTION | 4991 #undef DECLARE_CONCRETE_INSTRUCTION |
| 4965 | 4992 |
| 4966 } } // namespace v8::internal | 4993 } } // namespace v8::internal |
| 4967 | 4994 |
| 4968 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 4995 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |