Chromium Code Reviews| 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 |