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 3919 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4111 } | 4113 } |
4112 | 4114 |
4113 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric) | 4115 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric) |
4114 | 4116 |
4115 private: | 4117 private: |
4116 Handle<Object> name_; | 4118 Handle<Object> name_; |
4117 bool for_typeof_; | 4119 bool for_typeof_; |
4118 }; | 4120 }; |
4119 | 4121 |
4120 | 4122 |
4123 class HAllocateObject: public HTemplateInstruction<1> { | |
4124 public: | |
4125 HAllocateObject(HValue* context, Handle<JSFunction> constructor) | |
4126 : constructor_(constructor) { | |
4127 SetOperandAt(0, context); | |
4128 set_representation(Representation::Tagged()); | |
4129 SetGVNFlag(kChangesNewSpacePromotion); | |
4130 } | |
4131 | |
4132 // Maximum instance size for which allocations will be inlined. | |
4133 static const int kMaxSize = 64 * kPointerSize; | |
4134 | |
4135 HValue* context() { return OperandAt(0); } | |
4136 Handle<JSFunction> constructor() { return constructor_; } | |
4137 | |
4138 virtual Representation RequiredInputRepresentation(int index) { | |
4139 return Representation::Tagged(); | |
4140 } | |
4141 virtual Handle<Map> GetMonomorphicJSObjectMap() { | |
4142 ASSERT(constructor()->has_initial_map()); | |
4143 return Handle<Map>(constructor()->initial_map()); | |
4144 } | |
4145 virtual HType CalculateInferredType(); | |
4146 | |
4147 DECLARE_CONCRETE_INSTRUCTION(AllocateObject) | |
4148 | |
4149 private: | |
4150 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. | |
4151 // virtual bool IsDeletable() const { return true; } | |
4152 | |
4153 Handle<JSFunction> constructor_; | |
4154 }; | |
4155 | |
4156 | |
4157 class HAllocate: public HTemplateInstruction<2> { | |
4158 public: | |
4159 enum Flags { | |
4160 CAN_ALLOCATE_IN_NEW_SPACE = 1 << 0, | |
4161 CAN_ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1, | |
4162 CAN_ALLOCATE_IN_OLD_POINTER_SPACE = 1 << 2, | |
4163 ALLOCATE_DOUBLE_ALIGNED = 1 << 3 | |
4164 }; | |
4165 | |
4166 HAllocate(HValue* context, HValue* size, HType type, Flags flags) | |
4167 : type_(type), | |
4168 flags_(flags) { | |
4169 ASSERT((flags & CAN_ALLOCATE_IN_OLD_DATA_SPACE) == 0); // unimplemented | |
4170 ASSERT((flags & CAN_ALLOCATE_IN_OLD_POINTER_SPACE) == 0); // unimplemented | |
4171 SetOperandAt(0, context); | |
4172 SetOperandAt(1, size); | |
4173 set_representation(Representation::Tagged()); | |
4174 SetGVNFlag(kChangesNewSpacePromotion); | |
4175 } | |
4176 | |
4177 HValue* context() { return OperandAt(0); } | |
4178 HValue* size() { return OperandAt(1); } | |
4179 | |
4180 virtual Representation RequiredInputRepresentation(int index) { | |
4181 if (index == 0) { | |
4182 return Representation::Tagged(); | |
4183 } else { | |
4184 return Representation::Integer32(); | |
4185 } | |
4186 } | |
4187 | |
4188 virtual HType CalculateInferredType(); | |
4189 | |
4190 bool CanAllocateInNewSpace() const { | |
4191 return (flags_ & CAN_ALLOCATE_IN_NEW_SPACE) != 0; | |
4192 } | |
4193 | |
4194 bool CanAllocateInOldDataSpace() const { | |
4195 return (flags_ & CAN_ALLOCATE_IN_OLD_DATA_SPACE) != 0; | |
4196 } | |
4197 | |
4198 bool CanAllocateInOldPointerSpace() const { | |
4199 return (flags_ & CAN_ALLOCATE_IN_OLD_POINTER_SPACE) != 0; | |
4200 } | |
4201 | |
4202 bool CanAllocateInOldSpace() const { | |
4203 return CanAllocateInOldDataSpace() || | |
4204 CanAllocateInOldPointerSpace(); | |
4205 } | |
4206 | |
4207 bool GuaranteedInNewSpace() const { | |
4208 return CanAllocateInNewSpace() && !CanAllocateInOldSpace(); | |
4209 } | |
4210 | |
4211 bool MustAllocateDoubleAligned() const { | |
4212 return (flags_ & ALLOCATE_DOUBLE_ALIGNED) != 0; | |
4213 } | |
4214 | |
4215 DECLARE_CONCRETE_INSTRUCTION(Allocate) | |
4216 | |
4217 private: | |
4218 HType type_; | |
4219 Flags flags_; | |
4220 }; | |
4221 | |
4222 | |
4121 inline bool StoringValueNeedsWriteBarrier(HValue* value) { | 4223 inline bool StoringValueNeedsWriteBarrier(HValue* value) { |
4122 return !value->type().IsBoolean() | 4224 return !value->type().IsBoolean() |
4123 && !value->type().IsSmi() | 4225 && !value->type().IsSmi() |
4124 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable()); | 4226 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable()); |
4125 } | 4227 } |
4126 | 4228 |
4127 | 4229 |
4128 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, | 4230 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, |
4129 HValue* new_space_dominator) { | 4231 HValue* new_space_dominator) { |
4130 return (!object->IsAllocateObject() && !object->IsFastLiteral()) || | 4232 if (object != new_space_dominator) return true; |
4131 (object != new_space_dominator); | 4233 if (object->IsFastLiteral()) return false; |
4234 if (object->IsAllocateObject()) return false; | |
4235 if (object->IsAllocate()) { | |
4236 return !HAllocate::cast(object)->GuaranteedInNewSpace(); | |
4237 } | |
4238 return true; | |
4132 } | 4239 } |
4133 | 4240 |
4134 | 4241 |
4135 class HStoreGlobalCell: public HUnaryOperation { | 4242 class HStoreGlobalCell: public HUnaryOperation { |
4136 public: | 4243 public: |
4137 HStoreGlobalCell(HValue* value, | 4244 HStoreGlobalCell(HValue* value, |
4138 Handle<JSGlobalPropertyCell> cell, | 4245 Handle<JSGlobalPropertyCell> cell, |
4139 PropertyDetails details) | 4246 PropertyDetails details) |
4140 : HUnaryOperation(value), | 4247 : HUnaryOperation(value), |
4141 cell_(cell), | 4248 cell_(cell), |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4453 virtual void SetDehoisted(bool is_dehoisted) = 0; | 4560 virtual void SetDehoisted(bool is_dehoisted) = 0; |
4454 virtual ~ArrayInstructionInterface() { }; | 4561 virtual ~ArrayInstructionInterface() { }; |
4455 | 4562 |
4456 static Representation KeyedAccessIndexRequirement(Representation r) { | 4563 static Representation KeyedAccessIndexRequirement(Representation r) { |
4457 return r.IsInteger32() ? Representation::Integer32() | 4564 return r.IsInteger32() ? Representation::Integer32() |
4458 : Representation::Tagged(); | 4565 : Representation::Tagged(); |
4459 } | 4566 } |
4460 }; | 4567 }; |
4461 | 4568 |
4462 | 4569 |
4570 enum LoadKeyedHoleMode { | |
4571 NEVER_RETURN_HOLE, | |
4572 ALLOW_RETURN_HOLE | |
4573 }; | |
4574 | |
4575 | |
4463 class HLoadKeyed | 4576 class HLoadKeyed |
4464 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 4577 : public HTemplateInstruction<3>, public ArrayInstructionInterface { |
4465 public: | 4578 public: |
4466 HLoadKeyed(HValue* obj, | 4579 HLoadKeyed(HValue* obj, |
4467 HValue* key, | 4580 HValue* key, |
4468 HValue* dependency, | 4581 HValue* dependency, |
4469 ElementsKind elements_kind) | 4582 ElementsKind elements_kind, |
4583 LoadKeyedHoleMode mode = NEVER_RETURN_HOLE) | |
4470 : bit_field_(0) { | 4584 : bit_field_(0) { |
4471 bit_field_ = ElementsKindField::encode(elements_kind); | 4585 bit_field_ = ElementsKindField::encode(elements_kind) | |
4586 HoleModeField::encode(mode); | |
4472 | 4587 |
4473 SetOperandAt(0, obj); | 4588 SetOperandAt(0, obj); |
4474 SetOperandAt(1, key); | 4589 SetOperandAt(1, key); |
4475 SetOperandAt(2, dependency != NULL ? dependency : obj); | 4590 SetOperandAt(2, dependency != NULL ? dependency : obj); |
4476 | 4591 |
4477 if (!is_external()) { | 4592 if (!is_external()) { |
4478 // I can detect the case between storing double (holey and fast) and | 4593 // I can detect the case between storing double (holey and fast) and |
4479 // smi/object by looking at elements_kind_. | 4594 // smi/object by looking at elements_kind_. |
4480 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || | 4595 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || |
4481 IsFastDoubleElementsKind(elements_kind)); | 4596 IsFastDoubleElementsKind(elements_kind)); |
4482 | 4597 |
4483 if (IsFastSmiOrObjectElementsKind(elements_kind)) { | 4598 if (IsFastSmiOrObjectElementsKind(elements_kind)) { |
4484 if (IsFastSmiElementsKind(elements_kind) && | 4599 if (IsFastSmiElementsKind(elements_kind)) { |
4485 IsFastPackedElementsKind(elements_kind)) { | |
4486 set_type(HType::Smi()); | 4600 set_type(HType::Smi()); |
4487 } | 4601 } |
4488 | 4602 |
4489 set_representation(Representation::Tagged()); | 4603 set_representation(Representation::Tagged()); |
4490 SetGVNFlag(kDependsOnArrayElements); | 4604 SetGVNFlag(kDependsOnArrayElements); |
4491 } else { | 4605 } else { |
4492 set_representation(Representation::Double()); | 4606 set_representation(Representation::Double()); |
4493 SetGVNFlag(kDependsOnDoubleArrayElements); | 4607 SetGVNFlag(kDependsOnDoubleArrayElements); |
4494 } | 4608 } |
4495 } else { | 4609 } else { |
(...skipping 28 matching lines...) Expand all Loading... | |
4524 } | 4638 } |
4525 HValue* GetKey() { return key(); } | 4639 HValue* GetKey() { return key(); } |
4526 void SetKey(HValue* key) { SetOperandAt(1, key); } | 4640 void SetKey(HValue* key) { SetOperandAt(1, key); } |
4527 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } | 4641 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } |
4528 void SetDehoisted(bool is_dehoisted) { | 4642 void SetDehoisted(bool is_dehoisted) { |
4529 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); | 4643 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); |
4530 } | 4644 } |
4531 ElementsKind elements_kind() const { | 4645 ElementsKind elements_kind() const { |
4532 return ElementsKindField::decode(bit_field_); | 4646 return ElementsKindField::decode(bit_field_); |
4533 } | 4647 } |
4648 LoadKeyedHoleMode hole_mode() const { | |
4649 return HoleModeField::decode(bit_field_); | |
4650 } | |
4534 | 4651 |
4535 virtual Representation RequiredInputRepresentation(int index) { | 4652 virtual Representation RequiredInputRepresentation(int index) { |
4536 // kind_fast: tagged[int32] (none) | 4653 // kind_fast: tagged[int32] (none) |
4537 // kind_double: tagged[int32] (none) | 4654 // kind_double: tagged[int32] (none) |
4538 // kind_external: external[int32] (none) | 4655 // kind_external: external[int32] (none) |
4539 if (index == 0) { | 4656 if (index == 0) { |
4540 return is_external() ? Representation::External() | 4657 return is_external() ? Representation::External() |
4541 : Representation::Tagged(); | 4658 : Representation::Tagged(); |
4542 } | 4659 } |
4543 if (index == 1) { | 4660 if (index == 1) { |
4544 return ArrayInstructionInterface::KeyedAccessIndexRequirement( | 4661 return ArrayInstructionInterface::KeyedAccessIndexRequirement( |
4545 OperandAt(1)->representation()); | 4662 OperandAt(1)->representation()); |
4546 } | 4663 } |
4547 return Representation::None(); | 4664 return Representation::None(); |
4548 } | 4665 } |
4549 | 4666 |
4550 virtual Representation observed_input_representation(int index) { | 4667 virtual Representation observed_input_representation(int index) { |
4551 return RequiredInputRepresentation(index); | 4668 return RequiredInputRepresentation(index); |
4552 } | 4669 } |
4553 | 4670 |
4554 virtual void PrintDataTo(StringStream* stream); | 4671 virtual void PrintDataTo(StringStream* stream); |
4555 | 4672 |
4673 bool CanReturnHole() const; | |
4556 bool RequiresHoleCheck() const; | 4674 bool RequiresHoleCheck() const; |
4557 | 4675 |
4558 virtual Range* InferRange(Zone* zone); | 4676 virtual Range* InferRange(Zone* zone); |
4559 | 4677 |
4560 DECLARE_CONCRETE_INSTRUCTION(LoadKeyed) | 4678 DECLARE_CONCRETE_INSTRUCTION(LoadKeyed) |
4561 | 4679 |
4562 protected: | 4680 protected: |
4563 virtual bool DataEquals(HValue* other) { | 4681 virtual bool DataEquals(HValue* other) { |
4564 if (!other->IsLoadKeyed()) return false; | 4682 if (!other->IsLoadKeyed()) return false; |
4565 HLoadKeyed* other_load = HLoadKeyed::cast(other); | 4683 HLoadKeyed* other_load = HLoadKeyed::cast(other); |
4566 | 4684 |
4567 if (IsDehoisted() && index_offset() != other_load->index_offset()) | 4685 if (IsDehoisted() && index_offset() != other_load->index_offset()) |
4568 return false; | 4686 return false; |
4569 return elements_kind() == other_load->elements_kind(); | 4687 return elements_kind() == other_load->elements_kind(); |
4570 } | 4688 } |
4571 | 4689 |
4572 private: | 4690 private: |
4573 virtual bool IsDeletable() const { | 4691 virtual bool IsDeletable() const { |
4574 return !RequiresHoleCheck(); | 4692 return !RequiresHoleCheck(); |
4575 } | 4693 } |
4576 | 4694 |
4577 // Establish some checks around our packed fields | 4695 // Establish some checks around our packed fields |
4578 enum LoadKeyedBits { | 4696 enum LoadKeyedBits { |
4579 kBitsForElementsKind = 5, | 4697 kBitsForElementsKind = 5, |
4580 kBitsForIndexOffset = 26, | 4698 kBitsForHoleMode = 1, |
4699 kBitsForIndexOffset = 25, | |
4581 kBitsForIsDehoisted = 1, | 4700 kBitsForIsDehoisted = 1, |
4582 | 4701 |
4583 kStartElementsKind = 0, | 4702 kStartElementsKind = 0, |
4584 kStartIndexOffset = kStartElementsKind + kBitsForElementsKind, | 4703 kStartHoleMode = kStartElementsKind + kBitsForElementsKind, |
4704 kStartIndexOffset = kStartHoleMode + kBitsForHoleMode, | |
4585 kStartIsDehoisted = kStartIndexOffset + kBitsForIndexOffset | 4705 kStartIsDehoisted = kStartIndexOffset + kBitsForIndexOffset |
4586 }; | 4706 }; |
4587 | 4707 |
4588 STATIC_ASSERT((kBitsForElementsKind + kBitsForIndexOffset + | 4708 STATIC_ASSERT((kBitsForElementsKind + kBitsForIndexOffset + |
4589 kBitsForIsDehoisted) <= sizeof(uint32_t)*8); | 4709 kBitsForIsDehoisted) <= sizeof(uint32_t)*8); |
4590 STATIC_ASSERT(kElementsKindCount <= (1 << kBitsForElementsKind)); | 4710 STATIC_ASSERT(kElementsKindCount <= (1 << kBitsForElementsKind)); |
4591 class ElementsKindField: | 4711 class ElementsKindField: |
4592 public BitField<ElementsKind, kStartElementsKind, kBitsForElementsKind> | 4712 public BitField<ElementsKind, kStartElementsKind, kBitsForElementsKind> |
4593 {}; // NOLINT | 4713 {}; // NOLINT |
4714 class HoleModeField: | |
4715 public BitField<LoadKeyedHoleMode, kStartHoleMode, kBitsForHoleMode> | |
4716 {}; // NOLINT | |
4594 class IndexOffsetField: | 4717 class IndexOffsetField: |
4595 public BitField<uint32_t, kStartIndexOffset, kBitsForIndexOffset> | 4718 public BitField<uint32_t, kStartIndexOffset, kBitsForIndexOffset> |
4596 {}; // NOLINT | 4719 {}; // NOLINT |
4597 class IsDehoistedField: | 4720 class IsDehoistedField: |
4598 public BitField<bool, kStartIsDehoisted, kBitsForIsDehoisted> | 4721 public BitField<bool, kStartIsDehoisted, kBitsForIsDehoisted> |
4599 {}; // NOLINT | 4722 {}; // NOLINT |
4600 uint32_t bit_field_; | 4723 uint32_t bit_field_; |
4601 }; | 4724 }; |
4602 | 4725 |
4603 | 4726 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4722 Handle<String> name_; | 4845 Handle<String> name_; |
4723 StrictModeFlag strict_mode_flag_; | 4846 StrictModeFlag strict_mode_flag_; |
4724 }; | 4847 }; |
4725 | 4848 |
4726 | 4849 |
4727 class HStoreKeyed | 4850 class HStoreKeyed |
4728 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 4851 : public HTemplateInstruction<3>, public ArrayInstructionInterface { |
4729 public: | 4852 public: |
4730 HStoreKeyed(HValue* obj, HValue* key, HValue* val, | 4853 HStoreKeyed(HValue* obj, HValue* key, HValue* val, |
4731 ElementsKind elements_kind) | 4854 ElementsKind elements_kind) |
4732 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { | 4855 : elements_kind_(elements_kind), |
4856 index_offset_(0), | |
4857 is_dehoisted_(false), | |
4858 new_space_dominator_(NULL) { | |
4733 SetOperandAt(0, obj); | 4859 SetOperandAt(0, obj); |
4734 SetOperandAt(1, key); | 4860 SetOperandAt(1, key); |
4735 SetOperandAt(2, val); | 4861 SetOperandAt(2, val); |
4736 | 4862 |
4863 if (IsFastObjectElementsKind(elements_kind)) { | |
4864 SetFlag(kTrackSideEffectDominators); | |
4865 SetGVNFlag(kDependsOnNewSpacePromotion); | |
4866 } | |
4737 if (is_external()) { | 4867 if (is_external()) { |
4738 SetGVNFlag(kChangesSpecializedArrayElements); | 4868 SetGVNFlag(kChangesSpecializedArrayElements); |
4739 } else if (IsFastDoubleElementsKind(elements_kind)) { | 4869 } else if (IsFastDoubleElementsKind(elements_kind)) { |
4740 SetGVNFlag(kChangesDoubleArrayElements); | 4870 SetGVNFlag(kChangesDoubleArrayElements); |
4741 SetFlag(kDeoptimizeOnUndefined); | 4871 SetFlag(kDeoptimizeOnUndefined); |
4742 } else { | 4872 } else { |
4743 SetGVNFlag(kChangesArrayElements); | 4873 SetGVNFlag(kChangesArrayElements); |
4744 } | 4874 } |
4745 | 4875 |
4746 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. | 4876 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4794 return IsFastSmiElementsKind(elements_kind_); | 4924 return IsFastSmiElementsKind(elements_kind_); |
4795 } | 4925 } |
4796 ElementsKind elements_kind() const { return elements_kind_; } | 4926 ElementsKind elements_kind() const { return elements_kind_; } |
4797 uint32_t index_offset() { return index_offset_; } | 4927 uint32_t index_offset() { return index_offset_; } |
4798 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | 4928 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } |
4799 HValue* GetKey() { return key(); } | 4929 HValue* GetKey() { return key(); } |
4800 void SetKey(HValue* key) { SetOperandAt(1, key); } | 4930 void SetKey(HValue* key) { SetOperandAt(1, key); } |
4801 bool IsDehoisted() { return is_dehoisted_; } | 4931 bool IsDehoisted() { return is_dehoisted_; } |
4802 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | 4932 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } |
4803 | 4933 |
4934 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) { | |
4935 ASSERT(side_effect == kChangesNewSpacePromotion); | |
4936 new_space_dominator_ = dominator; | |
4937 } | |
4938 | |
4939 HValue* new_space_dominator() const { return new_space_dominator_; } | |
4940 | |
4804 bool NeedsWriteBarrier() { | 4941 bool NeedsWriteBarrier() { |
4805 if (value_is_smi()) { | 4942 if (value_is_smi()) { |
4806 return false; | 4943 return false; |
4807 } else { | 4944 } else { |
4808 return StoringValueNeedsWriteBarrier(value()); | 4945 return StoringValueNeedsWriteBarrier(value()) && |
4946 ReceiverObjectNeedsWriteBarrier(elements(), new_space_dominator()); | |
4809 } | 4947 } |
4810 } | 4948 } |
4811 | 4949 |
4812 bool NeedsCanonicalization(); | 4950 bool NeedsCanonicalization(); |
4813 | 4951 |
4814 virtual void PrintDataTo(StringStream* stream); | 4952 virtual void PrintDataTo(StringStream* stream); |
4815 | 4953 |
4816 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) | 4954 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) |
4817 | 4955 |
4818 private: | 4956 private: |
4819 ElementsKind elements_kind_; | 4957 ElementsKind elements_kind_; |
4820 uint32_t index_offset_; | 4958 uint32_t index_offset_; |
4821 bool is_dehoisted_; | 4959 bool is_dehoisted_; |
4960 HValue* new_space_dominator_; | |
4822 }; | 4961 }; |
4823 | 4962 |
4824 | 4963 |
4825 class HStoreKeyedGeneric: public HTemplateInstruction<4> { | 4964 class HStoreKeyedGeneric: public HTemplateInstruction<4> { |
4826 public: | 4965 public: |
4827 HStoreKeyedGeneric(HValue* context, | 4966 HStoreKeyedGeneric(HValue* context, |
4828 HValue* object, | 4967 HValue* object, |
4829 HValue* key, | 4968 HValue* key, |
4830 HValue* value, | 4969 HValue* value, |
4831 StrictModeFlag strict_mode_flag) | 4970 StrictModeFlag strict_mode_flag) |
(...skipping 18 matching lines...) Expand all Loading... | |
4850 | 4989 |
4851 virtual void PrintDataTo(StringStream* stream); | 4990 virtual void PrintDataTo(StringStream* stream); |
4852 | 4991 |
4853 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric) | 4992 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric) |
4854 | 4993 |
4855 private: | 4994 private: |
4856 StrictModeFlag strict_mode_flag_; | 4995 StrictModeFlag strict_mode_flag_; |
4857 }; | 4996 }; |
4858 | 4997 |
4859 | 4998 |
4860 class HTransitionElementsKind: public HTemplateInstruction<1> { | 4999 class HTransitionElementsKind: public HTemplateInstruction<2> { |
4861 public: | 5000 public: |
4862 HTransitionElementsKind(HValue* object, | 5001 HTransitionElementsKind(HValue* context, |
5002 HValue* object, | |
4863 Handle<Map> original_map, | 5003 Handle<Map> original_map, |
4864 Handle<Map> transitioned_map) | 5004 Handle<Map> transitioned_map) |
4865 : original_map_(original_map), | 5005 : original_map_(original_map), |
4866 transitioned_map_(transitioned_map), | 5006 transitioned_map_(transitioned_map), |
4867 from_kind_(original_map->elements_kind()), | 5007 from_kind_(original_map->elements_kind()), |
4868 to_kind_(transitioned_map->elements_kind()) { | 5008 to_kind_(transitioned_map->elements_kind()) { |
4869 SetOperandAt(0, object); | 5009 SetOperandAt(0, object); |
5010 SetOperandAt(1, context); | |
4870 SetFlag(kUseGVN); | 5011 SetFlag(kUseGVN); |
4871 SetGVNFlag(kChangesElementsKind); | 5012 SetGVNFlag(kChangesElementsKind); |
4872 if (original_map->has_fast_double_elements()) { | 5013 if (original_map->has_fast_double_elements()) { |
4873 SetGVNFlag(kChangesElementsPointer); | 5014 SetGVNFlag(kChangesElementsPointer); |
4874 SetGVNFlag(kChangesNewSpacePromotion); | 5015 SetGVNFlag(kChangesNewSpacePromotion); |
4875 } | 5016 } |
4876 if (transitioned_map->has_fast_double_elements()) { | 5017 if (transitioned_map->has_fast_double_elements()) { |
4877 SetGVNFlag(kChangesElementsPointer); | 5018 SetGVNFlag(kChangesElementsPointer); |
4878 SetGVNFlag(kChangesNewSpacePromotion); | 5019 SetGVNFlag(kChangesNewSpacePromotion); |
4879 } | 5020 } |
4880 set_representation(Representation::Tagged()); | 5021 set_representation(Representation::Tagged()); |
4881 } | 5022 } |
4882 | 5023 |
4883 virtual Representation RequiredInputRepresentation(int index) { | 5024 virtual Representation RequiredInputRepresentation(int index) { |
4884 return Representation::Tagged(); | 5025 return Representation::Tagged(); |
4885 } | 5026 } |
4886 | 5027 |
4887 HValue* object() { return OperandAt(0); } | 5028 HValue* object() { return OperandAt(0); } |
5029 HValue* context() { return OperandAt(1); } | |
4888 Handle<Map> original_map() { return original_map_; } | 5030 Handle<Map> original_map() { return original_map_; } |
4889 Handle<Map> transitioned_map() { return transitioned_map_; } | 5031 Handle<Map> transitioned_map() { return transitioned_map_; } |
4890 ElementsKind from_kind() { return from_kind_; } | 5032 ElementsKind from_kind() { return from_kind_; } |
4891 ElementsKind to_kind() { return to_kind_; } | 5033 ElementsKind to_kind() { return to_kind_; } |
4892 | 5034 |
4893 virtual void PrintDataTo(StringStream* stream); | 5035 virtual void PrintDataTo(StringStream* stream); |
4894 | 5036 |
4895 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind) | 5037 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind) |
4896 | 5038 |
4897 protected: | 5039 protected: |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5030 | 5172 |
5031 virtual Range* InferRange(Zone* zone) { | 5173 virtual Range* InferRange(Zone* zone) { |
5032 return new(zone) Range(0, String::kMaxLength); | 5174 return new(zone) Range(0, String::kMaxLength); |
5033 } | 5175 } |
5034 | 5176 |
5035 private: | 5177 private: |
5036 virtual bool IsDeletable() const { return true; } | 5178 virtual bool IsDeletable() const { return true; } |
5037 }; | 5179 }; |
5038 | 5180 |
5039 | 5181 |
5040 class HAllocateObject: public HTemplateInstruction<1> { | |
5041 public: | |
5042 HAllocateObject(HValue* context, Handle<JSFunction> constructor) | |
5043 : constructor_(constructor) { | |
5044 SetOperandAt(0, context); | |
5045 set_representation(Representation::Tagged()); | |
5046 SetGVNFlag(kChangesNewSpacePromotion); | |
5047 } | |
5048 | |
5049 // Maximum instance size for which allocations will be inlined. | |
5050 static const int kMaxSize = 64 * kPointerSize; | |
5051 | |
5052 HValue* context() { return OperandAt(0); } | |
5053 Handle<JSFunction> constructor() { return constructor_; } | |
5054 | |
5055 virtual Representation RequiredInputRepresentation(int index) { | |
5056 return Representation::Tagged(); | |
5057 } | |
5058 virtual Handle<Map> GetMonomorphicJSObjectMap() { | |
5059 ASSERT(constructor()->has_initial_map()); | |
5060 return Handle<Map>(constructor()->initial_map()); | |
5061 } | |
5062 virtual HType CalculateInferredType(); | |
5063 | |
5064 DECLARE_CONCRETE_INSTRUCTION(AllocateObject) | |
5065 | |
5066 private: | |
5067 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. | |
5068 // virtual bool IsDeletable() const { return true; } | |
5069 | |
5070 Handle<JSFunction> constructor_; | |
5071 }; | |
5072 | |
5073 | |
5074 template <int V> | 5182 template <int V> |
5075 class HMaterializedLiteral: public HTemplateInstruction<V> { | 5183 class HMaterializedLiteral: public HTemplateInstruction<V> { |
5076 public: | 5184 public: |
5077 HMaterializedLiteral<V>(int index, int depth, AllocationSiteMode mode) | 5185 HMaterializedLiteral<V>(int index, int depth, AllocationSiteMode mode) |
5078 : literal_index_(index), depth_(depth), allocation_site_mode_(mode) { | 5186 : literal_index_(index), depth_(depth), allocation_site_mode_(mode) { |
5079 this->set_representation(Representation::Tagged()); | 5187 this->set_representation(Representation::Tagged()); |
5080 } | 5188 } |
5081 | 5189 |
5082 HMaterializedLiteral<V>(int index, int depth) | 5190 HMaterializedLiteral<V>(int index, int depth) |
5083 : literal_index_(index), depth_(depth), | 5191 : literal_index_(index), depth_(depth), |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5297 return Representation::Tagged(); | 5405 return Representation::Tagged(); |
5298 } | 5406 } |
5299 | 5407 |
5300 DECLARE_CONCRETE_INSTRUCTION(Typeof) | 5408 DECLARE_CONCRETE_INSTRUCTION(Typeof) |
5301 | 5409 |
5302 private: | 5410 private: |
5303 virtual bool IsDeletable() const { return true; } | 5411 virtual bool IsDeletable() const { return true; } |
5304 }; | 5412 }; |
5305 | 5413 |
5306 | 5414 |
5415 class HTrapAllocationMemento : public HTemplateInstruction<2> { | |
Michael Starzinger
2013/02/01 13:15:08
Looks like this instruction only needs one operand
danno
2013/02/02 17:56:21
Done.
| |
5416 public: | |
5417 explicit HTrapAllocationMemento(HValue* obj) { | |
5418 SetOperandAt(0, obj); | |
5419 } | |
5420 | |
5421 virtual Representation RequiredInputRepresentation(int index) { | |
5422 return Representation::Tagged(); | |
5423 } | |
5424 | |
5425 HValue* object() { return OperandAt(0); } | |
5426 | |
5427 DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento) | |
5428 }; | |
5429 | |
5430 | |
5307 class HToFastProperties: public HUnaryOperation { | 5431 class HToFastProperties: public HUnaryOperation { |
5308 public: | 5432 public: |
5309 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) { | 5433 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) { |
5310 // This instruction is not marked as having side effects, but | 5434 // This instruction is not marked as having side effects, but |
5311 // changes the map of the input operand. Use it only when creating | 5435 // changes the map of the input operand. Use it only when creating |
5312 // object literals. | 5436 // object literals. |
5313 ASSERT(value->IsObjectLiteral() || value->IsFastLiteral()); | 5437 ASSERT(value->IsObjectLiteral() || value->IsFastLiteral()); |
5314 set_representation(Representation::Tagged()); | 5438 set_representation(Representation::Tagged()); |
5315 } | 5439 } |
5316 | 5440 |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5567 virtual bool IsDeletable() const { return true; } | 5691 virtual bool IsDeletable() const { return true; } |
5568 }; | 5692 }; |
5569 | 5693 |
5570 | 5694 |
5571 #undef DECLARE_INSTRUCTION | 5695 #undef DECLARE_INSTRUCTION |
5572 #undef DECLARE_CONCRETE_INSTRUCTION | 5696 #undef DECLARE_CONCRETE_INSTRUCTION |
5573 | 5697 |
5574 } } // namespace v8::internal | 5698 } } // namespace v8::internal |
5575 | 5699 |
5576 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 5700 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |