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 |