| 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 V(BinaryOperation) \ | 57 V(BinaryOperation) \ |
| 58 V(BitwiseBinaryOperation) \ | 58 V(BitwiseBinaryOperation) \ |
| 59 V(ControlInstruction) \ | 59 V(ControlInstruction) \ |
| 60 V(Instruction) \ | 60 V(Instruction) \ |
| 61 | 61 |
| 62 | 62 |
| 63 #define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \ | 63 #define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \ |
| 64 V(AbnormalExit) \ | 64 V(AbnormalExit) \ |
| 65 V(AccessArgumentsAt) \ | 65 V(AccessArgumentsAt) \ |
| 66 V(Add) \ | 66 V(Add) \ |
| 67 V(Allocate) \ |
| 67 V(AllocateObject) \ | 68 V(AllocateObject) \ |
| 68 V(ApplyArguments) \ | 69 V(ApplyArguments) \ |
| 69 V(ArgumentsElements) \ | 70 V(ArgumentsElements) \ |
| 70 V(ArgumentsLength) \ | 71 V(ArgumentsLength) \ |
| 71 V(ArgumentsObject) \ | 72 V(ArgumentsObject) \ |
| 72 V(ArrayLiteral) \ | 73 V(ArrayLiteral) \ |
| 73 V(Bitwise) \ | 74 V(Bitwise) \ |
| 74 V(BitNot) \ | 75 V(BitNot) \ |
| 75 V(BlockEntry) \ | 76 V(BlockEntry) \ |
| 76 V(BoundsCheck) \ | 77 V(BoundsCheck) \ |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 V(StringAdd) \ | 173 V(StringAdd) \ |
| 173 V(StringCharCodeAt) \ | 174 V(StringCharCodeAt) \ |
| 174 V(StringCharFromCode) \ | 175 V(StringCharFromCode) \ |
| 175 V(StringCompareAndBranch) \ | 176 V(StringCompareAndBranch) \ |
| 176 V(StringLength) \ | 177 V(StringLength) \ |
| 177 V(Sub) \ | 178 V(Sub) \ |
| 178 V(ThisFunction) \ | 179 V(ThisFunction) \ |
| 179 V(Throw) \ | 180 V(Throw) \ |
| 180 V(ToFastProperties) \ | 181 V(ToFastProperties) \ |
| 181 V(TransitionElementsKind) \ | 182 V(TransitionElementsKind) \ |
| 183 V(TrapAllocationMemento) \ |
| 182 V(Typeof) \ | 184 V(Typeof) \ |
| 183 V(TypeofIsAndBranch) \ | 185 V(TypeofIsAndBranch) \ |
| 184 V(UnaryMathOperation) \ | 186 V(UnaryMathOperation) \ |
| 185 V(UnknownOSRValue) \ | 187 V(UnknownOSRValue) \ |
| 186 V(UseConst) \ | 188 V(UseConst) \ |
| 187 V(ValueOf) \ | 189 V(ValueOf) \ |
| 188 V(ForInPrepareMap) \ | 190 V(ForInPrepareMap) \ |
| 189 V(ForInCacheArray) \ | 191 V(ForInCacheArray) \ |
| 190 V(CheckMapValue) \ | 192 V(CheckMapValue) \ |
| 191 V(LoadFieldByIndex) \ | 193 V(LoadFieldByIndex) \ |
| (...skipping 3961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4153 } | 4155 } |
| 4154 | 4156 |
| 4155 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric) | 4157 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric) |
| 4156 | 4158 |
| 4157 private: | 4159 private: |
| 4158 Handle<Object> name_; | 4160 Handle<Object> name_; |
| 4159 bool for_typeof_; | 4161 bool for_typeof_; |
| 4160 }; | 4162 }; |
| 4161 | 4163 |
| 4162 | 4164 |
| 4165 class HAllocateObject: public HTemplateInstruction<1> { |
| 4166 public: |
| 4167 HAllocateObject(HValue* context, Handle<JSFunction> constructor) |
| 4168 : constructor_(constructor) { |
| 4169 SetOperandAt(0, context); |
| 4170 set_representation(Representation::Tagged()); |
| 4171 SetGVNFlag(kChangesNewSpacePromotion); |
| 4172 } |
| 4173 |
| 4174 // Maximum instance size for which allocations will be inlined. |
| 4175 static const int kMaxSize = 64 * kPointerSize; |
| 4176 |
| 4177 HValue* context() { return OperandAt(0); } |
| 4178 Handle<JSFunction> constructor() { return constructor_; } |
| 4179 |
| 4180 virtual Representation RequiredInputRepresentation(int index) { |
| 4181 return Representation::Tagged(); |
| 4182 } |
| 4183 virtual Handle<Map> GetMonomorphicJSObjectMap() { |
| 4184 ASSERT(constructor()->has_initial_map()); |
| 4185 return Handle<Map>(constructor()->initial_map()); |
| 4186 } |
| 4187 virtual HType CalculateInferredType(); |
| 4188 |
| 4189 DECLARE_CONCRETE_INSTRUCTION(AllocateObject) |
| 4190 |
| 4191 private: |
| 4192 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. |
| 4193 // virtual bool IsDeletable() const { return true; } |
| 4194 |
| 4195 Handle<JSFunction> constructor_; |
| 4196 }; |
| 4197 |
| 4198 |
| 4199 class HAllocate: public HTemplateInstruction<2> { |
| 4200 public: |
| 4201 enum Flags { |
| 4202 CAN_ALLOCATE_IN_NEW_SPACE = 1 << 0, |
| 4203 CAN_ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1, |
| 4204 CAN_ALLOCATE_IN_OLD_POINTER_SPACE = 1 << 2, |
| 4205 ALLOCATE_DOUBLE_ALIGNED = 1 << 3 |
| 4206 }; |
| 4207 |
| 4208 HAllocate(HValue* context, HValue* size, HType type, Flags flags) |
| 4209 : type_(type), |
| 4210 flags_(flags) { |
| 4211 ASSERT((flags & CAN_ALLOCATE_IN_OLD_DATA_SPACE) == 0); // unimplemented |
| 4212 ASSERT((flags & CAN_ALLOCATE_IN_OLD_POINTER_SPACE) == 0); // unimplemented |
| 4213 SetOperandAt(0, context); |
| 4214 SetOperandAt(1, size); |
| 4215 set_representation(Representation::Tagged()); |
| 4216 SetGVNFlag(kChangesNewSpacePromotion); |
| 4217 } |
| 4218 |
| 4219 HValue* context() { return OperandAt(0); } |
| 4220 HValue* size() { return OperandAt(1); } |
| 4221 |
| 4222 virtual Representation RequiredInputRepresentation(int index) { |
| 4223 if (index == 0) { |
| 4224 return Representation::Tagged(); |
| 4225 } else { |
| 4226 return Representation::Integer32(); |
| 4227 } |
| 4228 } |
| 4229 |
| 4230 virtual HType CalculateInferredType(); |
| 4231 |
| 4232 bool CanAllocateInNewSpace() const { |
| 4233 return (flags_ & CAN_ALLOCATE_IN_NEW_SPACE) != 0; |
| 4234 } |
| 4235 |
| 4236 bool CanAllocateInOldDataSpace() const { |
| 4237 return (flags_ & CAN_ALLOCATE_IN_OLD_DATA_SPACE) != 0; |
| 4238 } |
| 4239 |
| 4240 bool CanAllocateInOldPointerSpace() const { |
| 4241 return (flags_ & CAN_ALLOCATE_IN_OLD_POINTER_SPACE) != 0; |
| 4242 } |
| 4243 |
| 4244 bool CanAllocateInOldSpace() const { |
| 4245 return CanAllocateInOldDataSpace() || |
| 4246 CanAllocateInOldPointerSpace(); |
| 4247 } |
| 4248 |
| 4249 bool GuaranteedInNewSpace() const { |
| 4250 return CanAllocateInNewSpace() && !CanAllocateInOldSpace(); |
| 4251 } |
| 4252 |
| 4253 bool MustAllocateDoubleAligned() const { |
| 4254 return (flags_ & ALLOCATE_DOUBLE_ALIGNED) != 0; |
| 4255 } |
| 4256 |
| 4257 DECLARE_CONCRETE_INSTRUCTION(Allocate) |
| 4258 |
| 4259 private: |
| 4260 HType type_; |
| 4261 Flags flags_; |
| 4262 }; |
| 4263 |
| 4264 |
| 4163 inline bool StoringValueNeedsWriteBarrier(HValue* value) { | 4265 inline bool StoringValueNeedsWriteBarrier(HValue* value) { |
| 4164 return !value->type().IsBoolean() | 4266 return !value->type().IsBoolean() |
| 4165 && !value->type().IsSmi() | 4267 && !value->type().IsSmi() |
| 4166 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable()); | 4268 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable()); |
| 4167 } | 4269 } |
| 4168 | 4270 |
| 4169 | 4271 |
| 4170 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, | 4272 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, |
| 4171 HValue* new_space_dominator) { | 4273 HValue* new_space_dominator) { |
| 4172 return (!object->IsAllocateObject() && !object->IsFastLiteral()) || | 4274 if (object != new_space_dominator) return true; |
| 4173 (object != new_space_dominator); | 4275 if (object->IsFastLiteral()) return false; |
| 4276 if (object->IsAllocateObject()) return false; |
| 4277 if (object->IsAllocate()) { |
| 4278 return !HAllocate::cast(object)->GuaranteedInNewSpace(); |
| 4279 } |
| 4280 return true; |
| 4174 } | 4281 } |
| 4175 | 4282 |
| 4176 | 4283 |
| 4177 class HStoreGlobalCell: public HUnaryOperation { | 4284 class HStoreGlobalCell: public HUnaryOperation { |
| 4178 public: | 4285 public: |
| 4179 HStoreGlobalCell(HValue* value, | 4286 HStoreGlobalCell(HValue* value, |
| 4180 Handle<JSGlobalPropertyCell> cell, | 4287 Handle<JSGlobalPropertyCell> cell, |
| 4181 PropertyDetails details) | 4288 PropertyDetails details) |
| 4182 : HUnaryOperation(value), | 4289 : HUnaryOperation(value), |
| 4183 cell_(cell), | 4290 cell_(cell), |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4495 virtual void SetDehoisted(bool is_dehoisted) = 0; | 4602 virtual void SetDehoisted(bool is_dehoisted) = 0; |
| 4496 virtual ~ArrayInstructionInterface() { }; | 4603 virtual ~ArrayInstructionInterface() { }; |
| 4497 | 4604 |
| 4498 static Representation KeyedAccessIndexRequirement(Representation r) { | 4605 static Representation KeyedAccessIndexRequirement(Representation r) { |
| 4499 return r.IsInteger32() ? Representation::Integer32() | 4606 return r.IsInteger32() ? Representation::Integer32() |
| 4500 : Representation::Tagged(); | 4607 : Representation::Tagged(); |
| 4501 } | 4608 } |
| 4502 }; | 4609 }; |
| 4503 | 4610 |
| 4504 | 4611 |
| 4612 enum LoadKeyedHoleMode { |
| 4613 NEVER_RETURN_HOLE, |
| 4614 ALLOW_RETURN_HOLE |
| 4615 }; |
| 4616 |
| 4617 |
| 4505 class HLoadKeyed | 4618 class HLoadKeyed |
| 4506 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 4619 : public HTemplateInstruction<3>, public ArrayInstructionInterface { |
| 4507 public: | 4620 public: |
| 4508 HLoadKeyed(HValue* obj, | 4621 HLoadKeyed(HValue* obj, |
| 4509 HValue* key, | 4622 HValue* key, |
| 4510 HValue* dependency, | 4623 HValue* dependency, |
| 4511 ElementsKind elements_kind) | 4624 ElementsKind elements_kind, |
| 4625 LoadKeyedHoleMode mode = NEVER_RETURN_HOLE) |
| 4512 : bit_field_(0) { | 4626 : bit_field_(0) { |
| 4513 bit_field_ = ElementsKindField::encode(elements_kind); | 4627 bit_field_ = ElementsKindField::encode(elements_kind) | |
| 4628 HoleModeField::encode(mode); |
| 4514 | 4629 |
| 4515 SetOperandAt(0, obj); | 4630 SetOperandAt(0, obj); |
| 4516 SetOperandAt(1, key); | 4631 SetOperandAt(1, key); |
| 4517 SetOperandAt(2, dependency != NULL ? dependency : obj); | 4632 SetOperandAt(2, dependency != NULL ? dependency : obj); |
| 4518 | 4633 |
| 4519 if (!is_external()) { | 4634 if (!is_external()) { |
| 4520 // I can detect the case between storing double (holey and fast) and | 4635 // I can detect the case between storing double (holey and fast) and |
| 4521 // smi/object by looking at elements_kind_. | 4636 // smi/object by looking at elements_kind_. |
| 4522 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || | 4637 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || |
| 4523 IsFastDoubleElementsKind(elements_kind)); | 4638 IsFastDoubleElementsKind(elements_kind)); |
| 4524 | 4639 |
| 4525 if (IsFastSmiOrObjectElementsKind(elements_kind)) { | 4640 if (IsFastSmiOrObjectElementsKind(elements_kind)) { |
| 4526 if (IsFastSmiElementsKind(elements_kind) && | 4641 if (IsFastSmiElementsKind(elements_kind)) { |
| 4527 IsFastPackedElementsKind(elements_kind)) { | |
| 4528 set_type(HType::Smi()); | 4642 set_type(HType::Smi()); |
| 4529 } | 4643 } |
| 4530 | 4644 |
| 4531 set_representation(Representation::Tagged()); | 4645 set_representation(Representation::Tagged()); |
| 4532 SetGVNFlag(kDependsOnArrayElements); | 4646 SetGVNFlag(kDependsOnArrayElements); |
| 4533 } else { | 4647 } else { |
| 4534 set_representation(Representation::Double()); | 4648 set_representation(Representation::Double()); |
| 4535 SetGVNFlag(kDependsOnDoubleArrayElements); | 4649 SetGVNFlag(kDependsOnDoubleArrayElements); |
| 4536 } | 4650 } |
| 4537 } else { | 4651 } else { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 4566 } | 4680 } |
| 4567 HValue* GetKey() { return key(); } | 4681 HValue* GetKey() { return key(); } |
| 4568 void SetKey(HValue* key) { SetOperandAt(1, key); } | 4682 void SetKey(HValue* key) { SetOperandAt(1, key); } |
| 4569 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } | 4683 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } |
| 4570 void SetDehoisted(bool is_dehoisted) { | 4684 void SetDehoisted(bool is_dehoisted) { |
| 4571 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); | 4685 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); |
| 4572 } | 4686 } |
| 4573 ElementsKind elements_kind() const { | 4687 ElementsKind elements_kind() const { |
| 4574 return ElementsKindField::decode(bit_field_); | 4688 return ElementsKindField::decode(bit_field_); |
| 4575 } | 4689 } |
| 4690 LoadKeyedHoleMode hole_mode() const { |
| 4691 return HoleModeField::decode(bit_field_); |
| 4692 } |
| 4576 | 4693 |
| 4577 virtual Representation RequiredInputRepresentation(int index) { | 4694 virtual Representation RequiredInputRepresentation(int index) { |
| 4578 // kind_fast: tagged[int32] (none) | 4695 // kind_fast: tagged[int32] (none) |
| 4579 // kind_double: tagged[int32] (none) | 4696 // kind_double: tagged[int32] (none) |
| 4580 // kind_external: external[int32] (none) | 4697 // kind_external: external[int32] (none) |
| 4581 if (index == 0) { | 4698 if (index == 0) { |
| 4582 return is_external() ? Representation::External() | 4699 return is_external() ? Representation::External() |
| 4583 : Representation::Tagged(); | 4700 : Representation::Tagged(); |
| 4584 } | 4701 } |
| 4585 if (index == 1) { | 4702 if (index == 1) { |
| 4586 return ArrayInstructionInterface::KeyedAccessIndexRequirement( | 4703 return ArrayInstructionInterface::KeyedAccessIndexRequirement( |
| 4587 OperandAt(1)->representation()); | 4704 OperandAt(1)->representation()); |
| 4588 } | 4705 } |
| 4589 return Representation::None(); | 4706 return Representation::None(); |
| 4590 } | 4707 } |
| 4591 | 4708 |
| 4592 virtual Representation observed_input_representation(int index) { | 4709 virtual Representation observed_input_representation(int index) { |
| 4593 return RequiredInputRepresentation(index); | 4710 return RequiredInputRepresentation(index); |
| 4594 } | 4711 } |
| 4595 | 4712 |
| 4596 virtual void PrintDataTo(StringStream* stream); | 4713 virtual void PrintDataTo(StringStream* stream); |
| 4597 | 4714 |
| 4715 bool UsesMustHandleHole() const; |
| 4598 bool RequiresHoleCheck() const; | 4716 bool RequiresHoleCheck() const; |
| 4599 | 4717 |
| 4600 virtual Range* InferRange(Zone* zone); | 4718 virtual Range* InferRange(Zone* zone); |
| 4601 | 4719 |
| 4602 DECLARE_CONCRETE_INSTRUCTION(LoadKeyed) | 4720 DECLARE_CONCRETE_INSTRUCTION(LoadKeyed) |
| 4603 | 4721 |
| 4604 protected: | 4722 protected: |
| 4605 virtual bool DataEquals(HValue* other) { | 4723 virtual bool DataEquals(HValue* other) { |
| 4606 if (!other->IsLoadKeyed()) return false; | 4724 if (!other->IsLoadKeyed()) return false; |
| 4607 HLoadKeyed* other_load = HLoadKeyed::cast(other); | 4725 HLoadKeyed* other_load = HLoadKeyed::cast(other); |
| 4608 | 4726 |
| 4609 if (IsDehoisted() && index_offset() != other_load->index_offset()) | 4727 if (IsDehoisted() && index_offset() != other_load->index_offset()) |
| 4610 return false; | 4728 return false; |
| 4611 return elements_kind() == other_load->elements_kind(); | 4729 return elements_kind() == other_load->elements_kind(); |
| 4612 } | 4730 } |
| 4613 | 4731 |
| 4614 private: | 4732 private: |
| 4615 virtual bool IsDeletable() const { | 4733 virtual bool IsDeletable() const { |
| 4616 return !RequiresHoleCheck(); | 4734 return !RequiresHoleCheck(); |
| 4617 } | 4735 } |
| 4618 | 4736 |
| 4619 // Establish some checks around our packed fields | 4737 // Establish some checks around our packed fields |
| 4620 enum LoadKeyedBits { | 4738 enum LoadKeyedBits { |
| 4621 kBitsForElementsKind = 5, | 4739 kBitsForElementsKind = 5, |
| 4622 kBitsForIndexOffset = 26, | 4740 kBitsForHoleMode = 1, |
| 4741 kBitsForIndexOffset = 25, |
| 4623 kBitsForIsDehoisted = 1, | 4742 kBitsForIsDehoisted = 1, |
| 4624 | 4743 |
| 4625 kStartElementsKind = 0, | 4744 kStartElementsKind = 0, |
| 4626 kStartIndexOffset = kStartElementsKind + kBitsForElementsKind, | 4745 kStartHoleMode = kStartElementsKind + kBitsForElementsKind, |
| 4746 kStartIndexOffset = kStartHoleMode + kBitsForHoleMode, |
| 4627 kStartIsDehoisted = kStartIndexOffset + kBitsForIndexOffset | 4747 kStartIsDehoisted = kStartIndexOffset + kBitsForIndexOffset |
| 4628 }; | 4748 }; |
| 4629 | 4749 |
| 4630 STATIC_ASSERT((kBitsForElementsKind + kBitsForIndexOffset + | 4750 STATIC_ASSERT((kBitsForElementsKind + kBitsForIndexOffset + |
| 4631 kBitsForIsDehoisted) <= sizeof(uint32_t)*8); | 4751 kBitsForIsDehoisted) <= sizeof(uint32_t)*8); |
| 4632 STATIC_ASSERT(kElementsKindCount <= (1 << kBitsForElementsKind)); | 4752 STATIC_ASSERT(kElementsKindCount <= (1 << kBitsForElementsKind)); |
| 4633 class ElementsKindField: | 4753 class ElementsKindField: |
| 4634 public BitField<ElementsKind, kStartElementsKind, kBitsForElementsKind> | 4754 public BitField<ElementsKind, kStartElementsKind, kBitsForElementsKind> |
| 4635 {}; // NOLINT | 4755 {}; // NOLINT |
| 4756 class HoleModeField: |
| 4757 public BitField<LoadKeyedHoleMode, kStartHoleMode, kBitsForHoleMode> |
| 4758 {}; // NOLINT |
| 4636 class IndexOffsetField: | 4759 class IndexOffsetField: |
| 4637 public BitField<uint32_t, kStartIndexOffset, kBitsForIndexOffset> | 4760 public BitField<uint32_t, kStartIndexOffset, kBitsForIndexOffset> |
| 4638 {}; // NOLINT | 4761 {}; // NOLINT |
| 4639 class IsDehoistedField: | 4762 class IsDehoistedField: |
| 4640 public BitField<bool, kStartIsDehoisted, kBitsForIsDehoisted> | 4763 public BitField<bool, kStartIsDehoisted, kBitsForIsDehoisted> |
| 4641 {}; // NOLINT | 4764 {}; // NOLINT |
| 4642 uint32_t bit_field_; | 4765 uint32_t bit_field_; |
| 4643 }; | 4766 }; |
| 4644 | 4767 |
| 4645 | 4768 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4764 Handle<String> name_; | 4887 Handle<String> name_; |
| 4765 StrictModeFlag strict_mode_flag_; | 4888 StrictModeFlag strict_mode_flag_; |
| 4766 }; | 4889 }; |
| 4767 | 4890 |
| 4768 | 4891 |
| 4769 class HStoreKeyed | 4892 class HStoreKeyed |
| 4770 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 4893 : public HTemplateInstruction<3>, public ArrayInstructionInterface { |
| 4771 public: | 4894 public: |
| 4772 HStoreKeyed(HValue* obj, HValue* key, HValue* val, | 4895 HStoreKeyed(HValue* obj, HValue* key, HValue* val, |
| 4773 ElementsKind elements_kind) | 4896 ElementsKind elements_kind) |
| 4774 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { | 4897 : elements_kind_(elements_kind), |
| 4898 index_offset_(0), |
| 4899 is_dehoisted_(false), |
| 4900 new_space_dominator_(NULL) { |
| 4775 SetOperandAt(0, obj); | 4901 SetOperandAt(0, obj); |
| 4776 SetOperandAt(1, key); | 4902 SetOperandAt(1, key); |
| 4777 SetOperandAt(2, val); | 4903 SetOperandAt(2, val); |
| 4778 | 4904 |
| 4905 if (IsFastObjectElementsKind(elements_kind)) { |
| 4906 SetFlag(kTrackSideEffectDominators); |
| 4907 SetGVNFlag(kDependsOnNewSpacePromotion); |
| 4908 } |
| 4779 if (is_external()) { | 4909 if (is_external()) { |
| 4780 SetGVNFlag(kChangesSpecializedArrayElements); | 4910 SetGVNFlag(kChangesSpecializedArrayElements); |
| 4781 } else if (IsFastDoubleElementsKind(elements_kind)) { | 4911 } else if (IsFastDoubleElementsKind(elements_kind)) { |
| 4782 SetGVNFlag(kChangesDoubleArrayElements); | 4912 SetGVNFlag(kChangesDoubleArrayElements); |
| 4783 SetFlag(kDeoptimizeOnUndefined); | 4913 SetFlag(kDeoptimizeOnUndefined); |
| 4784 } else { | 4914 } else { |
| 4785 SetGVNFlag(kChangesArrayElements); | 4915 SetGVNFlag(kChangesArrayElements); |
| 4786 } | 4916 } |
| 4787 | 4917 |
| 4788 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. | 4918 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4836 return IsFastSmiElementsKind(elements_kind_); | 4966 return IsFastSmiElementsKind(elements_kind_); |
| 4837 } | 4967 } |
| 4838 ElementsKind elements_kind() const { return elements_kind_; } | 4968 ElementsKind elements_kind() const { return elements_kind_; } |
| 4839 uint32_t index_offset() { return index_offset_; } | 4969 uint32_t index_offset() { return index_offset_; } |
| 4840 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | 4970 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } |
| 4841 HValue* GetKey() { return key(); } | 4971 HValue* GetKey() { return key(); } |
| 4842 void SetKey(HValue* key) { SetOperandAt(1, key); } | 4972 void SetKey(HValue* key) { SetOperandAt(1, key); } |
| 4843 bool IsDehoisted() { return is_dehoisted_; } | 4973 bool IsDehoisted() { return is_dehoisted_; } |
| 4844 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | 4974 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } |
| 4845 | 4975 |
| 4976 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) { |
| 4977 ASSERT(side_effect == kChangesNewSpacePromotion); |
| 4978 new_space_dominator_ = dominator; |
| 4979 } |
| 4980 |
| 4981 HValue* new_space_dominator() const { return new_space_dominator_; } |
| 4982 |
| 4846 bool NeedsWriteBarrier() { | 4983 bool NeedsWriteBarrier() { |
| 4847 if (value_is_smi()) { | 4984 if (value_is_smi()) { |
| 4848 return false; | 4985 return false; |
| 4849 } else { | 4986 } else { |
| 4850 return StoringValueNeedsWriteBarrier(value()); | 4987 return StoringValueNeedsWriteBarrier(value()) && |
| 4988 ReceiverObjectNeedsWriteBarrier(elements(), new_space_dominator()); |
| 4851 } | 4989 } |
| 4852 } | 4990 } |
| 4853 | 4991 |
| 4854 bool NeedsCanonicalization(); | 4992 bool NeedsCanonicalization(); |
| 4855 | 4993 |
| 4856 virtual void PrintDataTo(StringStream* stream); | 4994 virtual void PrintDataTo(StringStream* stream); |
| 4857 | 4995 |
| 4858 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) | 4996 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) |
| 4859 | 4997 |
| 4860 private: | 4998 private: |
| 4861 ElementsKind elements_kind_; | 4999 ElementsKind elements_kind_; |
| 4862 uint32_t index_offset_; | 5000 uint32_t index_offset_; |
| 4863 bool is_dehoisted_; | 5001 bool is_dehoisted_; |
| 5002 HValue* new_space_dominator_; |
| 4864 }; | 5003 }; |
| 4865 | 5004 |
| 4866 | 5005 |
| 4867 class HStoreKeyedGeneric: public HTemplateInstruction<4> { | 5006 class HStoreKeyedGeneric: public HTemplateInstruction<4> { |
| 4868 public: | 5007 public: |
| 4869 HStoreKeyedGeneric(HValue* context, | 5008 HStoreKeyedGeneric(HValue* context, |
| 4870 HValue* object, | 5009 HValue* object, |
| 4871 HValue* key, | 5010 HValue* key, |
| 4872 HValue* value, | 5011 HValue* value, |
| 4873 StrictModeFlag strict_mode_flag) | 5012 StrictModeFlag strict_mode_flag) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 4892 | 5031 |
| 4893 virtual void PrintDataTo(StringStream* stream); | 5032 virtual void PrintDataTo(StringStream* stream); |
| 4894 | 5033 |
| 4895 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric) | 5034 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric) |
| 4896 | 5035 |
| 4897 private: | 5036 private: |
| 4898 StrictModeFlag strict_mode_flag_; | 5037 StrictModeFlag strict_mode_flag_; |
| 4899 }; | 5038 }; |
| 4900 | 5039 |
| 4901 | 5040 |
| 4902 class HTransitionElementsKind: public HTemplateInstruction<1> { | 5041 class HTransitionElementsKind: public HTemplateInstruction<2> { |
| 4903 public: | 5042 public: |
| 4904 HTransitionElementsKind(HValue* object, | 5043 HTransitionElementsKind(HValue* context, |
| 5044 HValue* object, |
| 4905 Handle<Map> original_map, | 5045 Handle<Map> original_map, |
| 4906 Handle<Map> transitioned_map) | 5046 Handle<Map> transitioned_map) |
| 4907 : original_map_(original_map), | 5047 : original_map_(original_map), |
| 4908 transitioned_map_(transitioned_map), | 5048 transitioned_map_(transitioned_map), |
| 4909 from_kind_(original_map->elements_kind()), | 5049 from_kind_(original_map->elements_kind()), |
| 4910 to_kind_(transitioned_map->elements_kind()) { | 5050 to_kind_(transitioned_map->elements_kind()) { |
| 4911 SetOperandAt(0, object); | 5051 SetOperandAt(0, object); |
| 5052 SetOperandAt(1, context); |
| 4912 SetFlag(kUseGVN); | 5053 SetFlag(kUseGVN); |
| 4913 SetGVNFlag(kChangesElementsKind); | 5054 SetGVNFlag(kChangesElementsKind); |
| 4914 if (original_map->has_fast_double_elements()) { | 5055 if (original_map->has_fast_double_elements()) { |
| 4915 SetGVNFlag(kChangesElementsPointer); | 5056 SetGVNFlag(kChangesElementsPointer); |
| 4916 SetGVNFlag(kChangesNewSpacePromotion); | 5057 SetGVNFlag(kChangesNewSpacePromotion); |
| 4917 } | 5058 } |
| 4918 if (transitioned_map->has_fast_double_elements()) { | 5059 if (transitioned_map->has_fast_double_elements()) { |
| 4919 SetGVNFlag(kChangesElementsPointer); | 5060 SetGVNFlag(kChangesElementsPointer); |
| 4920 SetGVNFlag(kChangesNewSpacePromotion); | 5061 SetGVNFlag(kChangesNewSpacePromotion); |
| 4921 } | 5062 } |
| 4922 set_representation(Representation::Tagged()); | 5063 set_representation(Representation::Tagged()); |
| 4923 } | 5064 } |
| 4924 | 5065 |
| 4925 virtual Representation RequiredInputRepresentation(int index) { | 5066 virtual Representation RequiredInputRepresentation(int index) { |
| 4926 return Representation::Tagged(); | 5067 return Representation::Tagged(); |
| 4927 } | 5068 } |
| 4928 | 5069 |
| 4929 HValue* object() { return OperandAt(0); } | 5070 HValue* object() { return OperandAt(0); } |
| 5071 HValue* context() { return OperandAt(1); } |
| 4930 Handle<Map> original_map() { return original_map_; } | 5072 Handle<Map> original_map() { return original_map_; } |
| 4931 Handle<Map> transitioned_map() { return transitioned_map_; } | 5073 Handle<Map> transitioned_map() { return transitioned_map_; } |
| 4932 ElementsKind from_kind() { return from_kind_; } | 5074 ElementsKind from_kind() { return from_kind_; } |
| 4933 ElementsKind to_kind() { return to_kind_; } | 5075 ElementsKind to_kind() { return to_kind_; } |
| 4934 | 5076 |
| 4935 virtual void PrintDataTo(StringStream* stream); | 5077 virtual void PrintDataTo(StringStream* stream); |
| 4936 | 5078 |
| 4937 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind) | 5079 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind) |
| 4938 | 5080 |
| 4939 protected: | 5081 protected: |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5072 | 5214 |
| 5073 virtual Range* InferRange(Zone* zone) { | 5215 virtual Range* InferRange(Zone* zone) { |
| 5074 return new(zone) Range(0, String::kMaxLength); | 5216 return new(zone) Range(0, String::kMaxLength); |
| 5075 } | 5217 } |
| 5076 | 5218 |
| 5077 private: | 5219 private: |
| 5078 virtual bool IsDeletable() const { return true; } | 5220 virtual bool IsDeletable() const { return true; } |
| 5079 }; | 5221 }; |
| 5080 | 5222 |
| 5081 | 5223 |
| 5082 class HAllocateObject: public HTemplateInstruction<1> { | |
| 5083 public: | |
| 5084 HAllocateObject(HValue* context, Handle<JSFunction> constructor) | |
| 5085 : constructor_(constructor) { | |
| 5086 SetOperandAt(0, context); | |
| 5087 set_representation(Representation::Tagged()); | |
| 5088 SetGVNFlag(kChangesNewSpacePromotion); | |
| 5089 } | |
| 5090 | |
| 5091 // Maximum instance size for which allocations will be inlined. | |
| 5092 static const int kMaxSize = 64 * kPointerSize; | |
| 5093 | |
| 5094 HValue* context() { return OperandAt(0); } | |
| 5095 Handle<JSFunction> constructor() { return constructor_; } | |
| 5096 | |
| 5097 virtual Representation RequiredInputRepresentation(int index) { | |
| 5098 return Representation::Tagged(); | |
| 5099 } | |
| 5100 virtual Handle<Map> GetMonomorphicJSObjectMap() { | |
| 5101 ASSERT(constructor()->has_initial_map()); | |
| 5102 return Handle<Map>(constructor()->initial_map()); | |
| 5103 } | |
| 5104 virtual HType CalculateInferredType(); | |
| 5105 | |
| 5106 DECLARE_CONCRETE_INSTRUCTION(AllocateObject) | |
| 5107 | |
| 5108 private: | |
| 5109 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. | |
| 5110 // virtual bool IsDeletable() const { return true; } | |
| 5111 | |
| 5112 Handle<JSFunction> constructor_; | |
| 5113 }; | |
| 5114 | |
| 5115 | |
| 5116 template <int V> | 5224 template <int V> |
| 5117 class HMaterializedLiteral: public HTemplateInstruction<V> { | 5225 class HMaterializedLiteral: public HTemplateInstruction<V> { |
| 5118 public: | 5226 public: |
| 5119 HMaterializedLiteral<V>(int index, int depth, AllocationSiteMode mode) | 5227 HMaterializedLiteral<V>(int index, int depth, AllocationSiteMode mode) |
| 5120 : literal_index_(index), depth_(depth), allocation_site_mode_(mode) { | 5228 : literal_index_(index), depth_(depth), allocation_site_mode_(mode) { |
| 5121 this->set_representation(Representation::Tagged()); | 5229 this->set_representation(Representation::Tagged()); |
| 5122 } | 5230 } |
| 5123 | 5231 |
| 5124 HMaterializedLiteral<V>(int index, int depth) | 5232 HMaterializedLiteral<V>(int index, int depth) |
| 5125 : literal_index_(index), depth_(depth), | 5233 : literal_index_(index), depth_(depth), |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5339 return Representation::Tagged(); | 5447 return Representation::Tagged(); |
| 5340 } | 5448 } |
| 5341 | 5449 |
| 5342 DECLARE_CONCRETE_INSTRUCTION(Typeof) | 5450 DECLARE_CONCRETE_INSTRUCTION(Typeof) |
| 5343 | 5451 |
| 5344 private: | 5452 private: |
| 5345 virtual bool IsDeletable() const { return true; } | 5453 virtual bool IsDeletable() const { return true; } |
| 5346 }; | 5454 }; |
| 5347 | 5455 |
| 5348 | 5456 |
| 5457 class HTrapAllocationMemento : public HTemplateInstruction<1> { |
| 5458 public: |
| 5459 explicit HTrapAllocationMemento(HValue* obj) { |
| 5460 SetOperandAt(0, obj); |
| 5461 } |
| 5462 |
| 5463 virtual Representation RequiredInputRepresentation(int index) { |
| 5464 return Representation::Tagged(); |
| 5465 } |
| 5466 |
| 5467 HValue* object() { return OperandAt(0); } |
| 5468 |
| 5469 DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento) |
| 5470 }; |
| 5471 |
| 5472 |
| 5349 class HToFastProperties: public HUnaryOperation { | 5473 class HToFastProperties: public HUnaryOperation { |
| 5350 public: | 5474 public: |
| 5351 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) { | 5475 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) { |
| 5352 // This instruction is not marked as having side effects, but | 5476 // This instruction is not marked as having side effects, but |
| 5353 // changes the map of the input operand. Use it only when creating | 5477 // changes the map of the input operand. Use it only when creating |
| 5354 // object literals. | 5478 // object literals. |
| 5355 ASSERT(value->IsObjectLiteral() || value->IsFastLiteral()); | 5479 ASSERT(value->IsObjectLiteral() || value->IsFastLiteral()); |
| 5356 set_representation(Representation::Tagged()); | 5480 set_representation(Representation::Tagged()); |
| 5357 } | 5481 } |
| 5358 | 5482 |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5609 virtual bool IsDeletable() const { return true; } | 5733 virtual bool IsDeletable() const { return true; } |
| 5610 }; | 5734 }; |
| 5611 | 5735 |
| 5612 | 5736 |
| 5613 #undef DECLARE_INSTRUCTION | 5737 #undef DECLARE_INSTRUCTION |
| 5614 #undef DECLARE_CONCRETE_INSTRUCTION | 5738 #undef DECLARE_CONCRETE_INSTRUCTION |
| 5615 | 5739 |
| 5616 } } // namespace v8::internal | 5740 } } // namespace v8::internal |
| 5617 | 5741 |
| 5618 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 5742 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |