Chromium Code Reviews| 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 |