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 3928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4120 | 4122 |
4121 inline bool StoringValueNeedsWriteBarrier(HValue* value) { | 4123 inline bool StoringValueNeedsWriteBarrier(HValue* value) { |
4122 return !value->type().IsBoolean() | 4124 return !value->type().IsBoolean() |
4123 && !value->type().IsSmi() | 4125 && !value->type().IsSmi() |
4124 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable()); | 4126 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable()); |
4125 } | 4127 } |
4126 | 4128 |
4127 | 4129 |
4128 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, | 4130 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, |
4129 HValue* new_space_dominator) { | 4131 HValue* new_space_dominator) { |
4130 return (!object->IsAllocateObject() && !object->IsFastLiteral()) || | 4132 return (!object->IsAllocateObject() && !object->IsAllocate() && |
Michael Starzinger
2013/01/31 13:15:10
This only holds if HAllocate guarantees that it al
danno
2013/01/31 15:53:25
Done.
| |
4133 !object->IsFastLiteral()) || | |
4131 (object != new_space_dominator); | 4134 (object != new_space_dominator); |
4132 } | 4135 } |
4133 | 4136 |
4134 | 4137 |
4135 class HStoreGlobalCell: public HUnaryOperation { | 4138 class HStoreGlobalCell: public HUnaryOperation { |
4136 public: | 4139 public: |
4137 HStoreGlobalCell(HValue* value, | 4140 HStoreGlobalCell(HValue* value, |
4138 Handle<JSGlobalPropertyCell> cell, | 4141 Handle<JSGlobalPropertyCell> cell, |
4139 PropertyDetails details) | 4142 PropertyDetails details) |
4140 : HUnaryOperation(value), | 4143 : HUnaryOperation(value), |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4453 virtual void SetDehoisted(bool is_dehoisted) = 0; | 4456 virtual void SetDehoisted(bool is_dehoisted) = 0; |
4454 virtual ~ArrayInstructionInterface() { }; | 4457 virtual ~ArrayInstructionInterface() { }; |
4455 | 4458 |
4456 static Representation KeyedAccessIndexRequirement(Representation r) { | 4459 static Representation KeyedAccessIndexRequirement(Representation r) { |
4457 return r.IsInteger32() ? Representation::Integer32() | 4460 return r.IsInteger32() ? Representation::Integer32() |
4458 : Representation::Tagged(); | 4461 : Representation::Tagged(); |
4459 } | 4462 } |
4460 }; | 4463 }; |
4461 | 4464 |
4462 | 4465 |
4466 enum LoadKeyedHoleMode { | |
4467 NEVER_RETURN_HOLE, | |
4468 ALLOW_RETURN_HOLE | |
4469 }; | |
4470 | |
4471 | |
4463 class HLoadKeyed | 4472 class HLoadKeyed |
4464 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 4473 : public HTemplateInstruction<3>, public ArrayInstructionInterface { |
4465 public: | 4474 public: |
4466 HLoadKeyed(HValue* obj, | 4475 HLoadKeyed(HValue* obj, |
4467 HValue* key, | 4476 HValue* key, |
4468 HValue* dependency, | 4477 HValue* dependency, |
4469 ElementsKind elements_kind) | 4478 ElementsKind elements_kind, |
4479 LoadKeyedHoleMode mode = NEVER_RETURN_HOLE) | |
4470 : bit_field_(0) { | 4480 : bit_field_(0) { |
4471 bit_field_ = ElementsKindField::encode(elements_kind); | 4481 bit_field_ = ElementsKindField::encode(elements_kind) | |
4482 HoleModeField::encode(mode); | |
4472 | 4483 |
4473 SetOperandAt(0, obj); | 4484 SetOperandAt(0, obj); |
4474 SetOperandAt(1, key); | 4485 SetOperandAt(1, key); |
4475 SetOperandAt(2, dependency != NULL ? dependency : obj); | 4486 SetOperandAt(2, dependency != NULL ? dependency : obj); |
4476 | 4487 |
4477 if (!is_external()) { | 4488 if (!is_external()) { |
4478 // I can detect the case between storing double (holey and fast) and | 4489 // I can detect the case between storing double (holey and fast) and |
4479 // smi/object by looking at elements_kind_. | 4490 // smi/object by looking at elements_kind_. |
4480 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || | 4491 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || |
4481 IsFastDoubleElementsKind(elements_kind)); | 4492 IsFastDoubleElementsKind(elements_kind)); |
4482 | 4493 |
4483 if (IsFastSmiOrObjectElementsKind(elements_kind)) { | 4494 if (IsFastSmiOrObjectElementsKind(elements_kind)) { |
4484 if (IsFastSmiElementsKind(elements_kind) && | 4495 if (IsFastSmiElementsKind(elements_kind)) { |
4485 IsFastPackedElementsKind(elements_kind)) { | |
4486 set_type(HType::Smi()); | 4496 set_type(HType::Smi()); |
4487 } | 4497 } |
4488 | 4498 |
4489 set_representation(Representation::Tagged()); | 4499 set_representation(Representation::Tagged()); |
4490 SetGVNFlag(kDependsOnArrayElements); | 4500 SetGVNFlag(kDependsOnArrayElements); |
4491 } else { | 4501 } else { |
4492 set_representation(Representation::Double()); | 4502 set_representation(Representation::Double()); |
4493 SetGVNFlag(kDependsOnDoubleArrayElements); | 4503 SetGVNFlag(kDependsOnDoubleArrayElements); |
4494 } | 4504 } |
4495 } else { | 4505 } else { |
(...skipping 28 matching lines...) Expand all Loading... | |
4524 } | 4534 } |
4525 HValue* GetKey() { return key(); } | 4535 HValue* GetKey() { return key(); } |
4526 void SetKey(HValue* key) { SetOperandAt(1, key); } | 4536 void SetKey(HValue* key) { SetOperandAt(1, key); } |
4527 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } | 4537 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } |
4528 void SetDehoisted(bool is_dehoisted) { | 4538 void SetDehoisted(bool is_dehoisted) { |
4529 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); | 4539 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); |
4530 } | 4540 } |
4531 ElementsKind elements_kind() const { | 4541 ElementsKind elements_kind() const { |
4532 return ElementsKindField::decode(bit_field_); | 4542 return ElementsKindField::decode(bit_field_); |
4533 } | 4543 } |
4544 LoadKeyedHoleMode hole_mode() const { | |
4545 return HoleModeField::decode(bit_field_); | |
4546 } | |
4534 | 4547 |
4535 virtual Representation RequiredInputRepresentation(int index) { | 4548 virtual Representation RequiredInputRepresentation(int index) { |
4536 // kind_fast: tagged[int32] (none) | 4549 // kind_fast: tagged[int32] (none) |
4537 // kind_double: tagged[int32] (none) | 4550 // kind_double: tagged[int32] (none) |
4538 // kind_external: external[int32] (none) | 4551 // kind_external: external[int32] (none) |
4539 if (index == 0) { | 4552 if (index == 0) { |
4540 return is_external() ? Representation::External() | 4553 return is_external() ? Representation::External() |
4541 : Representation::Tagged(); | 4554 : Representation::Tagged(); |
4542 } | 4555 } |
4543 if (index == 1) { | 4556 if (index == 1) { |
4544 return ArrayInstructionInterface::KeyedAccessIndexRequirement( | 4557 return ArrayInstructionInterface::KeyedAccessIndexRequirement( |
4545 OperandAt(1)->representation()); | 4558 OperandAt(1)->representation()); |
4546 } | 4559 } |
4547 return Representation::None(); | 4560 return Representation::None(); |
4548 } | 4561 } |
4549 | 4562 |
4550 virtual Representation observed_input_representation(int index) { | 4563 virtual Representation observed_input_representation(int index) { |
4551 return RequiredInputRepresentation(index); | 4564 return RequiredInputRepresentation(index); |
4552 } | 4565 } |
4553 | 4566 |
4554 virtual void PrintDataTo(StringStream* stream); | 4567 virtual void PrintDataTo(StringStream* stream); |
4555 | 4568 |
4569 bool CanReturnHole() const; | |
4556 bool RequiresHoleCheck() const; | 4570 bool RequiresHoleCheck() const; |
4557 | 4571 |
4558 virtual Range* InferRange(Zone* zone); | 4572 virtual Range* InferRange(Zone* zone); |
4559 | 4573 |
4560 DECLARE_CONCRETE_INSTRUCTION(LoadKeyed) | 4574 DECLARE_CONCRETE_INSTRUCTION(LoadKeyed) |
4561 | 4575 |
4562 protected: | 4576 protected: |
4563 virtual bool DataEquals(HValue* other) { | 4577 virtual bool DataEquals(HValue* other) { |
4564 if (!other->IsLoadKeyed()) return false; | 4578 if (!other->IsLoadKeyed()) return false; |
4565 HLoadKeyed* other_load = HLoadKeyed::cast(other); | 4579 HLoadKeyed* other_load = HLoadKeyed::cast(other); |
4566 | 4580 |
4567 if (IsDehoisted() && index_offset() != other_load->index_offset()) | 4581 if (IsDehoisted() && index_offset() != other_load->index_offset()) |
4568 return false; | 4582 return false; |
4569 return elements_kind() == other_load->elements_kind(); | 4583 return elements_kind() == other_load->elements_kind(); |
4570 } | 4584 } |
4571 | 4585 |
4572 private: | 4586 private: |
4573 virtual bool IsDeletable() const { | 4587 virtual bool IsDeletable() const { |
4574 return !RequiresHoleCheck(); | 4588 return !RequiresHoleCheck(); |
4575 } | 4589 } |
4576 | 4590 |
4577 // Establish some checks around our packed fields | 4591 // Establish some checks around our packed fields |
4578 enum LoadKeyedBits { | 4592 enum LoadKeyedBits { |
4579 kBitsForElementsKind = 5, | 4593 kBitsForElementsKind = 5, |
4580 kBitsForIndexOffset = 26, | 4594 kBitsForHoleMode = 1, |
4595 kBitsForIndexOffset = 25, | |
4581 kBitsForIsDehoisted = 1, | 4596 kBitsForIsDehoisted = 1, |
4582 | 4597 |
4583 kStartElementsKind = 0, | 4598 kStartElementsKind = 0, |
4584 kStartIndexOffset = kStartElementsKind + kBitsForElementsKind, | 4599 kStartHoleMode = kStartElementsKind + kBitsForElementsKind, |
4600 kStartIndexOffset = kStartHoleMode + kBitsForHoleMode, | |
4585 kStartIsDehoisted = kStartIndexOffset + kBitsForIndexOffset | 4601 kStartIsDehoisted = kStartIndexOffset + kBitsForIndexOffset |
4586 }; | 4602 }; |
4587 | 4603 |
4588 STATIC_ASSERT((kBitsForElementsKind + kBitsForIndexOffset + | 4604 STATIC_ASSERT((kBitsForElementsKind + kBitsForIndexOffset + |
4589 kBitsForIsDehoisted) <= sizeof(uint32_t)*8); | 4605 kBitsForIsDehoisted) <= sizeof(uint32_t)*8); |
4590 STATIC_ASSERT(kElementsKindCount <= (1 << kBitsForElementsKind)); | 4606 STATIC_ASSERT(kElementsKindCount <= (1 << kBitsForElementsKind)); |
4591 class ElementsKindField: | 4607 class ElementsKindField: |
4592 public BitField<ElementsKind, kStartElementsKind, kBitsForElementsKind> | 4608 public BitField<ElementsKind, kStartElementsKind, kBitsForElementsKind> |
4593 {}; // NOLINT | 4609 {}; // NOLINT |
4610 class HoleModeField: | |
4611 public BitField<LoadKeyedHoleMode, kStartHoleMode, kBitsForHoleMode> | |
4612 {}; // NOLINT | |
4594 class IndexOffsetField: | 4613 class IndexOffsetField: |
4595 public BitField<uint32_t, kStartIndexOffset, kBitsForIndexOffset> | 4614 public BitField<uint32_t, kStartIndexOffset, kBitsForIndexOffset> |
4596 {}; // NOLINT | 4615 {}; // NOLINT |
4597 class IsDehoistedField: | 4616 class IsDehoistedField: |
4598 public BitField<bool, kStartIsDehoisted, kBitsForIsDehoisted> | 4617 public BitField<bool, kStartIsDehoisted, kBitsForIsDehoisted> |
4599 {}; // NOLINT | 4618 {}; // NOLINT |
4600 uint32_t bit_field_; | 4619 uint32_t bit_field_; |
4601 }; | 4620 }; |
4602 | 4621 |
4603 | 4622 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4722 Handle<String> name_; | 4741 Handle<String> name_; |
4723 StrictModeFlag strict_mode_flag_; | 4742 StrictModeFlag strict_mode_flag_; |
4724 }; | 4743 }; |
4725 | 4744 |
4726 | 4745 |
4727 class HStoreKeyed | 4746 class HStoreKeyed |
4728 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 4747 : public HTemplateInstruction<3>, public ArrayInstructionInterface { |
4729 public: | 4748 public: |
4730 HStoreKeyed(HValue* obj, HValue* key, HValue* val, | 4749 HStoreKeyed(HValue* obj, HValue* key, HValue* val, |
4731 ElementsKind elements_kind) | 4750 ElementsKind elements_kind) |
4732 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { | 4751 : elements_kind_(elements_kind), |
4752 index_offset_(0), | |
4753 is_dehoisted_(false), | |
4754 new_space_dominator_(NULL) { | |
4733 SetOperandAt(0, obj); | 4755 SetOperandAt(0, obj); |
4734 SetOperandAt(1, key); | 4756 SetOperandAt(1, key); |
4735 SetOperandAt(2, val); | 4757 SetOperandAt(2, val); |
4736 | 4758 |
4759 if (IsFastObjectElementsKind(elements_kind)) { | |
4760 SetFlag(kTrackSideEffectDominators); | |
4761 SetGVNFlag(kDependsOnNewSpacePromotion); | |
4762 } | |
4737 if (is_external()) { | 4763 if (is_external()) { |
4738 SetGVNFlag(kChangesSpecializedArrayElements); | 4764 SetGVNFlag(kChangesSpecializedArrayElements); |
4739 } else if (IsFastDoubleElementsKind(elements_kind)) { | 4765 } else if (IsFastDoubleElementsKind(elements_kind)) { |
4740 SetGVNFlag(kChangesDoubleArrayElements); | 4766 SetGVNFlag(kChangesDoubleArrayElements); |
4741 SetFlag(kDeoptimizeOnUndefined); | 4767 SetFlag(kDeoptimizeOnUndefined); |
4742 } else { | 4768 } else { |
4743 SetGVNFlag(kChangesArrayElements); | 4769 SetGVNFlag(kChangesArrayElements); |
4744 } | 4770 } |
4745 | 4771 |
4746 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. | 4772 // 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_); | 4820 return IsFastSmiElementsKind(elements_kind_); |
4795 } | 4821 } |
4796 ElementsKind elements_kind() const { return elements_kind_; } | 4822 ElementsKind elements_kind() const { return elements_kind_; } |
4797 uint32_t index_offset() { return index_offset_; } | 4823 uint32_t index_offset() { return index_offset_; } |
4798 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | 4824 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } |
4799 HValue* GetKey() { return key(); } | 4825 HValue* GetKey() { return key(); } |
4800 void SetKey(HValue* key) { SetOperandAt(1, key); } | 4826 void SetKey(HValue* key) { SetOperandAt(1, key); } |
4801 bool IsDehoisted() { return is_dehoisted_; } | 4827 bool IsDehoisted() { return is_dehoisted_; } |
4802 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | 4828 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } |
4803 | 4829 |
4830 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) { | |
4831 ASSERT(side_effect == kChangesNewSpacePromotion); | |
4832 new_space_dominator_ = dominator; | |
4833 } | |
4834 | |
4835 HValue* new_space_dominator() const { return new_space_dominator_; } | |
4836 | |
4804 bool NeedsWriteBarrier() { | 4837 bool NeedsWriteBarrier() { |
4805 if (value_is_smi()) { | 4838 if (value_is_smi()) { |
4806 return false; | 4839 return false; |
4807 } else { | 4840 } else { |
4808 return StoringValueNeedsWriteBarrier(value()); | 4841 return StoringValueNeedsWriteBarrier(value()) && |
4842 ReceiverObjectNeedsWriteBarrier(elements(), new_space_dominator()); | |
4809 } | 4843 } |
4810 } | 4844 } |
4811 | 4845 |
4812 bool NeedsCanonicalization(); | 4846 bool NeedsCanonicalization(); |
4813 | 4847 |
4814 virtual void PrintDataTo(StringStream* stream); | 4848 virtual void PrintDataTo(StringStream* stream); |
4815 | 4849 |
4816 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) | 4850 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) |
4817 | 4851 |
4818 private: | 4852 private: |
4819 ElementsKind elements_kind_; | 4853 ElementsKind elements_kind_; |
4820 uint32_t index_offset_; | 4854 uint32_t index_offset_; |
4821 bool is_dehoisted_; | 4855 bool is_dehoisted_; |
4856 HValue* new_space_dominator_; | |
4822 }; | 4857 }; |
4823 | 4858 |
4824 | 4859 |
4825 class HStoreKeyedGeneric: public HTemplateInstruction<4> { | 4860 class HStoreKeyedGeneric: public HTemplateInstruction<4> { |
4826 public: | 4861 public: |
4827 HStoreKeyedGeneric(HValue* context, | 4862 HStoreKeyedGeneric(HValue* context, |
4828 HValue* object, | 4863 HValue* object, |
4829 HValue* key, | 4864 HValue* key, |
4830 HValue* value, | 4865 HValue* value, |
4831 StrictModeFlag strict_mode_flag) | 4866 StrictModeFlag strict_mode_flag) |
(...skipping 18 matching lines...) Expand all Loading... | |
4850 | 4885 |
4851 virtual void PrintDataTo(StringStream* stream); | 4886 virtual void PrintDataTo(StringStream* stream); |
4852 | 4887 |
4853 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric) | 4888 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric) |
4854 | 4889 |
4855 private: | 4890 private: |
4856 StrictModeFlag strict_mode_flag_; | 4891 StrictModeFlag strict_mode_flag_; |
4857 }; | 4892 }; |
4858 | 4893 |
4859 | 4894 |
4860 class HTransitionElementsKind: public HTemplateInstruction<1> { | 4895 class HTransitionElementsKind: public HTemplateInstruction<2> { |
4861 public: | 4896 public: |
4862 HTransitionElementsKind(HValue* object, | 4897 HTransitionElementsKind(HValue* context, |
4898 HValue* object, | |
4863 Handle<Map> original_map, | 4899 Handle<Map> original_map, |
4864 Handle<Map> transitioned_map) | 4900 Handle<Map> transitioned_map) |
4865 : original_map_(original_map), | 4901 : original_map_(original_map), |
4866 transitioned_map_(transitioned_map), | 4902 transitioned_map_(transitioned_map), |
4867 from_kind_(original_map->elements_kind()), | 4903 from_kind_(original_map->elements_kind()), |
4868 to_kind_(transitioned_map->elements_kind()) { | 4904 to_kind_(transitioned_map->elements_kind()) { |
4869 SetOperandAt(0, object); | 4905 SetOperandAt(0, object); |
4906 SetOperandAt(1, context); | |
4870 SetFlag(kUseGVN); | 4907 SetFlag(kUseGVN); |
4871 SetGVNFlag(kChangesElementsKind); | 4908 SetGVNFlag(kChangesElementsKind); |
4872 if (original_map->has_fast_double_elements()) { | 4909 if (original_map->has_fast_double_elements()) { |
4873 SetGVNFlag(kChangesElementsPointer); | 4910 SetGVNFlag(kChangesElementsPointer); |
4874 SetGVNFlag(kChangesNewSpacePromotion); | 4911 SetGVNFlag(kChangesNewSpacePromotion); |
4875 } | 4912 } |
4876 if (transitioned_map->has_fast_double_elements()) { | 4913 if (transitioned_map->has_fast_double_elements()) { |
4877 SetGVNFlag(kChangesElementsPointer); | 4914 SetGVNFlag(kChangesElementsPointer); |
4878 SetGVNFlag(kChangesNewSpacePromotion); | 4915 SetGVNFlag(kChangesNewSpacePromotion); |
4879 } | 4916 } |
4880 set_representation(Representation::Tagged()); | 4917 set_representation(Representation::Tagged()); |
4881 } | 4918 } |
4882 | 4919 |
4883 virtual Representation RequiredInputRepresentation(int index) { | 4920 virtual Representation RequiredInputRepresentation(int index) { |
4884 return Representation::Tagged(); | 4921 return Representation::Tagged(); |
4885 } | 4922 } |
4886 | 4923 |
4887 HValue* object() { return OperandAt(0); } | 4924 HValue* object() { return OperandAt(0); } |
4925 HValue* context() { return OperandAt(1); } | |
4888 Handle<Map> original_map() { return original_map_; } | 4926 Handle<Map> original_map() { return original_map_; } |
4889 Handle<Map> transitioned_map() { return transitioned_map_; } | 4927 Handle<Map> transitioned_map() { return transitioned_map_; } |
4890 ElementsKind from_kind() { return from_kind_; } | 4928 ElementsKind from_kind() { return from_kind_; } |
4891 ElementsKind to_kind() { return to_kind_; } | 4929 ElementsKind to_kind() { return to_kind_; } |
4892 | 4930 |
4893 virtual void PrintDataTo(StringStream* stream); | 4931 virtual void PrintDataTo(StringStream* stream); |
4894 | 4932 |
4895 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind) | 4933 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind) |
4896 | 4934 |
4897 protected: | 4935 protected: |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5064 DECLARE_CONCRETE_INSTRUCTION(AllocateObject) | 5102 DECLARE_CONCRETE_INSTRUCTION(AllocateObject) |
5065 | 5103 |
5066 private: | 5104 private: |
5067 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. | 5105 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. |
5068 // virtual bool IsDeletable() const { return true; } | 5106 // virtual bool IsDeletable() const { return true; } |
5069 | 5107 |
5070 Handle<JSFunction> constructor_; | 5108 Handle<JSFunction> constructor_; |
5071 }; | 5109 }; |
5072 | 5110 |
5073 | 5111 |
5112 class HAllocate: public HTemplateInstruction<2> { | |
5113 public: | |
5114 enum Flags { | |
5115 CAN_ALLOCATE_IN_NEW_SPACE = 1 << 0, | |
5116 CAN_ALLOCATE_IN_OLD_SPACE = 1 << 1, | |
Michael Starzinger
2013/01/31 13:15:10
The old-space flag will need to indicate which old
danno
2013/01/31 15:53:25
Done.
| |
5117 ALLOCATE_DOUBLE_ALIGNED = 1 << 2, | |
5118 ALLOCATE_IN_ANY_SPACE = CAN_ALLOCATE_IN_NEW_SPACE | | |
5119 CAN_ALLOCATE_IN_OLD_SPACE | |
5120 }; | |
5121 | |
5122 HAllocate(HValue* context, HValue* size, HType type, Flags flags) | |
5123 : type_(type), | |
5124 flags_(flags) { | |
5125 ASSERT((flags & CAN_ALLOCATE_IN_OLD_SPACE) == 0); // unimplemented | |
5126 SetOperandAt(0, context); | |
5127 SetOperandAt(1, size); | |
5128 set_representation(Representation::Tagged()); | |
5129 SetGVNFlag(kChangesNewSpacePromotion); | |
5130 } | |
5131 | |
5132 HValue* context() { return OperandAt(0); } | |
5133 HValue* size() { return OperandAt(1); } | |
5134 | |
5135 virtual Representation RequiredInputRepresentation(int index) { | |
5136 if (index == 0) { | |
5137 return Representation::Tagged(); | |
5138 } else { | |
5139 return Representation::Integer32(); | |
5140 } | |
5141 } | |
5142 | |
5143 virtual HType CalculateInferredType(); | |
5144 | |
5145 bool CanAllocateInNewSpace() const { | |
5146 return (flags_ & CAN_ALLOCATE_IN_NEW_SPACE) != 0; | |
5147 } | |
5148 | |
5149 bool CanAllocateInOldSpace() const { | |
5150 return (flags_ & CAN_ALLOCATE_IN_OLD_SPACE) != 0; | |
5151 } | |
5152 | |
5153 bool MustAllocateDoubleAligned() const { | |
5154 return (flags_ & ALLOCATE_DOUBLE_ALIGNED) != 0; | |
5155 } | |
5156 | |
5157 DECLARE_CONCRETE_INSTRUCTION(Allocate) | |
5158 | |
5159 private: | |
5160 HType type_; | |
5161 Flags flags_; | |
5162 }; | |
5163 | |
5164 | |
5074 template <int V> | 5165 template <int V> |
5075 class HMaterializedLiteral: public HTemplateInstruction<V> { | 5166 class HMaterializedLiteral: public HTemplateInstruction<V> { |
5076 public: | 5167 public: |
5077 HMaterializedLiteral<V>(int index, int depth, AllocationSiteMode mode) | 5168 HMaterializedLiteral<V>(int index, int depth, AllocationSiteMode mode) |
5078 : literal_index_(index), depth_(depth), allocation_site_mode_(mode) { | 5169 : literal_index_(index), depth_(depth), allocation_site_mode_(mode) { |
5079 this->set_representation(Representation::Tagged()); | 5170 this->set_representation(Representation::Tagged()); |
5080 } | 5171 } |
5081 | 5172 |
5082 HMaterializedLiteral<V>(int index, int depth) | 5173 HMaterializedLiteral<V>(int index, int depth) |
5083 : literal_index_(index), depth_(depth), | 5174 : literal_index_(index), depth_(depth), |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5297 return Representation::Tagged(); | 5388 return Representation::Tagged(); |
5298 } | 5389 } |
5299 | 5390 |
5300 DECLARE_CONCRETE_INSTRUCTION(Typeof) | 5391 DECLARE_CONCRETE_INSTRUCTION(Typeof) |
5301 | 5392 |
5302 private: | 5393 private: |
5303 virtual bool IsDeletable() const { return true; } | 5394 virtual bool IsDeletable() const { return true; } |
5304 }; | 5395 }; |
5305 | 5396 |
5306 | 5397 |
5398 class HTrapAllocationMemento : public HTemplateInstruction<2> { | |
5399 public: | |
5400 explicit HTrapAllocationMemento(HValue* obj) { | |
5401 SetOperandAt(0, obj); | |
5402 } | |
5403 | |
5404 virtual Representation RequiredInputRepresentation(int index) { | |
5405 return Representation::Tagged(); | |
5406 } | |
5407 | |
5408 HValue* object() { return OperandAt(0); } | |
5409 | |
5410 DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento) | |
5411 }; | |
5412 | |
5413 | |
5307 class HToFastProperties: public HUnaryOperation { | 5414 class HToFastProperties: public HUnaryOperation { |
5308 public: | 5415 public: |
5309 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) { | 5416 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) { |
5310 // This instruction is not marked as having side effects, but | 5417 // This instruction is not marked as having side effects, but |
5311 // changes the map of the input operand. Use it only when creating | 5418 // changes the map of the input operand. Use it only when creating |
5312 // object literals. | 5419 // object literals. |
5313 ASSERT(value->IsObjectLiteral() || value->IsFastLiteral()); | 5420 ASSERT(value->IsObjectLiteral() || value->IsFastLiteral()); |
5314 set_representation(Representation::Tagged()); | 5421 set_representation(Representation::Tagged()); |
5315 } | 5422 } |
5316 | 5423 |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5567 virtual bool IsDeletable() const { return true; } | 5674 virtual bool IsDeletable() const { return true; } |
5568 }; | 5675 }; |
5569 | 5676 |
5570 | 5677 |
5571 #undef DECLARE_INSTRUCTION | 5678 #undef DECLARE_INSTRUCTION |
5572 #undef DECLARE_CONCRETE_INSTRUCTION | 5679 #undef DECLARE_CONCRETE_INSTRUCTION |
5573 | 5680 |
5574 } } // namespace v8::internal | 5681 } } // namespace v8::internal |
5575 | 5682 |
5576 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 5683 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |