Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/hydrogen-instructions.h

Issue 10802038: Add dependency to HLoadKeyed* instructions to prevent invalid hoisting (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix bugs Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 4009 matching lines...) Expand 10 before | Expand all | Expand 10 after
4020 public: 4020 public:
4021 virtual HValue* GetKey() = 0; 4021 virtual HValue* GetKey() = 0;
4022 virtual void SetKey(HValue* key) = 0; 4022 virtual void SetKey(HValue* key) = 0;
4023 virtual void SetIndexOffset(uint32_t index_offset) = 0; 4023 virtual void SetIndexOffset(uint32_t index_offset) = 0;
4024 virtual bool IsDehoisted() = 0; 4024 virtual bool IsDehoisted() = 0;
4025 virtual void SetDehoisted(bool is_dehoisted) = 0; 4025 virtual void SetDehoisted(bool is_dehoisted) = 0;
4026 virtual ~ArrayInstructionInterface() { }; 4026 virtual ~ArrayInstructionInterface() { };
4027 }; 4027 };
4028 4028
4029 class HLoadKeyedFastElement 4029 class HLoadKeyedFastElement
4030 : public HTemplateInstruction<2>, public ArrayInstructionInterface { 4030 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
4031 public: 4031 public:
4032 HLoadKeyedFastElement(HValue* obj, 4032 HLoadKeyedFastElement(HValue* obj,
4033 HValue* key, 4033 HValue* key,
4034 HValue* dependency,
4034 ElementsKind elements_kind = FAST_ELEMENTS) 4035 ElementsKind elements_kind = FAST_ELEMENTS)
4035 : bit_field_(0) { 4036 : bit_field_(0) {
4036 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind)); 4037 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind));
4037 bit_field_ = ElementsKindField::encode(elements_kind); 4038 bit_field_ = ElementsKindField::encode(elements_kind);
4038 if (IsFastSmiElementsKind(elements_kind) && 4039 if (IsFastSmiElementsKind(elements_kind) &&
4039 IsFastPackedElementsKind(elements_kind)) { 4040 IsFastPackedElementsKind(elements_kind)) {
4040 set_type(HType::Smi()); 4041 set_type(HType::Smi());
4041 } 4042 }
4042 SetOperandAt(0, obj); 4043 SetOperandAt(0, obj);
4043 SetOperandAt(1, key); 4044 SetOperandAt(1, key);
4045 SetOperandAt(2, dependency);
4044 set_representation(Representation::Tagged()); 4046 set_representation(Representation::Tagged());
4045 SetGVNFlag(kDependsOnArrayElements); 4047 SetGVNFlag(kDependsOnArrayElements);
4046 SetFlag(kUseGVN); 4048 SetFlag(kUseGVN);
4047 } 4049 }
4048 4050
4049 HValue* object() { return OperandAt(0); } 4051 HValue* object() { return OperandAt(0); }
4050 HValue* key() { return OperandAt(1); } 4052 HValue* key() { return OperandAt(1); }
4053 HValue* dependency() { return OperandAt(2); }
4051 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); } 4054 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); }
4052 void SetIndexOffset(uint32_t index_offset) { 4055 void SetIndexOffset(uint32_t index_offset) {
4053 bit_field_ = IndexOffsetField::update(bit_field_, index_offset); 4056 bit_field_ = IndexOffsetField::update(bit_field_, index_offset);
4054 } 4057 }
4055 HValue* GetKey() { return key(); } 4058 HValue* GetKey() { return key(); }
4056 void SetKey(HValue* key) { SetOperandAt(1, key); } 4059 void SetKey(HValue* key) { SetOperandAt(1, key); }
4057 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } 4060 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); }
4058 void SetDehoisted(bool is_dehoisted) { 4061 void SetDehoisted(bool is_dehoisted) {
4059 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); 4062 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted);
4060 } 4063 }
4061 ElementsKind elements_kind() const { 4064 ElementsKind elements_kind() const {
4062 return ElementsKindField::decode(bit_field_); 4065 return ElementsKindField::decode(bit_field_);
4063 } 4066 }
4064 4067
4065 virtual Representation RequiredInputRepresentation(int index) { 4068 virtual Representation RequiredInputRepresentation(int index) {
4066 // The key is supposed to be Integer32. 4069 // The key is supposed to be Integer32.
4067 return index == 0 4070 if (index == 0) return Representation::Tagged();
4068 ? Representation::Tagged() 4071 if (index == 1) return Representation::Integer32();
4069 : Representation::Integer32(); 4072 return Representation::None();
4070 } 4073 }
4071 4074
4072 virtual void PrintDataTo(StringStream* stream); 4075 virtual void PrintDataTo(StringStream* stream);
4073 4076
4074 bool RequiresHoleCheck(); 4077 bool RequiresHoleCheck();
4075 4078
4076 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement) 4079 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
4077 4080
4078 protected: 4081 protected:
4079 virtual bool DataEquals(HValue* other) { 4082 virtual bool DataEquals(HValue* other) {
4080 if (!other->IsLoadKeyedFastElement()) return false; 4083 if (!other->IsLoadKeyedFastElement()) return false;
4081 HLoadKeyedFastElement* other_load = HLoadKeyedFastElement::cast(other); 4084 HLoadKeyedFastElement* other_load = HLoadKeyedFastElement::cast(other);
4082 if (IsDehoisted() && index_offset() != other_load->index_offset()) 4085 if (IsDehoisted() && index_offset() != other_load->index_offset())
4083 return false; 4086 return false;
4084 return elements_kind() == other_load->elements_kind(); 4087 return elements_kind() == other_load->elements_kind();
4085 } 4088 }
4086 4089
4087 private: 4090 private:
4088 class ElementsKindField: public BitField<ElementsKind, 0, 4> {}; 4091 class ElementsKindField: public BitField<ElementsKind, 0, 4> {};
4089 class IndexOffsetField: public BitField<uint32_t, 4, 27> {}; 4092 class IndexOffsetField: public BitField<uint32_t, 4, 27> {};
4090 class IsDehoistedField: public BitField<bool, 31, 1> {}; 4093 class IsDehoistedField: public BitField<bool, 31, 1> {};
4091 uint32_t bit_field_; 4094 uint32_t bit_field_;
4092 }; 4095 };
4093 4096
4094 4097
4095 enum HoleCheckMode { PERFORM_HOLE_CHECK, OMIT_HOLE_CHECK }; 4098 enum HoleCheckMode { PERFORM_HOLE_CHECK, OMIT_HOLE_CHECK };
4096 4099
4097 4100
4098 class HLoadKeyedFastDoubleElement 4101 class HLoadKeyedFastDoubleElement
4099 : public HTemplateInstruction<2>, public ArrayInstructionInterface { 4102 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
4100 public: 4103 public:
4101 HLoadKeyedFastDoubleElement( 4104 HLoadKeyedFastDoubleElement(
4102 HValue* elements, 4105 HValue* elements,
4103 HValue* key, 4106 HValue* key,
4107 HValue* dependency,
4104 HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK) 4108 HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK)
4105 : index_offset_(0), 4109 : index_offset_(0),
4106 is_dehoisted_(false), 4110 is_dehoisted_(false),
4107 hole_check_mode_(hole_check_mode) { 4111 hole_check_mode_(hole_check_mode) {
4108 SetOperandAt(0, elements); 4112 SetOperandAt(0, elements);
4109 SetOperandAt(1, key); 4113 SetOperandAt(1, key);
4114 SetOperandAt(2, dependency);
4110 set_representation(Representation::Double()); 4115 set_representation(Representation::Double());
4111 SetGVNFlag(kDependsOnDoubleArrayElements); 4116 SetGVNFlag(kDependsOnDoubleArrayElements);
4112 SetFlag(kUseGVN); 4117 SetFlag(kUseGVN);
4113 } 4118 }
4114 4119
4115 HValue* elements() { return OperandAt(0); } 4120 HValue* elements() { return OperandAt(0); }
4116 HValue* key() { return OperandAt(1); } 4121 HValue* key() { return OperandAt(1); }
4122 HValue* dependency() { return OperandAt(2); }
4117 uint32_t index_offset() { return index_offset_; } 4123 uint32_t index_offset() { return index_offset_; }
4118 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } 4124 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4119 HValue* GetKey() { return key(); } 4125 HValue* GetKey() { return key(); }
4120 void SetKey(HValue* key) { SetOperandAt(1, key); } 4126 void SetKey(HValue* key) { SetOperandAt(1, key); }
4121 bool IsDehoisted() { return is_dehoisted_; } 4127 bool IsDehoisted() { return is_dehoisted_; }
4122 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } 4128 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
4123 4129
4124 virtual Representation RequiredInputRepresentation(int index) { 4130 virtual Representation RequiredInputRepresentation(int index) {
4125 // The key is supposed to be Integer32. 4131 // The key is supposed to be Integer32.
4126 return index == 0 4132 if (index == 0) return Representation::Tagged();
4127 ? Representation::Tagged() 4133 if (index == 1) return Representation::Integer32();
4128 : Representation::Integer32(); 4134 return Representation::None();
4129 } 4135 }
4130 4136
4131 bool RequiresHoleCheck() { 4137 bool RequiresHoleCheck() {
4132 return hole_check_mode_ == PERFORM_HOLE_CHECK; 4138 return hole_check_mode_ == PERFORM_HOLE_CHECK;
4133 } 4139 }
4134 4140
4135 virtual void PrintDataTo(StringStream* stream); 4141 virtual void PrintDataTo(StringStream* stream);
4136 4142
4137 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement) 4143 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement)
4138 4144
4139 protected: 4145 protected:
4140 virtual bool DataEquals(HValue* other) { 4146 virtual bool DataEquals(HValue* other) {
4141 if (!other->IsLoadKeyedFastDoubleElement()) return false; 4147 if (!other->IsLoadKeyedFastDoubleElement()) return false;
4142 HLoadKeyedFastDoubleElement* other_load = 4148 HLoadKeyedFastDoubleElement* other_load =
4143 HLoadKeyedFastDoubleElement::cast(other); 4149 HLoadKeyedFastDoubleElement::cast(other);
4144 return hole_check_mode_ == other_load->hole_check_mode_; 4150 return hole_check_mode_ == other_load->hole_check_mode_;
4145 } 4151 }
4146 4152
4147 private: 4153 private:
4148 uint32_t index_offset_; 4154 uint32_t index_offset_;
4149 bool is_dehoisted_; 4155 bool is_dehoisted_;
4150 HoleCheckMode hole_check_mode_; 4156 HoleCheckMode hole_check_mode_;
4151 }; 4157 };
4152 4158
4153 4159
4154 class HLoadKeyedSpecializedArrayElement 4160 class HLoadKeyedSpecializedArrayElement
4155 : public HTemplateInstruction<2>, public ArrayInstructionInterface { 4161 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
4156 public: 4162 public:
4157 HLoadKeyedSpecializedArrayElement(HValue* external_elements, 4163 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
4158 HValue* key, 4164 HValue* key,
4165 HValue* dependency,
4159 ElementsKind elements_kind) 4166 ElementsKind elements_kind)
4160 : elements_kind_(elements_kind), 4167 : elements_kind_(elements_kind),
4161 index_offset_(0), 4168 index_offset_(0),
4162 is_dehoisted_(false) { 4169 is_dehoisted_(false) {
4163 SetOperandAt(0, external_elements); 4170 SetOperandAt(0, external_elements);
4164 SetOperandAt(1, key); 4171 SetOperandAt(1, key);
4172 SetOperandAt(2, dependency);
4165 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 4173 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
4166 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 4174 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
4167 set_representation(Representation::Double()); 4175 set_representation(Representation::Double());
4168 } else { 4176 } else {
4169 set_representation(Representation::Integer32()); 4177 set_representation(Representation::Integer32());
4170 } 4178 }
4171 SetGVNFlag(kDependsOnSpecializedArrayElements); 4179 SetGVNFlag(kDependsOnSpecializedArrayElements);
4172 // Native code could change the specialized array. 4180 // Native code could change the specialized array.
4173 SetGVNFlag(kDependsOnCalls); 4181 SetGVNFlag(kDependsOnCalls);
4174 SetFlag(kUseGVN); 4182 SetFlag(kUseGVN);
4175 } 4183 }
4176 4184
4177 virtual void PrintDataTo(StringStream* stream); 4185 virtual void PrintDataTo(StringStream* stream);
4178 4186
4179 virtual Representation RequiredInputRepresentation(int index) { 4187 virtual Representation RequiredInputRepresentation(int index) {
4180 // The key is supposed to be Integer32, but the base pointer 4188 // The key is supposed to be Integer32.
4181 // for the element load is a naked pointer. 4189 if (index == 0) return Representation::External();
4182 return index == 0 4190 if (index == 1) return Representation::Integer32();
4183 ? Representation::External() 4191 return Representation::None();
4184 : Representation::Integer32();
4185 } 4192 }
4186 4193
4187 HValue* external_pointer() { return OperandAt(0); } 4194 HValue* external_pointer() { return OperandAt(0); }
4188 HValue* key() { return OperandAt(1); } 4195 HValue* key() { return OperandAt(1); }
4196 HValue* dependency() { return OperandAt(2); }
4189 ElementsKind elements_kind() const { return elements_kind_; } 4197 ElementsKind elements_kind() const { return elements_kind_; }
4190 uint32_t index_offset() { return index_offset_; } 4198 uint32_t index_offset() { return index_offset_; }
4191 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } 4199 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4192 HValue* GetKey() { return key(); } 4200 HValue* GetKey() { return key(); }
4193 void SetKey(HValue* key) { SetOperandAt(1, key); } 4201 void SetKey(HValue* key) { SetOperandAt(1, key); }
4194 bool IsDehoisted() { return is_dehoisted_; } 4202 bool IsDehoisted() { return is_dehoisted_; }
4195 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } 4203 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
4196 4204
4197 virtual Range* InferRange(Zone* zone); 4205 virtual Range* InferRange(Zone* zone);
4198 4206
(...skipping 951 matching lines...) Expand 10 before | Expand all | Expand 10 after
5150 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); 5158 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex);
5151 }; 5159 };
5152 5160
5153 5161
5154 #undef DECLARE_INSTRUCTION 5162 #undef DECLARE_INSTRUCTION
5155 #undef DECLARE_CONCRETE_INSTRUCTION 5163 #undef DECLARE_CONCRETE_INSTRUCTION
5156 5164
5157 } } // namespace v8::internal 5165 } } // namespace v8::internal
5158 5166
5159 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 5167 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698