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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
126 V(IsSmiAndBranch) \ | 126 V(IsSmiAndBranch) \ |
127 V(IsUndetectableAndBranch) \ | 127 V(IsUndetectableAndBranch) \ |
128 V(JSArrayLength) \ | 128 V(JSArrayLength) \ |
129 V(LeaveInlined) \ | 129 V(LeaveInlined) \ |
130 V(LoadContextSlot) \ | 130 V(LoadContextSlot) \ |
131 V(LoadElements) \ | 131 V(LoadElements) \ |
132 V(LoadExternalArrayPointer) \ | 132 V(LoadExternalArrayPointer) \ |
133 V(LoadFunctionPrototype) \ | 133 V(LoadFunctionPrototype) \ |
134 V(LoadGlobalCell) \ | 134 V(LoadGlobalCell) \ |
135 V(LoadGlobalGeneric) \ | 135 V(LoadGlobalGeneric) \ |
136 V(LoadKeyedFastDoubleElement) \ | 136 V(LoadKeyed) \ |
137 V(LoadKeyedFastElement) \ | |
138 V(LoadKeyedGeneric) \ | 137 V(LoadKeyedGeneric) \ |
139 V(LoadKeyedSpecializedArrayElement) \ | |
140 V(LoadNamedField) \ | 138 V(LoadNamedField) \ |
141 V(LoadNamedFieldPolymorphic) \ | 139 V(LoadNamedFieldPolymorphic) \ |
142 V(LoadNamedGeneric) \ | 140 V(LoadNamedGeneric) \ |
143 V(MapEnumLength) \ | 141 V(MapEnumLength) \ |
144 V(MathFloorOfDiv) \ | 142 V(MathFloorOfDiv) \ |
145 V(MathMinMax) \ | 143 V(MathMinMax) \ |
146 V(Mod) \ | 144 V(Mod) \ |
147 V(Mul) \ | 145 V(Mul) \ |
148 V(ObjectLiteral) \ | 146 V(ObjectLiteral) \ |
149 V(OsrEntry) \ | 147 V(OsrEntry) \ |
150 V(OuterContext) \ | 148 V(OuterContext) \ |
151 V(Parameter) \ | 149 V(Parameter) \ |
152 V(Power) \ | 150 V(Power) \ |
153 V(PushArgument) \ | 151 V(PushArgument) \ |
154 V(Random) \ | 152 V(Random) \ |
155 V(RegExpLiteral) \ | 153 V(RegExpLiteral) \ |
156 V(Return) \ | 154 V(Return) \ |
157 V(Sar) \ | 155 V(Sar) \ |
158 V(Shl) \ | 156 V(Shl) \ |
159 V(Shr) \ | 157 V(Shr) \ |
160 V(Simulate) \ | 158 V(Simulate) \ |
161 V(SoftDeoptimize) \ | 159 V(SoftDeoptimize) \ |
162 V(StackCheck) \ | 160 V(StackCheck) \ |
163 V(StoreContextSlot) \ | 161 V(StoreContextSlot) \ |
164 V(StoreGlobalCell) \ | 162 V(StoreGlobalCell) \ |
165 V(StoreGlobalGeneric) \ | 163 V(StoreGlobalGeneric) \ |
166 V(StoreKeyedFastDoubleElement) \ | 164 V(StoreKeyed) \ |
167 V(StoreKeyedFastElement) \ | |
168 V(StoreKeyedGeneric) \ | 165 V(StoreKeyedGeneric) \ |
169 V(StoreKeyedSpecializedArrayElement) \ | |
170 V(StoreNamedField) \ | 166 V(StoreNamedField) \ |
171 V(StoreNamedGeneric) \ | 167 V(StoreNamedGeneric) \ |
172 V(StringAdd) \ | 168 V(StringAdd) \ |
173 V(StringCharCodeAt) \ | 169 V(StringCharCodeAt) \ |
174 V(StringCharFromCode) \ | 170 V(StringCharFromCode) \ |
175 V(StringCompareAndBranch) \ | 171 V(StringCompareAndBranch) \ |
176 V(StringLength) \ | 172 V(StringLength) \ |
177 V(Sub) \ | 173 V(Sub) \ |
178 V(ThisFunction) \ | 174 V(ThisFunction) \ |
179 V(Throw) \ | 175 V(Throw) \ |
(...skipping 4056 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4236 class ArrayInstructionInterface { | 4232 class ArrayInstructionInterface { |
4237 public: | 4233 public: |
4238 virtual HValue* GetKey() = 0; | 4234 virtual HValue* GetKey() = 0; |
4239 virtual void SetKey(HValue* key) = 0; | 4235 virtual void SetKey(HValue* key) = 0; |
4240 virtual void SetIndexOffset(uint32_t index_offset) = 0; | 4236 virtual void SetIndexOffset(uint32_t index_offset) = 0; |
4241 virtual bool IsDehoisted() = 0; | 4237 virtual bool IsDehoisted() = 0; |
4242 virtual void SetDehoisted(bool is_dehoisted) = 0; | 4238 virtual void SetDehoisted(bool is_dehoisted) = 0; |
4243 virtual ~ArrayInstructionInterface() { }; | 4239 virtual ~ArrayInstructionInterface() { }; |
4244 }; | 4240 }; |
4245 | 4241 |
4246 class HLoadKeyedFastElement | 4242 |
4243 class HLoadKeyed | |
4247 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 4244 : public HTemplateInstruction<3>, public ArrayInstructionInterface { |
4248 public: | 4245 public: |
4249 HLoadKeyedFastElement(HValue* obj, | 4246 HLoadKeyed(HValue* obj, |
4250 HValue* key, | 4247 HValue* key, |
4251 HValue* dependency, | 4248 HValue* dependency, |
4252 ElementsKind elements_kind = FAST_ELEMENTS) | 4249 ElementsKind elements_kind) |
4253 : bit_field_(0) { | 4250 : bit_field_(0) { |
4254 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind)); | |
4255 bit_field_ = ElementsKindField::encode(elements_kind); | 4251 bit_field_ = ElementsKindField::encode(elements_kind); |
4256 if (IsFastSmiElementsKind(elements_kind) && | 4252 |
4257 IsFastPackedElementsKind(elements_kind)) { | |
4258 set_type(HType::Smi()); | |
4259 } | |
4260 SetOperandAt(0, obj); | 4253 SetOperandAt(0, obj); |
4261 SetOperandAt(1, key); | 4254 SetOperandAt(1, key); |
4262 SetOperandAt(2, dependency); | 4255 SetOperandAt(2, dependency); |
4263 set_representation(Representation::Tagged()); | 4256 |
4264 SetGVNFlag(kDependsOnArrayElements); | 4257 if (!is_external()) { |
4258 // I can detect the case between storing double (holey and fast) and | |
4259 // smi/object by looking at elements_kind_. | |
4260 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || | |
4261 IsFastDoubleElementsKind(elements_kind)); | |
4262 | |
4263 if (IsFastSmiOrObjectElementsKind(elements_kind)) { | |
4264 if (IsFastSmiElementsKind(elements_kind) && | |
4265 IsFastPackedElementsKind(elements_kind)) { | |
4266 set_type(HType::Smi()); | |
4267 } | |
4268 | |
4269 set_representation(Representation::Tagged()); | |
4270 SetGVNFlag(kDependsOnArrayElements); | |
4271 } else { | |
4272 set_representation(Representation::Double()); | |
4273 SetGVNFlag(kDependsOnDoubleArrayElements); | |
4274 } | |
4275 } else { | |
4276 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | |
4277 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | |
4278 set_representation(Representation::Double()); | |
4279 } else { | |
4280 set_representation(Representation::Integer32()); | |
4281 } | |
4282 | |
4283 SetGVNFlag(kDependsOnSpecializedArrayElements); | |
4284 // Native code could change the specialized array. | |
4285 SetGVNFlag(kDependsOnCalls); | |
4286 } | |
4287 | |
4265 SetFlag(kUseGVN); | 4288 SetFlag(kUseGVN); |
4266 } | 4289 } |
4267 | 4290 |
4268 HValue* object() { return OperandAt(0); } | 4291 bool is_external() const { return |
danno
2012/10/29 14:56:13
nit:
bool is_external() const {
return ....;
}
mvstanton
2012/10/29 15:23:57
Done.
| |
4292 IsExternalArrayElementsKind(elements_kind()); } | |
4293 HValue* elements() { return OperandAt(0); } | |
4269 HValue* key() { return OperandAt(1); } | 4294 HValue* key() { return OperandAt(1); } |
4270 HValue* dependency() { return OperandAt(2); } | 4295 HValue* dependency() { return OperandAt(2); } |
4271 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); } | 4296 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); } |
4272 void SetIndexOffset(uint32_t index_offset) { | 4297 void SetIndexOffset(uint32_t index_offset) { |
4273 bit_field_ = IndexOffsetField::update(bit_field_, index_offset); | 4298 bit_field_ = IndexOffsetField::update(bit_field_, index_offset); |
4274 } | 4299 } |
4275 HValue* GetKey() { return key(); } | 4300 HValue* GetKey() { return key(); } |
4276 void SetKey(HValue* key) { SetOperandAt(1, key); } | 4301 void SetKey(HValue* key) { SetOperandAt(1, key); } |
4277 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } | 4302 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } |
4278 void SetDehoisted(bool is_dehoisted) { | 4303 void SetDehoisted(bool is_dehoisted) { |
4279 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); | 4304 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); |
4280 } | 4305 } |
4281 ElementsKind elements_kind() const { | 4306 ElementsKind elements_kind() const { |
4282 return ElementsKindField::decode(bit_field_); | 4307 return ElementsKindField::decode(bit_field_); |
4283 } | 4308 } |
4284 | 4309 |
4285 virtual Representation RequiredInputRepresentation(int index) { | 4310 virtual Representation RequiredInputRepresentation(int index) { |
4286 // The key is supposed to be Integer32. | 4311 // kind_fast: tagged[int32] (none) |
4287 if (index == 0) return Representation::Tagged(); | 4312 // kind_double: tagged[int32] (none) |
4313 // kind_external: external[int32] (none) | |
4314 if (index == 0) { | |
4315 return is_external() ? Representation::External() | |
4316 : Representation::Tagged(); | |
4317 } | |
4288 if (index == 1) return Representation::Integer32(); | 4318 if (index == 1) return Representation::Integer32(); |
4289 return Representation::None(); | 4319 return Representation::None(); |
4290 } | 4320 } |
4291 | 4321 |
4292 virtual void PrintDataTo(StringStream* stream); | 4322 virtual void PrintDataTo(StringStream* stream); |
4293 | 4323 |
4294 bool RequiresHoleCheck() const; | 4324 bool RequiresHoleCheck() const; |
4295 | 4325 |
4296 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement) | 4326 virtual Range* InferRange(Zone* zone); |
4327 | |
4328 DECLARE_CONCRETE_INSTRUCTION(LoadKeyed) | |
4297 | 4329 |
4298 protected: | 4330 protected: |
4299 virtual bool DataEquals(HValue* other) { | 4331 virtual bool DataEquals(HValue* other) { |
4300 if (!other->IsLoadKeyedFastElement()) return false; | 4332 if (!other->IsLoadKeyed()) return false; |
4301 HLoadKeyedFastElement* other_load = HLoadKeyedFastElement::cast(other); | 4333 HLoadKeyed* other_load = HLoadKeyed::cast(other); |
4334 | |
4302 if (IsDehoisted() && index_offset() != other_load->index_offset()) | 4335 if (IsDehoisted() && index_offset() != other_load->index_offset()) |
4303 return false; | 4336 return false; |
4304 return elements_kind() == other_load->elements_kind(); | 4337 return elements_kind() == other_load->elements_kind(); |
4305 } | 4338 } |
4306 | 4339 |
4307 private: | 4340 private: |
4308 virtual bool IsDeletable() const { return !RequiresHoleCheck(); } | 4341 virtual bool IsDeletable() const { |
4342 return !RequiresHoleCheck(); | |
4343 } | |
4309 | 4344 |
4310 class ElementsKindField: public BitField<ElementsKind, 0, 4> {}; | 4345 // Establish some checks around our packed fields |
4311 class IndexOffsetField: public BitField<uint32_t, 4, 27> {}; | 4346 enum LoadKeyedBits { |
4312 class IsDehoistedField: public BitField<bool, 31, 1> {}; | 4347 kBitsForElementsKind = 5, |
4348 kBitsForIndexOffset = 26, | |
4349 kBitsForIsDehoisted = 1, | |
4350 | |
4351 kStartElementsKind = 0, | |
4352 kStartIndexOffset = kStartElementsKind + kBitsForElementsKind, | |
4353 kStartIsDehoisted = kStartIndexOffset + kBitsForIndexOffset | |
4354 }; | |
4355 | |
4356 STATIC_ASSERT((kBitsForElementsKind + kBitsForIndexOffset + | |
4357 kBitsForIsDehoisted) <= sizeof(uint32_t)*8); | |
4358 STATIC_ASSERT(kElementsKindCount <= (1 << kBitsForElementsKind)); | |
4359 class ElementsKindField: | |
4360 public BitField<ElementsKind, kStartElementsKind, kBitsForElementsKind> | |
4361 {}; // NOLINT | |
4362 class IndexOffsetField: | |
4363 public BitField<uint32_t, kStartIndexOffset, kBitsForIndexOffset> | |
4364 {}; // NOLINT | |
4365 class IsDehoistedField: | |
4366 public BitField<bool, kStartIsDehoisted, kBitsForIsDehoisted> | |
4367 {}; // NOLINT | |
4313 uint32_t bit_field_; | 4368 uint32_t bit_field_; |
4314 }; | 4369 }; |
4315 | 4370 |
4316 | 4371 |
4317 enum HoleCheckMode { PERFORM_HOLE_CHECK, OMIT_HOLE_CHECK }; | |
4318 | |
4319 | |
4320 class HLoadKeyedFastDoubleElement | |
4321 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | |
4322 public: | |
4323 HLoadKeyedFastDoubleElement( | |
4324 HValue* elements, | |
4325 HValue* key, | |
4326 HValue* dependency, | |
4327 HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK) | |
4328 : index_offset_(0), | |
4329 is_dehoisted_(false), | |
4330 hole_check_mode_(hole_check_mode) { | |
4331 SetOperandAt(0, elements); | |
4332 SetOperandAt(1, key); | |
4333 SetOperandAt(2, dependency); | |
4334 set_representation(Representation::Double()); | |
4335 SetGVNFlag(kDependsOnDoubleArrayElements); | |
4336 SetFlag(kUseGVN); | |
4337 } | |
4338 | |
4339 HValue* elements() { return OperandAt(0); } | |
4340 HValue* key() { return OperandAt(1); } | |
4341 HValue* dependency() { return OperandAt(2); } | |
4342 uint32_t index_offset() { return index_offset_; } | |
4343 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | |
4344 HValue* GetKey() { return key(); } | |
4345 void SetKey(HValue* key) { SetOperandAt(1, key); } | |
4346 bool IsDehoisted() { return is_dehoisted_; } | |
4347 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | |
4348 | |
4349 virtual Representation RequiredInputRepresentation(int index) { | |
4350 // The key is supposed to be Integer32. | |
4351 if (index == 0) return Representation::Tagged(); | |
4352 if (index == 1) return Representation::Integer32(); | |
4353 return Representation::None(); | |
4354 } | |
4355 | |
4356 bool RequiresHoleCheck() const { | |
4357 return hole_check_mode_ == PERFORM_HOLE_CHECK; | |
4358 } | |
4359 | |
4360 virtual void PrintDataTo(StringStream* stream); | |
4361 | |
4362 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement) | |
4363 | |
4364 protected: | |
4365 virtual bool DataEquals(HValue* other) { | |
4366 if (!other->IsLoadKeyedFastDoubleElement()) return false; | |
4367 HLoadKeyedFastDoubleElement* other_load = | |
4368 HLoadKeyedFastDoubleElement::cast(other); | |
4369 return hole_check_mode_ == other_load->hole_check_mode_; | |
4370 } | |
4371 | |
4372 private: | |
4373 virtual bool IsDeletable() const { return !RequiresHoleCheck(); } | |
4374 | |
4375 uint32_t index_offset_; | |
4376 bool is_dehoisted_; | |
4377 HoleCheckMode hole_check_mode_; | |
4378 }; | |
4379 | |
4380 | |
4381 class HLoadKeyedSpecializedArrayElement | |
4382 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | |
4383 public: | |
4384 HLoadKeyedSpecializedArrayElement(HValue* external_elements, | |
4385 HValue* key, | |
4386 HValue* dependency, | |
4387 ElementsKind elements_kind) | |
4388 : elements_kind_(elements_kind), | |
4389 index_offset_(0), | |
4390 is_dehoisted_(false) { | |
4391 SetOperandAt(0, external_elements); | |
4392 SetOperandAt(1, key); | |
4393 SetOperandAt(2, dependency); | |
4394 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | |
4395 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | |
4396 set_representation(Representation::Double()); | |
4397 } else { | |
4398 set_representation(Representation::Integer32()); | |
4399 } | |
4400 SetGVNFlag(kDependsOnSpecializedArrayElements); | |
4401 // Native code could change the specialized array. | |
4402 SetGVNFlag(kDependsOnCalls); | |
4403 SetFlag(kUseGVN); | |
4404 } | |
4405 | |
4406 virtual void PrintDataTo(StringStream* stream); | |
4407 | |
4408 virtual Representation RequiredInputRepresentation(int index) { | |
4409 // The key is supposed to be Integer32. | |
4410 if (index == 0) return Representation::External(); | |
4411 if (index == 1) return Representation::Integer32(); | |
4412 return Representation::None(); | |
4413 } | |
4414 | |
4415 HValue* external_pointer() { return OperandAt(0); } | |
4416 HValue* key() { return OperandAt(1); } | |
4417 HValue* dependency() { return OperandAt(2); } | |
4418 ElementsKind elements_kind() const { return elements_kind_; } | |
4419 uint32_t index_offset() { return index_offset_; } | |
4420 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | |
4421 HValue* GetKey() { return key(); } | |
4422 void SetKey(HValue* key) { SetOperandAt(1, key); } | |
4423 bool IsDehoisted() { return is_dehoisted_; } | |
4424 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | |
4425 | |
4426 virtual Range* InferRange(Zone* zone); | |
4427 | |
4428 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement) | |
4429 | |
4430 protected: | |
4431 virtual bool DataEquals(HValue* other) { | |
4432 if (!other->IsLoadKeyedSpecializedArrayElement()) return false; | |
4433 HLoadKeyedSpecializedArrayElement* cast_other = | |
4434 HLoadKeyedSpecializedArrayElement::cast(other); | |
4435 return elements_kind_ == cast_other->elements_kind(); | |
4436 } | |
4437 | |
4438 private: | |
4439 virtual bool IsDeletable() const { return true; } | |
4440 | |
4441 ElementsKind elements_kind_; | |
4442 uint32_t index_offset_; | |
4443 bool is_dehoisted_; | |
4444 }; | |
4445 | |
4446 | |
4447 class HLoadKeyedGeneric: public HTemplateInstruction<3> { | 4372 class HLoadKeyedGeneric: public HTemplateInstruction<3> { |
4448 public: | 4373 public: |
4449 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) { | 4374 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) { |
4450 set_representation(Representation::Tagged()); | 4375 set_representation(Representation::Tagged()); |
4451 SetOperandAt(0, obj); | 4376 SetOperandAt(0, obj); |
4452 SetOperandAt(1, key); | 4377 SetOperandAt(1, key); |
4453 SetOperandAt(2, context); | 4378 SetOperandAt(2, context); |
4454 SetAllSideEffects(); | 4379 SetAllSideEffects(); |
4455 } | 4380 } |
4456 | 4381 |
4457 HValue* object() { return OperandAt(0); } | 4382 HValue* object() { return OperandAt(0); } |
4458 HValue* key() { return OperandAt(1); } | 4383 HValue* key() { return OperandAt(1); } |
4459 HValue* context() { return OperandAt(2); } | 4384 HValue* context() { return OperandAt(2); } |
4460 | 4385 |
4461 virtual void PrintDataTo(StringStream* stream); | 4386 virtual void PrintDataTo(StringStream* stream); |
4462 | 4387 |
4463 virtual Representation RequiredInputRepresentation(int index) { | 4388 virtual Representation RequiredInputRepresentation(int index) { |
4389 // tagged[tagged] | |
4464 return Representation::Tagged(); | 4390 return Representation::Tagged(); |
4465 } | 4391 } |
4466 | 4392 |
4467 virtual HValue* Canonicalize(); | 4393 virtual HValue* Canonicalize(); |
4468 | 4394 |
4469 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) | 4395 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) |
4470 }; | 4396 }; |
4471 | 4397 |
4472 | 4398 |
4473 class HStoreNamedField: public HTemplateInstruction<2> { | 4399 class HStoreNamedField: public HTemplateInstruction<2> { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4559 } | 4485 } |
4560 | 4486 |
4561 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric) | 4487 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric) |
4562 | 4488 |
4563 private: | 4489 private: |
4564 Handle<String> name_; | 4490 Handle<String> name_; |
4565 StrictModeFlag strict_mode_flag_; | 4491 StrictModeFlag strict_mode_flag_; |
4566 }; | 4492 }; |
4567 | 4493 |
4568 | 4494 |
4569 class HStoreKeyedFastElement | 4495 class HStoreKeyed |
4570 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 4496 : public HTemplateInstruction<3>, public ArrayInstructionInterface { |
4571 public: | 4497 public: |
4572 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val, | 4498 HStoreKeyed(HValue* obj, HValue* key, HValue* val, |
4573 ElementsKind elements_kind = FAST_ELEMENTS) | 4499 ElementsKind elements_kind) |
4574 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { | 4500 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { |
4575 SetOperandAt(0, obj); | 4501 SetOperandAt(0, obj); |
4576 SetOperandAt(1, key); | 4502 SetOperandAt(1, key); |
4577 SetOperandAt(2, val); | 4503 SetOperandAt(2, val); |
4578 SetGVNFlag(kChangesArrayElements); | 4504 |
4505 if (is_external()) { | |
4506 SetGVNFlag(kChangesSpecializedArrayElements); | |
4507 } else if (IsFastDoubleElementsKind(elements_kind)) { | |
4508 SetGVNFlag(kChangesDoubleArrayElements); | |
4509 SetFlag(kDeoptimizeOnUndefined); | |
4510 } else { | |
4511 SetGVNFlag(kChangesArrayElements); | |
4512 } | |
4579 } | 4513 } |
4580 | 4514 |
4581 virtual Representation RequiredInputRepresentation(int index) { | 4515 virtual Representation RequiredInputRepresentation(int index) { |
4582 // The key is supposed to be Integer32. | 4516 // kind_fast: tagged[int32] = tagged |
4583 return index == 1 | 4517 // kind_double: tagged[int32] = double |
4584 ? Representation::Integer32() | 4518 // kind_external: external[int32] = (double | int32) |
4585 : Representation::Tagged(); | 4519 if (index == 0) { |
4520 return is_external() ? Representation::External() | |
4521 : Representation::Tagged(); | |
4522 } else if (index == 1) { | |
4523 return Representation::Integer32(); | |
4524 } | |
4525 | |
4526 ASSERT_EQ(index, 2); | |
4527 if (IsDoubleOrFloatElementsKind(elements_kind())) { | |
4528 return Representation::Double(); | |
4529 } | |
4530 | |
4531 return is_external() ? Representation::Integer32() | |
4532 : Representation::Tagged(); | |
4586 } | 4533 } |
4587 | 4534 |
4588 HValue* object() { return OperandAt(0); } | 4535 bool is_external() const { return |
4536 IsExternalArrayElementsKind(elements_kind()); } | |
4537 HValue* elements() { return OperandAt(0); } | |
4589 HValue* key() { return OperandAt(1); } | 4538 HValue* key() { return OperandAt(1); } |
4590 HValue* value() { return OperandAt(2); } | 4539 HValue* value() { return OperandAt(2); } |
4591 bool value_is_smi() { | 4540 bool value_is_smi() const { |
4592 return IsFastSmiElementsKind(elements_kind_); | 4541 return IsFastSmiElementsKind(elements_kind_); |
4593 } | 4542 } |
4543 ElementsKind elements_kind() const { return elements_kind_; } | |
4594 uint32_t index_offset() { return index_offset_; } | 4544 uint32_t index_offset() { return index_offset_; } |
4595 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | 4545 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } |
4596 HValue* GetKey() { return key(); } | 4546 HValue* GetKey() { return key(); } |
4597 void SetKey(HValue* key) { SetOperandAt(1, key); } | |
4598 bool IsDehoisted() { return is_dehoisted_; } | |
4599 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | |
4600 | |
4601 bool NeedsWriteBarrier() { | |
4602 if (value_is_smi()) { | |
4603 return false; | |
4604 } else { | |
4605 return StoringValueNeedsWriteBarrier(value()); | |
4606 } | |
4607 } | |
4608 | |
4609 virtual void PrintDataTo(StringStream* stream); | |
4610 | |
4611 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement) | |
4612 | |
4613 private: | |
4614 ElementsKind elements_kind_; | |
4615 uint32_t index_offset_; | |
4616 bool is_dehoisted_; | |
4617 }; | |
4618 | |
4619 | |
4620 class HStoreKeyedFastDoubleElement | |
4621 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | |
4622 public: | |
4623 HStoreKeyedFastDoubleElement(HValue* elements, | |
4624 HValue* key, | |
4625 HValue* val) | |
4626 : index_offset_(0), is_dehoisted_(false) { | |
4627 SetOperandAt(0, elements); | |
4628 SetOperandAt(1, key); | |
4629 SetOperandAt(2, val); | |
4630 SetFlag(kDeoptimizeOnUndefined); | |
4631 SetGVNFlag(kChangesDoubleArrayElements); | |
4632 } | |
4633 | |
4634 virtual Representation RequiredInputRepresentation(int index) { | |
4635 if (index == 1) { | |
4636 return Representation::Integer32(); | |
4637 } else if (index == 2) { | |
4638 return Representation::Double(); | |
4639 } else { | |
4640 return Representation::Tagged(); | |
4641 } | |
4642 } | |
4643 | |
4644 HValue* elements() { return OperandAt(0); } | |
4645 HValue* key() { return OperandAt(1); } | |
4646 HValue* value() { return OperandAt(2); } | |
4647 uint32_t index_offset() { return index_offset_; } | |
4648 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | |
4649 HValue* GetKey() { return key(); } | |
4650 void SetKey(HValue* key) { SetOperandAt(1, key); } | 4547 void SetKey(HValue* key) { SetOperandAt(1, key); } |
4651 bool IsDehoisted() { return is_dehoisted_; } | 4548 bool IsDehoisted() { return is_dehoisted_; } |
4652 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | 4549 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } |
4653 | 4550 |
4654 bool NeedsWriteBarrier() { | 4551 bool NeedsWriteBarrier() { |
4655 return StoringValueNeedsWriteBarrier(value()); | 4552 if (value_is_smi()) { |
4553 return false; | |
4554 } else { | |
4555 return StoringValueNeedsWriteBarrier(value()); | |
4556 } | |
4656 } | 4557 } |
4657 | 4558 |
4658 bool NeedsCanonicalization(); | 4559 bool NeedsCanonicalization(); |
4659 | 4560 |
4660 virtual void PrintDataTo(StringStream* stream); | 4561 virtual void PrintDataTo(StringStream* stream); |
4661 | 4562 |
4662 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement) | 4563 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) |
4663 | |
4664 private: | |
4665 uint32_t index_offset_; | |
4666 bool is_dehoisted_; | |
4667 }; | |
4668 | |
4669 | |
4670 class HStoreKeyedSpecializedArrayElement | |
4671 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | |
4672 public: | |
4673 HStoreKeyedSpecializedArrayElement(HValue* external_elements, | |
4674 HValue* key, | |
4675 HValue* val, | |
4676 ElementsKind elements_kind) | |
4677 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { | |
4678 SetGVNFlag(kChangesSpecializedArrayElements); | |
4679 SetOperandAt(0, external_elements); | |
4680 SetOperandAt(1, key); | |
4681 SetOperandAt(2, val); | |
4682 } | |
4683 | |
4684 virtual void PrintDataTo(StringStream* stream); | |
4685 | |
4686 virtual Representation RequiredInputRepresentation(int index) { | |
4687 if (index == 0) { | |
4688 return Representation::External(); | |
4689 } else { | |
4690 bool float_or_double_elements = | |
4691 elements_kind() == EXTERNAL_FLOAT_ELEMENTS || | |
4692 elements_kind() == EXTERNAL_DOUBLE_ELEMENTS; | |
4693 if (index == 2 && float_or_double_elements) { | |
4694 return Representation::Double(); | |
4695 } else { | |
4696 return Representation::Integer32(); | |
4697 } | |
4698 } | |
4699 } | |
4700 | |
4701 HValue* external_pointer() { return OperandAt(0); } | |
4702 HValue* key() { return OperandAt(1); } | |
4703 HValue* value() { return OperandAt(2); } | |
4704 ElementsKind elements_kind() const { return elements_kind_; } | |
4705 uint32_t index_offset() { return index_offset_; } | |
4706 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | |
4707 HValue* GetKey() { return key(); } | |
4708 void SetKey(HValue* key) { SetOperandAt(1, key); } | |
4709 bool IsDehoisted() { return is_dehoisted_; } | |
4710 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | |
4711 | |
4712 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement) | |
4713 | 4564 |
4714 private: | 4565 private: |
4715 ElementsKind elements_kind_; | 4566 ElementsKind elements_kind_; |
4716 uint32_t index_offset_; | 4567 uint32_t index_offset_; |
4717 bool is_dehoisted_; | 4568 bool is_dehoisted_; |
4718 }; | 4569 }; |
4719 | 4570 |
4720 | 4571 |
4721 class HStoreKeyedGeneric: public HTemplateInstruction<4> { | 4572 class HStoreKeyedGeneric: public HTemplateInstruction<4> { |
4722 public: | 4573 public: |
(...skipping 10 matching lines...) Expand all Loading... | |
4733 SetAllSideEffects(); | 4584 SetAllSideEffects(); |
4734 } | 4585 } |
4735 | 4586 |
4736 HValue* object() { return OperandAt(0); } | 4587 HValue* object() { return OperandAt(0); } |
4737 HValue* key() { return OperandAt(1); } | 4588 HValue* key() { return OperandAt(1); } |
4738 HValue* value() { return OperandAt(2); } | 4589 HValue* value() { return OperandAt(2); } |
4739 HValue* context() { return OperandAt(3); } | 4590 HValue* context() { return OperandAt(3); } |
4740 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; } | 4591 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; } |
4741 | 4592 |
4742 virtual Representation RequiredInputRepresentation(int index) { | 4593 virtual Representation RequiredInputRepresentation(int index) { |
4594 // tagged[tagged] = tagged | |
4743 return Representation::Tagged(); | 4595 return Representation::Tagged(); |
4744 } | 4596 } |
4745 | 4597 |
4746 virtual void PrintDataTo(StringStream* stream); | 4598 virtual void PrintDataTo(StringStream* stream); |
4747 | 4599 |
4748 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric) | 4600 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric) |
4749 | 4601 |
4750 private: | 4602 private: |
4751 StrictModeFlag strict_mode_flag_; | 4603 StrictModeFlag strict_mode_flag_; |
4752 }; | 4604 }; |
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5412 virtual bool IsDeletable() const { return true; } | 5264 virtual bool IsDeletable() const { return true; } |
5413 }; | 5265 }; |
5414 | 5266 |
5415 | 5267 |
5416 #undef DECLARE_INSTRUCTION | 5268 #undef DECLARE_INSTRUCTION |
5417 #undef DECLARE_CONCRETE_INSTRUCTION | 5269 #undef DECLARE_CONCRETE_INSTRUCTION |
5418 | 5270 |
5419 } } // namespace v8::internal | 5271 } } // namespace v8::internal |
5420 | 5272 |
5421 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 5273 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |