| 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 { |
| 4292 return IsExternalArrayElementsKind(elements_kind()); |
| 4293 } |
| 4294 HValue* elements() { return OperandAt(0); } |
| 4269 HValue* key() { return OperandAt(1); } | 4295 HValue* key() { return OperandAt(1); } |
| 4270 HValue* dependency() { return OperandAt(2); } | 4296 HValue* dependency() { return OperandAt(2); } |
| 4271 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); } | 4297 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); } |
| 4272 void SetIndexOffset(uint32_t index_offset) { | 4298 void SetIndexOffset(uint32_t index_offset) { |
| 4273 bit_field_ = IndexOffsetField::update(bit_field_, index_offset); | 4299 bit_field_ = IndexOffsetField::update(bit_field_, index_offset); |
| 4274 } | 4300 } |
| 4275 HValue* GetKey() { return key(); } | 4301 HValue* GetKey() { return key(); } |
| 4276 void SetKey(HValue* key) { SetOperandAt(1, key); } | 4302 void SetKey(HValue* key) { SetOperandAt(1, key); } |
| 4277 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } | 4303 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } |
| 4278 void SetDehoisted(bool is_dehoisted) { | 4304 void SetDehoisted(bool is_dehoisted) { |
| 4279 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); | 4305 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); |
| 4280 } | 4306 } |
| 4281 ElementsKind elements_kind() const { | 4307 ElementsKind elements_kind() const { |
| 4282 return ElementsKindField::decode(bit_field_); | 4308 return ElementsKindField::decode(bit_field_); |
| 4283 } | 4309 } |
| 4284 | 4310 |
| 4285 virtual Representation RequiredInputRepresentation(int index) { | 4311 virtual Representation RequiredInputRepresentation(int index) { |
| 4286 // The key is supposed to be Integer32. | 4312 // kind_fast: tagged[int32] (none) |
| 4287 if (index == 0) return Representation::Tagged(); | 4313 // kind_double: tagged[int32] (none) |
| 4314 // kind_external: external[int32] (none) |
| 4315 if (index == 0) { |
| 4316 return is_external() ? Representation::External() |
| 4317 : Representation::Tagged(); |
| 4318 } |
| 4288 if (index == 1) return Representation::Integer32(); | 4319 if (index == 1) return Representation::Integer32(); |
| 4289 return Representation::None(); | 4320 return Representation::None(); |
| 4290 } | 4321 } |
| 4291 | 4322 |
| 4292 virtual void PrintDataTo(StringStream* stream); | 4323 virtual void PrintDataTo(StringStream* stream); |
| 4293 | 4324 |
| 4294 bool RequiresHoleCheck() const; | 4325 bool RequiresHoleCheck() const; |
| 4295 | 4326 |
| 4296 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement) | 4327 virtual Range* InferRange(Zone* zone); |
| 4328 |
| 4329 DECLARE_CONCRETE_INSTRUCTION(LoadKeyed) |
| 4297 | 4330 |
| 4298 protected: | 4331 protected: |
| 4299 virtual bool DataEquals(HValue* other) { | 4332 virtual bool DataEquals(HValue* other) { |
| 4300 if (!other->IsLoadKeyedFastElement()) return false; | 4333 if (!other->IsLoadKeyed()) return false; |
| 4301 HLoadKeyedFastElement* other_load = HLoadKeyedFastElement::cast(other); | 4334 HLoadKeyed* other_load = HLoadKeyed::cast(other); |
| 4335 |
| 4302 if (IsDehoisted() && index_offset() != other_load->index_offset()) | 4336 if (IsDehoisted() && index_offset() != other_load->index_offset()) |
| 4303 return false; | 4337 return false; |
| 4304 return elements_kind() == other_load->elements_kind(); | 4338 return elements_kind() == other_load->elements_kind(); |
| 4305 } | 4339 } |
| 4306 | 4340 |
| 4307 private: | 4341 private: |
| 4308 virtual bool IsDeletable() const { return !RequiresHoleCheck(); } | 4342 virtual bool IsDeletable() const { |
| 4343 return !RequiresHoleCheck(); |
| 4344 } |
| 4309 | 4345 |
| 4310 class ElementsKindField: public BitField<ElementsKind, 0, 4> {}; | 4346 // Establish some checks around our packed fields |
| 4311 class IndexOffsetField: public BitField<uint32_t, 4, 27> {}; | 4347 enum LoadKeyedBits { |
| 4312 class IsDehoistedField: public BitField<bool, 31, 1> {}; | 4348 kBitsForElementsKind = 5, |
| 4349 kBitsForIndexOffset = 26, |
| 4350 kBitsForIsDehoisted = 1, |
| 4351 |
| 4352 kStartElementsKind = 0, |
| 4353 kStartIndexOffset = kStartElementsKind + kBitsForElementsKind, |
| 4354 kStartIsDehoisted = kStartIndexOffset + kBitsForIndexOffset |
| 4355 }; |
| 4356 |
| 4357 STATIC_ASSERT((kBitsForElementsKind + kBitsForIndexOffset + |
| 4358 kBitsForIsDehoisted) <= sizeof(uint32_t)*8); |
| 4359 STATIC_ASSERT(kElementsKindCount <= (1 << kBitsForElementsKind)); |
| 4360 class ElementsKindField: |
| 4361 public BitField<ElementsKind, kStartElementsKind, kBitsForElementsKind> |
| 4362 {}; // NOLINT |
| 4363 class IndexOffsetField: |
| 4364 public BitField<uint32_t, kStartIndexOffset, kBitsForIndexOffset> |
| 4365 {}; // NOLINT |
| 4366 class IsDehoistedField: |
| 4367 public BitField<bool, kStartIsDehoisted, kBitsForIsDehoisted> |
| 4368 {}; // NOLINT |
| 4313 uint32_t bit_field_; | 4369 uint32_t bit_field_; |
| 4314 }; | 4370 }; |
| 4315 | 4371 |
| 4316 | 4372 |
| 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> { | 4373 class HLoadKeyedGeneric: public HTemplateInstruction<3> { |
| 4448 public: | 4374 public: |
| 4449 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) { | 4375 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) { |
| 4450 set_representation(Representation::Tagged()); | 4376 set_representation(Representation::Tagged()); |
| 4451 SetOperandAt(0, obj); | 4377 SetOperandAt(0, obj); |
| 4452 SetOperandAt(1, key); | 4378 SetOperandAt(1, key); |
| 4453 SetOperandAt(2, context); | 4379 SetOperandAt(2, context); |
| 4454 SetAllSideEffects(); | 4380 SetAllSideEffects(); |
| 4455 } | 4381 } |
| 4456 | 4382 |
| 4457 HValue* object() { return OperandAt(0); } | 4383 HValue* object() { return OperandAt(0); } |
| 4458 HValue* key() { return OperandAt(1); } | 4384 HValue* key() { return OperandAt(1); } |
| 4459 HValue* context() { return OperandAt(2); } | 4385 HValue* context() { return OperandAt(2); } |
| 4460 | 4386 |
| 4461 virtual void PrintDataTo(StringStream* stream); | 4387 virtual void PrintDataTo(StringStream* stream); |
| 4462 | 4388 |
| 4463 virtual Representation RequiredInputRepresentation(int index) { | 4389 virtual Representation RequiredInputRepresentation(int index) { |
| 4390 // tagged[tagged] |
| 4464 return Representation::Tagged(); | 4391 return Representation::Tagged(); |
| 4465 } | 4392 } |
| 4466 | 4393 |
| 4467 virtual HValue* Canonicalize(); | 4394 virtual HValue* Canonicalize(); |
| 4468 | 4395 |
| 4469 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) | 4396 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric) |
| 4470 }; | 4397 }; |
| 4471 | 4398 |
| 4472 | 4399 |
| 4473 class HStoreNamedField: public HTemplateInstruction<2> { | 4400 class HStoreNamedField: public HTemplateInstruction<2> { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4559 } | 4486 } |
| 4560 | 4487 |
| 4561 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric) | 4488 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric) |
| 4562 | 4489 |
| 4563 private: | 4490 private: |
| 4564 Handle<String> name_; | 4491 Handle<String> name_; |
| 4565 StrictModeFlag strict_mode_flag_; | 4492 StrictModeFlag strict_mode_flag_; |
| 4566 }; | 4493 }; |
| 4567 | 4494 |
| 4568 | 4495 |
| 4569 class HStoreKeyedFastElement | 4496 class HStoreKeyed |
| 4570 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 4497 : public HTemplateInstruction<3>, public ArrayInstructionInterface { |
| 4571 public: | 4498 public: |
| 4572 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val, | 4499 HStoreKeyed(HValue* obj, HValue* key, HValue* val, |
| 4573 ElementsKind elements_kind = FAST_ELEMENTS) | 4500 ElementsKind elements_kind) |
| 4574 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { | 4501 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { |
| 4575 SetOperandAt(0, obj); | 4502 SetOperandAt(0, obj); |
| 4576 SetOperandAt(1, key); | 4503 SetOperandAt(1, key); |
| 4577 SetOperandAt(2, val); | 4504 SetOperandAt(2, val); |
| 4578 SetGVNFlag(kChangesArrayElements); | 4505 |
| 4506 if (is_external()) { |
| 4507 SetGVNFlag(kChangesSpecializedArrayElements); |
| 4508 } else if (IsFastDoubleElementsKind(elements_kind)) { |
| 4509 SetGVNFlag(kChangesDoubleArrayElements); |
| 4510 SetFlag(kDeoptimizeOnUndefined); |
| 4511 } else { |
| 4512 SetGVNFlag(kChangesArrayElements); |
| 4513 } |
| 4579 } | 4514 } |
| 4580 | 4515 |
| 4581 virtual Representation RequiredInputRepresentation(int index) { | 4516 virtual Representation RequiredInputRepresentation(int index) { |
| 4582 // The key is supposed to be Integer32. | 4517 // kind_fast: tagged[int32] = tagged |
| 4583 return index == 1 | 4518 // kind_double: tagged[int32] = double |
| 4584 ? Representation::Integer32() | 4519 // kind_external: external[int32] = (double | int32) |
| 4585 : Representation::Tagged(); | 4520 if (index == 0) { |
| 4521 return is_external() ? Representation::External() |
| 4522 : Representation::Tagged(); |
| 4523 } else if (index == 1) { |
| 4524 return Representation::Integer32(); |
| 4525 } |
| 4526 |
| 4527 ASSERT_EQ(index, 2); |
| 4528 if (IsDoubleOrFloatElementsKind(elements_kind())) { |
| 4529 return Representation::Double(); |
| 4530 } |
| 4531 |
| 4532 return is_external() ? Representation::Integer32() |
| 4533 : Representation::Tagged(); |
| 4586 } | 4534 } |
| 4587 | 4535 |
| 4588 HValue* object() { return OperandAt(0); } | 4536 bool is_external() const { |
| 4537 return IsExternalArrayElementsKind(elements_kind()); |
| 4538 } |
| 4539 HValue* elements() { return OperandAt(0); } |
| 4589 HValue* key() { return OperandAt(1); } | 4540 HValue* key() { return OperandAt(1); } |
| 4590 HValue* value() { return OperandAt(2); } | 4541 HValue* value() { return OperandAt(2); } |
| 4591 bool value_is_smi() { | 4542 bool value_is_smi() const { |
| 4592 return IsFastSmiElementsKind(elements_kind_); | 4543 return IsFastSmiElementsKind(elements_kind_); |
| 4593 } | 4544 } |
| 4545 ElementsKind elements_kind() const { return elements_kind_; } |
| 4594 uint32_t index_offset() { return index_offset_; } | 4546 uint32_t index_offset() { return index_offset_; } |
| 4595 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | 4547 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } |
| 4596 HValue* GetKey() { return key(); } | 4548 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); } | 4549 void SetKey(HValue* key) { SetOperandAt(1, key); } |
| 4651 bool IsDehoisted() { return is_dehoisted_; } | 4550 bool IsDehoisted() { return is_dehoisted_; } |
| 4652 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | 4551 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } |
| 4653 | 4552 |
| 4654 bool NeedsWriteBarrier() { | 4553 bool NeedsWriteBarrier() { |
| 4655 return StoringValueNeedsWriteBarrier(value()); | 4554 if (value_is_smi()) { |
| 4555 return false; |
| 4556 } else { |
| 4557 return StoringValueNeedsWriteBarrier(value()); |
| 4558 } |
| 4656 } | 4559 } |
| 4657 | 4560 |
| 4658 bool NeedsCanonicalization(); | 4561 bool NeedsCanonicalization(); |
| 4659 | 4562 |
| 4660 virtual void PrintDataTo(StringStream* stream); | 4563 virtual void PrintDataTo(StringStream* stream); |
| 4661 | 4564 |
| 4662 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement) | 4565 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 | 4566 |
| 4714 private: | 4567 private: |
| 4715 ElementsKind elements_kind_; | 4568 ElementsKind elements_kind_; |
| 4716 uint32_t index_offset_; | 4569 uint32_t index_offset_; |
| 4717 bool is_dehoisted_; | 4570 bool is_dehoisted_; |
| 4718 }; | 4571 }; |
| 4719 | 4572 |
| 4720 | 4573 |
| 4721 class HStoreKeyedGeneric: public HTemplateInstruction<4> { | 4574 class HStoreKeyedGeneric: public HTemplateInstruction<4> { |
| 4722 public: | 4575 public: |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4733 SetAllSideEffects(); | 4586 SetAllSideEffects(); |
| 4734 } | 4587 } |
| 4735 | 4588 |
| 4736 HValue* object() { return OperandAt(0); } | 4589 HValue* object() { return OperandAt(0); } |
| 4737 HValue* key() { return OperandAt(1); } | 4590 HValue* key() { return OperandAt(1); } |
| 4738 HValue* value() { return OperandAt(2); } | 4591 HValue* value() { return OperandAt(2); } |
| 4739 HValue* context() { return OperandAt(3); } | 4592 HValue* context() { return OperandAt(3); } |
| 4740 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; } | 4593 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; } |
| 4741 | 4594 |
| 4742 virtual Representation RequiredInputRepresentation(int index) { | 4595 virtual Representation RequiredInputRepresentation(int index) { |
| 4596 // tagged[tagged] = tagged |
| 4743 return Representation::Tagged(); | 4597 return Representation::Tagged(); |
| 4744 } | 4598 } |
| 4745 | 4599 |
| 4746 virtual void PrintDataTo(StringStream* stream); | 4600 virtual void PrintDataTo(StringStream* stream); |
| 4747 | 4601 |
| 4748 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric) | 4602 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric) |
| 4749 | 4603 |
| 4750 private: | 4604 private: |
| 4751 StrictModeFlag strict_mode_flag_; | 4605 StrictModeFlag strict_mode_flag_; |
| 4752 }; | 4606 }; |
| (...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5412 virtual bool IsDeletable() const { return true; } | 5266 virtual bool IsDeletable() const { return true; } |
| 5413 }; | 5267 }; |
| 5414 | 5268 |
| 5415 | 5269 |
| 5416 #undef DECLARE_INSTRUCTION | 5270 #undef DECLARE_INSTRUCTION |
| 5417 #undef DECLARE_CONCRETE_INSTRUCTION | 5271 #undef DECLARE_CONCRETE_INSTRUCTION |
| 5418 | 5272 |
| 5419 } } // namespace v8::internal | 5273 } } // namespace v8::internal |
| 5420 | 5274 |
| 5421 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 5275 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |