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 1822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3940 return Representation::Tagged(); | 3933 return Representation::Tagged(); |
3941 } | 3934 } |
3942 | 3935 |
3943 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype) | 3936 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype) |
3944 | 3937 |
3945 protected: | 3938 protected: |
3946 virtual bool DataEquals(HValue* other) { return true; } | 3939 virtual bool DataEquals(HValue* other) { return true; } |
3947 }; | 3940 }; |
3948 | 3941 |
3949 | 3942 |
3943 enum HoleCheckMode { PERFORM_HOLE_CHECK, OMIT_HOLE_CHECK }; | |
3944 | |
3945 | |
3950 class HLoadKeyedFastElement: public HTemplateInstruction<2> { | 3946 class HLoadKeyedFastElement: public HTemplateInstruction<2> { |
3951 public: | 3947 public: |
3952 enum HoleCheckMode { PERFORM_HOLE_CHECK, OMIT_HOLE_CHECK }; | |
3953 | |
3954 HLoadKeyedFastElement(HValue* obj, | 3948 HLoadKeyedFastElement(HValue* obj, |
3955 HValue* key, | 3949 HValue* key, |
3956 HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK) | 3950 HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK) |
3957 : hole_check_mode_(hole_check_mode) { | 3951 : hole_check_mode_(hole_check_mode) { |
3958 SetOperandAt(0, obj); | 3952 SetOperandAt(0, obj); |
3959 SetOperandAt(1, key); | 3953 SetOperandAt(1, key); |
3960 set_representation(Representation::Tagged()); | 3954 set_representation(Representation::Tagged()); |
3961 SetGVNFlag(kDependsOnArrayElements); | 3955 SetGVNFlag(kDependsOnArrayElements); |
3962 SetFlag(kUseGVN); | 3956 SetFlag(kUseGVN); |
3963 } | 3957 } |
(...skipping 21 matching lines...) Expand all Loading... | |
3985 return hole_check_mode_ == other_load->hole_check_mode_; | 3979 return hole_check_mode_ == other_load->hole_check_mode_; |
3986 } | 3980 } |
3987 | 3981 |
3988 private: | 3982 private: |
3989 HoleCheckMode hole_check_mode_; | 3983 HoleCheckMode hole_check_mode_; |
3990 }; | 3984 }; |
3991 | 3985 |
3992 | 3986 |
3993 class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> { | 3987 class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> { |
3994 public: | 3988 public: |
3995 HLoadKeyedFastDoubleElement(HValue* elements, HValue* key) { | 3989 HLoadKeyedFastDoubleElement( |
3990 HValue* elements, | |
3991 HValue* key, | |
3992 HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK) | |
3993 : hole_check_mode_(hole_check_mode) { | |
3996 SetOperandAt(0, elements); | 3994 SetOperandAt(0, elements); |
3997 SetOperandAt(1, key); | 3995 SetOperandAt(1, key); |
3998 set_representation(Representation::Double()); | 3996 set_representation(Representation::Double()); |
3999 SetGVNFlag(kDependsOnDoubleArrayElements); | 3997 SetGVNFlag(kDependsOnDoubleArrayElements); |
4000 SetFlag(kUseGVN); | 3998 SetFlag(kUseGVN); |
4001 } | 3999 } |
4002 | 4000 |
4003 HValue* elements() { return OperandAt(0); } | 4001 HValue* elements() { return OperandAt(0); } |
4004 HValue* key() { return OperandAt(1); } | 4002 HValue* key() { return OperandAt(1); } |
4005 | 4003 |
4006 virtual Representation RequiredInputRepresentation(int index) { | 4004 virtual Representation RequiredInputRepresentation(int index) { |
4007 // The key is supposed to be Integer32. | 4005 // The key is supposed to be Integer32. |
4008 return index == 0 | 4006 return index == 0 |
4009 ? Representation::Tagged() | 4007 ? Representation::Tagged() |
4010 : Representation::Integer32(); | 4008 : Representation::Integer32(); |
4011 } | 4009 } |
4012 | 4010 |
4011 bool RequiresHoleCheck() { | |
4012 return hole_check_mode_ == PERFORM_HOLE_CHECK; | |
4013 } | |
4014 | |
4013 virtual void PrintDataTo(StringStream* stream); | 4015 virtual void PrintDataTo(StringStream* stream); |
4014 | 4016 |
4015 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement) | 4017 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement) |
4016 | 4018 |
4017 protected: | 4019 protected: |
4018 virtual bool DataEquals(HValue* other) { return true; } | 4020 virtual bool DataEquals(HValue* other) { |
4021 if (!other->IsLoadKeyedFastDoubleElement()) return false; | |
4022 HLoadKeyedFastDoubleElement* other_load = | |
4023 HLoadKeyedFastDoubleElement::cast(other); | |
4024 return hole_check_mode_ == other_load->hole_check_mode_; | |
4025 } | |
4026 | |
4027 private: | |
4028 HoleCheckMode hole_check_mode_; | |
4019 }; | 4029 }; |
4020 | 4030 |
4021 | 4031 |
4022 class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> { | 4032 class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> { |
4023 public: | 4033 public: |
4024 HLoadKeyedSpecializedArrayElement(HValue* external_elements, | 4034 HLoadKeyedSpecializedArrayElement(HValue* external_elements, |
4025 HValue* key, | 4035 HValue* key, |
4026 ElementsKind elements_kind) | 4036 ElementsKind elements_kind) |
4027 : elements_kind_(elements_kind) { | 4037 : elements_kind_(elements_kind) { |
4028 SetOperandAt(0, external_elements); | 4038 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. | 4213 // The key is supposed to be Integer32. |
4204 return index == 1 | 4214 return index == 1 |
4205 ? Representation::Integer32() | 4215 ? Representation::Integer32() |
4206 : Representation::Tagged(); | 4216 : Representation::Tagged(); |
4207 } | 4217 } |
4208 | 4218 |
4209 HValue* object() { return OperandAt(0); } | 4219 HValue* object() { return OperandAt(0); } |
4210 HValue* key() { return OperandAt(1); } | 4220 HValue* key() { return OperandAt(1); } |
4211 HValue* value() { return OperandAt(2); } | 4221 HValue* value() { return OperandAt(2); } |
4212 bool value_is_smi() { | 4222 bool value_is_smi() { |
4213 return elements_kind_ == FAST_SMI_ONLY_ELEMENTS; | 4223 return IsFastSmiElementsKind(elements_kind_); |
4214 } | 4224 } |
4215 | 4225 |
4216 bool NeedsWriteBarrier() { | 4226 bool NeedsWriteBarrier() { |
4217 if (value_is_smi()) { | 4227 if (value_is_smi()) { |
4218 return false; | 4228 return false; |
4219 } else { | 4229 } else { |
4220 return StoringValueNeedsWriteBarrier(value()); | 4230 return StoringValueNeedsWriteBarrier(value()); |
4221 } | 4231 } |
4222 } | 4232 } |
4223 | 4233 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4345 | 4355 |
4346 class HTransitionElementsKind: public HTemplateInstruction<1> { | 4356 class HTransitionElementsKind: public HTemplateInstruction<1> { |
4347 public: | 4357 public: |
4348 HTransitionElementsKind(HValue* object, | 4358 HTransitionElementsKind(HValue* object, |
4349 Handle<Map> original_map, | 4359 Handle<Map> original_map, |
4350 Handle<Map> transitioned_map) | 4360 Handle<Map> transitioned_map) |
4351 : original_map_(original_map), | 4361 : original_map_(original_map), |
4352 transitioned_map_(transitioned_map) { | 4362 transitioned_map_(transitioned_map) { |
4353 SetOperandAt(0, object); | 4363 SetOperandAt(0, object); |
4354 SetFlag(kUseGVN); | 4364 SetFlag(kUseGVN); |
4365 // Don't set GVN DependOn flags here. That would defeat GVN's detection of | |
4366 // congruent HTransitionElementsKind instructions. Instruction hoisting | |
4367 // handles HTransitionElementsKind instruction specially, explicitly adding | |
4368 // DependsOn flags during its dependency calculations. | |
4355 SetGVNFlag(kChangesElementsKind); | 4369 SetGVNFlag(kChangesElementsKind); |
4356 SetGVNFlag(kChangesElementsPointer); | 4370 if (original_map->has_fast_double_elements()) { |
Jakob Kummerow
2012/05/13 21:55:27
The bodies of these two if-blocks are the same; I'
danno
2012/05/22 11:05:21
Done.
| |
4357 SetGVNFlag(kChangesNewSpacePromotion); | 4371 SetGVNFlag(kChangesElementsPointer); |
4372 SetGVNFlag(kChangesNewSpacePromotion); | |
4373 } | |
4374 if (transitioned_map->has_fast_double_elements()) { | |
4375 SetGVNFlag(kChangesElementsPointer); | |
4376 SetGVNFlag(kChangesNewSpacePromotion); | |
4377 } | |
4358 set_representation(Representation::Tagged()); | 4378 set_representation(Representation::Tagged()); |
4359 } | 4379 } |
4360 | 4380 |
4361 virtual Representation RequiredInputRepresentation(int index) { | 4381 virtual Representation RequiredInputRepresentation(int index) { |
4362 return Representation::Tagged(); | 4382 return Representation::Tagged(); |
4363 } | 4383 } |
4364 | 4384 |
4365 HValue* object() { return OperandAt(0); } | 4385 HValue* object() { return OperandAt(0); } |
4366 Handle<Map> original_map() { return original_map_; } | 4386 Handle<Map> original_map() { return original_map_; } |
4367 Handle<Map> transitioned_map() { return transitioned_map_; } | 4387 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), | 4605 : HMaterializedLiteral<1>(literal_index, depth), |
4586 length_(length), | 4606 length_(length), |
4587 boilerplate_object_(boilerplate_object) { | 4607 boilerplate_object_(boilerplate_object) { |
4588 SetOperandAt(0, context); | 4608 SetOperandAt(0, context); |
4589 SetGVNFlag(kChangesNewSpacePromotion); | 4609 SetGVNFlag(kChangesNewSpacePromotion); |
4590 } | 4610 } |
4591 | 4611 |
4592 HValue* context() { return OperandAt(0); } | 4612 HValue* context() { return OperandAt(0); } |
4593 ElementsKind boilerplate_elements_kind() const { | 4613 ElementsKind boilerplate_elements_kind() const { |
4594 if (!boilerplate_object_->IsJSObject()) { | 4614 if (!boilerplate_object_->IsJSObject()) { |
4595 return FAST_ELEMENTS; | 4615 return TERMINAL_FAST_ELEMENTS_KIND; |
4596 } | 4616 } |
4597 return Handle<JSObject>::cast(boilerplate_object_)->GetElementsKind(); | 4617 return Handle<JSObject>::cast(boilerplate_object_)->GetElementsKind(); |
4598 } | 4618 } |
4599 Handle<HeapObject> boilerplate_object() const { return boilerplate_object_; } | 4619 Handle<HeapObject> boilerplate_object() const { return boilerplate_object_; } |
4600 int length() const { return length_; } | 4620 int length() const { return length_; } |
4601 | 4621 |
4602 bool IsCopyOnWrite() const; | 4622 bool IsCopyOnWrite() const; |
4603 | 4623 |
4604 virtual Representation RequiredInputRepresentation(int index) { | 4624 virtual Representation RequiredInputRepresentation(int index) { |
4605 return Representation::Tagged(); | 4625 return Representation::Tagged(); |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4959 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); | 4979 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); |
4960 }; | 4980 }; |
4961 | 4981 |
4962 | 4982 |
4963 #undef DECLARE_INSTRUCTION | 4983 #undef DECLARE_INSTRUCTION |
4964 #undef DECLARE_CONCRETE_INSTRUCTION | 4984 #undef DECLARE_CONCRETE_INSTRUCTION |
4965 | 4985 |
4966 } } // namespace v8::internal | 4986 } } // namespace v8::internal |
4967 | 4987 |
4968 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 4988 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |