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

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 nits 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 4035 matching lines...) Expand 10 before | Expand all | Expand 10 after
4046 public: 4046 public:
4047 virtual HValue* GetKey() = 0; 4047 virtual HValue* GetKey() = 0;
4048 virtual void SetKey(HValue* key) = 0; 4048 virtual void SetKey(HValue* key) = 0;
4049 virtual void SetIndexOffset(uint32_t index_offset) = 0; 4049 virtual void SetIndexOffset(uint32_t index_offset) = 0;
4050 virtual bool IsDehoisted() = 0; 4050 virtual bool IsDehoisted() = 0;
4051 virtual void SetDehoisted(bool is_dehoisted) = 0; 4051 virtual void SetDehoisted(bool is_dehoisted) = 0;
4052 virtual ~ArrayInstructionInterface() { }; 4052 virtual ~ArrayInstructionInterface() { };
4053 }; 4053 };
4054 4054
4055 class HLoadKeyedFastElement 4055 class HLoadKeyedFastElement
4056 : public HTemplateInstruction<2>, public ArrayInstructionInterface { 4056 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
4057 public: 4057 public:
4058 HLoadKeyedFastElement(HValue* obj, 4058 HLoadKeyedFastElement(HValue* obj,
4059 HValue* key, 4059 HValue* key,
4060 HValue* dependency,
4060 ElementsKind elements_kind = FAST_ELEMENTS) 4061 ElementsKind elements_kind = FAST_ELEMENTS)
4061 : bit_field_(0) { 4062 : bit_field_(0) {
4062 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind)); 4063 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind));
4063 bit_field_ = ElementsKindField::encode(elements_kind); 4064 bit_field_ = ElementsKindField::encode(elements_kind);
4064 if (IsFastSmiElementsKind(elements_kind) && 4065 if (IsFastSmiElementsKind(elements_kind) &&
4065 IsFastPackedElementsKind(elements_kind)) { 4066 IsFastPackedElementsKind(elements_kind)) {
4066 set_type(HType::Smi()); 4067 set_type(HType::Smi());
4067 } 4068 }
4068 SetOperandAt(0, obj); 4069 SetOperandAt(0, obj);
4069 SetOperandAt(1, key); 4070 SetOperandAt(1, key);
4071 SetOperandAt(2, dependency);
4070 set_representation(Representation::Tagged()); 4072 set_representation(Representation::Tagged());
4071 SetGVNFlag(kDependsOnArrayElements); 4073 SetGVNFlag(kDependsOnArrayElements);
4072 SetFlag(kUseGVN); 4074 SetFlag(kUseGVN);
4073 } 4075 }
4074 4076
4075 HValue* object() { return OperandAt(0); } 4077 HValue* object() { return OperandAt(0); }
4076 HValue* key() { return OperandAt(1); } 4078 HValue* key() { return OperandAt(1); }
4079 HValue* dependency() { return OperandAt(2); }
4077 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); } 4080 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); }
4078 void SetIndexOffset(uint32_t index_offset) { 4081 void SetIndexOffset(uint32_t index_offset) {
4079 bit_field_ = IndexOffsetField::update(bit_field_, index_offset); 4082 bit_field_ = IndexOffsetField::update(bit_field_, index_offset);
4080 } 4083 }
4081 HValue* GetKey() { return key(); } 4084 HValue* GetKey() { return key(); }
4082 void SetKey(HValue* key) { SetOperandAt(1, key); } 4085 void SetKey(HValue* key) { SetOperandAt(1, key); }
4083 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } 4086 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); }
4084 void SetDehoisted(bool is_dehoisted) { 4087 void SetDehoisted(bool is_dehoisted) {
4085 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); 4088 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted);
4086 } 4089 }
4087 ElementsKind elements_kind() const { 4090 ElementsKind elements_kind() const {
4088 return ElementsKindField::decode(bit_field_); 4091 return ElementsKindField::decode(bit_field_);
4089 } 4092 }
4090 4093
4091 virtual Representation RequiredInputRepresentation(int index) { 4094 virtual Representation RequiredInputRepresentation(int index) {
4092 // The key is supposed to be Integer32. 4095 // The key is supposed to be Integer32.
4093 return index == 0 4096 if (index == 0) return Representation::Tagged();
4094 ? Representation::Tagged() 4097 if (index == 1) return Representation::Integer32();
4095 : Representation::Integer32(); 4098 return Representation::None();
4096 } 4099 }
4097 4100
4098 virtual void PrintDataTo(StringStream* stream); 4101 virtual void PrintDataTo(StringStream* stream);
4099 4102
4100 bool RequiresHoleCheck(); 4103 bool RequiresHoleCheck();
4101 4104
4102 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement) 4105 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
4103 4106
4104 protected: 4107 protected:
4105 virtual bool DataEquals(HValue* other) { 4108 virtual bool DataEquals(HValue* other) {
4106 if (!other->IsLoadKeyedFastElement()) return false; 4109 if (!other->IsLoadKeyedFastElement()) return false;
4107 HLoadKeyedFastElement* other_load = HLoadKeyedFastElement::cast(other); 4110 HLoadKeyedFastElement* other_load = HLoadKeyedFastElement::cast(other);
4108 if (IsDehoisted() && index_offset() != other_load->index_offset()) 4111 if (IsDehoisted() && index_offset() != other_load->index_offset())
4109 return false; 4112 return false;
4110 return elements_kind() == other_load->elements_kind(); 4113 return elements_kind() == other_load->elements_kind();
4111 } 4114 }
4112 4115
4113 private: 4116 private:
4114 class ElementsKindField: public BitField<ElementsKind, 0, 4> {}; 4117 class ElementsKindField: public BitField<ElementsKind, 0, 4> {};
4115 class IndexOffsetField: public BitField<uint32_t, 4, 27> {}; 4118 class IndexOffsetField: public BitField<uint32_t, 4, 27> {};
4116 class IsDehoistedField: public BitField<bool, 31, 1> {}; 4119 class IsDehoistedField: public BitField<bool, 31, 1> {};
4117 uint32_t bit_field_; 4120 uint32_t bit_field_;
4118 }; 4121 };
4119 4122
4120 4123
4121 enum HoleCheckMode { PERFORM_HOLE_CHECK, OMIT_HOLE_CHECK }; 4124 enum HoleCheckMode { PERFORM_HOLE_CHECK, OMIT_HOLE_CHECK };
4122 4125
4123 4126
4124 class HLoadKeyedFastDoubleElement 4127 class HLoadKeyedFastDoubleElement
4125 : public HTemplateInstruction<2>, public ArrayInstructionInterface { 4128 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
4126 public: 4129 public:
4127 HLoadKeyedFastDoubleElement( 4130 HLoadKeyedFastDoubleElement(
4128 HValue* elements, 4131 HValue* elements,
4129 HValue* key, 4132 HValue* key,
4133 HValue* dependency,
4130 HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK) 4134 HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK)
4131 : index_offset_(0), 4135 : index_offset_(0),
4132 is_dehoisted_(false), 4136 is_dehoisted_(false),
4133 hole_check_mode_(hole_check_mode) { 4137 hole_check_mode_(hole_check_mode) {
4134 SetOperandAt(0, elements); 4138 SetOperandAt(0, elements);
4135 SetOperandAt(1, key); 4139 SetOperandAt(1, key);
4140 SetOperandAt(2, dependency);
4136 set_representation(Representation::Double()); 4141 set_representation(Representation::Double());
4137 SetGVNFlag(kDependsOnDoubleArrayElements); 4142 SetGVNFlag(kDependsOnDoubleArrayElements);
4138 SetFlag(kUseGVN); 4143 SetFlag(kUseGVN);
4139 } 4144 }
4140 4145
4141 HValue* elements() { return OperandAt(0); } 4146 HValue* elements() { return OperandAt(0); }
4142 HValue* key() { return OperandAt(1); } 4147 HValue* key() { return OperandAt(1); }
4148 HValue* dependency() { return OperandAt(2); }
4143 uint32_t index_offset() { return index_offset_; } 4149 uint32_t index_offset() { return index_offset_; }
4144 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } 4150 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4145 HValue* GetKey() { return key(); } 4151 HValue* GetKey() { return key(); }
4146 void SetKey(HValue* key) { SetOperandAt(1, key); } 4152 void SetKey(HValue* key) { SetOperandAt(1, key); }
4147 bool IsDehoisted() { return is_dehoisted_; } 4153 bool IsDehoisted() { return is_dehoisted_; }
4148 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } 4154 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
4149 4155
4150 virtual Representation RequiredInputRepresentation(int index) { 4156 virtual Representation RequiredInputRepresentation(int index) {
4151 // The key is supposed to be Integer32. 4157 // The key is supposed to be Integer32.
4152 return index == 0 4158 if (index == 0) return Representation::Tagged();
4153 ? Representation::Tagged() 4159 if (index == 1) return Representation::Integer32();
4154 : Representation::Integer32(); 4160 return Representation::None();
4155 } 4161 }
4156 4162
4157 bool RequiresHoleCheck() { 4163 bool RequiresHoleCheck() {
4158 return hole_check_mode_ == PERFORM_HOLE_CHECK; 4164 return hole_check_mode_ == PERFORM_HOLE_CHECK;
4159 } 4165 }
4160 4166
4161 virtual void PrintDataTo(StringStream* stream); 4167 virtual void PrintDataTo(StringStream* stream);
4162 4168
4163 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement) 4169 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement)
4164 4170
4165 protected: 4171 protected:
4166 virtual bool DataEquals(HValue* other) { 4172 virtual bool DataEquals(HValue* other) {
4167 if (!other->IsLoadKeyedFastDoubleElement()) return false; 4173 if (!other->IsLoadKeyedFastDoubleElement()) return false;
4168 HLoadKeyedFastDoubleElement* other_load = 4174 HLoadKeyedFastDoubleElement* other_load =
4169 HLoadKeyedFastDoubleElement::cast(other); 4175 HLoadKeyedFastDoubleElement::cast(other);
4170 return hole_check_mode_ == other_load->hole_check_mode_; 4176 return hole_check_mode_ == other_load->hole_check_mode_;
4171 } 4177 }
4172 4178
4173 private: 4179 private:
4174 uint32_t index_offset_; 4180 uint32_t index_offset_;
4175 bool is_dehoisted_; 4181 bool is_dehoisted_;
4176 HoleCheckMode hole_check_mode_; 4182 HoleCheckMode hole_check_mode_;
4177 }; 4183 };
4178 4184
4179 4185
4180 class HLoadKeyedSpecializedArrayElement 4186 class HLoadKeyedSpecializedArrayElement
4181 : public HTemplateInstruction<2>, public ArrayInstructionInterface { 4187 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
4182 public: 4188 public:
4183 HLoadKeyedSpecializedArrayElement(HValue* external_elements, 4189 HLoadKeyedSpecializedArrayElement(HValue* external_elements,
4184 HValue* key, 4190 HValue* key,
4191 HValue* dependency,
4185 ElementsKind elements_kind) 4192 ElementsKind elements_kind)
4186 : elements_kind_(elements_kind), 4193 : elements_kind_(elements_kind),
4187 index_offset_(0), 4194 index_offset_(0),
4188 is_dehoisted_(false) { 4195 is_dehoisted_(false) {
4189 SetOperandAt(0, external_elements); 4196 SetOperandAt(0, external_elements);
4190 SetOperandAt(1, key); 4197 SetOperandAt(1, key);
4198 SetOperandAt(2, dependency);
4191 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 4199 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
4192 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 4200 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
4193 set_representation(Representation::Double()); 4201 set_representation(Representation::Double());
4194 } else { 4202 } else {
4195 set_representation(Representation::Integer32()); 4203 set_representation(Representation::Integer32());
4196 } 4204 }
4197 SetGVNFlag(kDependsOnSpecializedArrayElements); 4205 SetGVNFlag(kDependsOnSpecializedArrayElements);
4198 // Native code could change the specialized array. 4206 // Native code could change the specialized array.
4199 SetGVNFlag(kDependsOnCalls); 4207 SetGVNFlag(kDependsOnCalls);
4200 SetFlag(kUseGVN); 4208 SetFlag(kUseGVN);
4201 } 4209 }
4202 4210
4203 virtual void PrintDataTo(StringStream* stream); 4211 virtual void PrintDataTo(StringStream* stream);
4204 4212
4205 virtual Representation RequiredInputRepresentation(int index) { 4213 virtual Representation RequiredInputRepresentation(int index) {
4206 // The key is supposed to be Integer32, but the base pointer 4214 // The key is supposed to be Integer32.
4207 // for the element load is a naked pointer. 4215 if (index == 0) return Representation::External();
4208 return index == 0 4216 if (index == 1) return Representation::Integer32();
4209 ? Representation::External() 4217 return Representation::None();
4210 : Representation::Integer32();
4211 } 4218 }
4212 4219
4213 HValue* external_pointer() { return OperandAt(0); } 4220 HValue* external_pointer() { return OperandAt(0); }
4214 HValue* key() { return OperandAt(1); } 4221 HValue* key() { return OperandAt(1); }
4222 HValue* dependency() { return OperandAt(2); }
4215 ElementsKind elements_kind() const { return elements_kind_; } 4223 ElementsKind elements_kind() const { return elements_kind_; }
4216 uint32_t index_offset() { return index_offset_; } 4224 uint32_t index_offset() { return index_offset_; }
4217 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } 4225 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4218 HValue* GetKey() { return key(); } 4226 HValue* GetKey() { return key(); }
4219 void SetKey(HValue* key) { SetOperandAt(1, key); } 4227 void SetKey(HValue* key) { SetOperandAt(1, key); }
4220 bool IsDehoisted() { return is_dehoisted_; } 4228 bool IsDehoisted() { return is_dehoisted_; }
4221 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } 4229 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
4222 4230
4223 virtual Range* InferRange(Zone* zone); 4231 virtual Range* InferRange(Zone* zone);
4224 4232
(...skipping 951 matching lines...) Expand 10 before | Expand all | Expand 10 after
5176 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); 5184 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex);
5177 }; 5185 };
5178 5186
5179 5187
5180 #undef DECLARE_INSTRUCTION 5188 #undef DECLARE_INSTRUCTION
5181 #undef DECLARE_CONCRETE_INSTRUCTION 5189 #undef DECLARE_CONCRETE_INSTRUCTION
5182 5190
5183 } } // namespace v8::internal 5191 } } // namespace v8::internal
5184 5192
5185 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 5193 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698