| 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 1416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1427 } | 1427 } |
| 1428 | 1428 |
| 1429 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 1429 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 1430 | 1430 |
| 1431 DECLARE_CONCRETE_INSTRUCTION(Goto) | 1431 DECLARE_CONCRETE_INSTRUCTION(Goto) |
| 1432 }; | 1432 }; |
| 1433 | 1433 |
| 1434 | 1434 |
| 1435 class HDeoptimize V8_FINAL : public HTemplateControlInstruction<1, 0> { | 1435 class HDeoptimize V8_FINAL : public HTemplateControlInstruction<1, 0> { |
| 1436 public: | 1436 public: |
| 1437 static HInstruction* New(Zone* zone, | 1437 static HDeoptimize* New(Zone* zone, |
| 1438 HValue* context, | 1438 HValue* context, |
| 1439 const char* reason, | 1439 const char* reason, |
| 1440 Deoptimizer::BailoutType type, | 1440 Deoptimizer::BailoutType type, |
| 1441 HBasicBlock* unreachable_continuation) { | 1441 HBasicBlock* unreachable_continuation) { |
| 1442 return new(zone) HDeoptimize(reason, type, unreachable_continuation); | 1442 return new(zone) HDeoptimize(reason, type, unreachable_continuation); |
| 1443 } | 1443 } |
| 1444 | 1444 |
| 1445 virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE { | 1445 virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE { |
| 1446 *block = NULL; | 1446 *block = NULL; |
| 1447 return true; | 1447 return true; |
| 1448 } | 1448 } |
| 1449 | 1449 |
| 1450 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 1450 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 1451 return Representation::None(); | 1451 return Representation::None(); |
| (...skipping 1179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2631 if (index == 0) { | 2631 if (index == 0) { |
| 2632 return Representation::Tagged(); | 2632 return Representation::Tagged(); |
| 2633 } else { | 2633 } else { |
| 2634 switch (op_) { | 2634 switch (op_) { |
| 2635 case kMathFloor: | 2635 case kMathFloor: |
| 2636 case kMathRound: | 2636 case kMathRound: |
| 2637 case kMathSqrt: | 2637 case kMathSqrt: |
| 2638 case kMathPowHalf: | 2638 case kMathPowHalf: |
| 2639 case kMathLog: | 2639 case kMathLog: |
| 2640 case kMathExp: | 2640 case kMathExp: |
| 2641 case kMathSin: | |
| 2642 case kMathCos: | |
| 2643 case kMathTan: | |
| 2644 return Representation::Double(); | 2641 return Representation::Double(); |
| 2645 case kMathAbs: | 2642 case kMathAbs: |
| 2646 return representation(); | 2643 return representation(); |
| 2647 default: | 2644 default: |
| 2648 UNREACHABLE(); | 2645 UNREACHABLE(); |
| 2649 return Representation::None(); | 2646 return Representation::None(); |
| 2650 } | 2647 } |
| 2651 } | 2648 } |
| 2652 } | 2649 } |
| 2653 | 2650 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2678 set_representation(Representation::Integer32()); | 2675 set_representation(Representation::Integer32()); |
| 2679 break; | 2676 break; |
| 2680 case kMathAbs: | 2677 case kMathAbs: |
| 2681 // Not setting representation here: it is None intentionally. | 2678 // Not setting representation here: it is None intentionally. |
| 2682 SetFlag(kFlexibleRepresentation); | 2679 SetFlag(kFlexibleRepresentation); |
| 2683 // TODO(svenpanne) This flag is actually only needed if representation() | 2680 // TODO(svenpanne) This flag is actually only needed if representation() |
| 2684 // is tagged, and not when it is an unboxed double or unboxed integer. | 2681 // is tagged, and not when it is an unboxed double or unboxed integer. |
| 2685 SetGVNFlag(kChangesNewSpacePromotion); | 2682 SetGVNFlag(kChangesNewSpacePromotion); |
| 2686 break; | 2683 break; |
| 2687 case kMathLog: | 2684 case kMathLog: |
| 2688 case kMathSin: | |
| 2689 case kMathCos: | |
| 2690 case kMathTan: | |
| 2691 set_representation(Representation::Double()); | 2685 set_representation(Representation::Double()); |
| 2692 // These operations use the TranscendentalCache, so they may allocate. | 2686 // These operations use the TranscendentalCache, so they may allocate. |
| 2693 SetGVNFlag(kChangesNewSpacePromotion); | 2687 SetGVNFlag(kChangesNewSpacePromotion); |
| 2694 break; | 2688 break; |
| 2695 case kMathExp: | 2689 case kMathExp: |
| 2696 case kMathSqrt: | 2690 case kMathSqrt: |
| 2697 case kMathPowHalf: | 2691 case kMathPowHalf: |
| 2698 set_representation(Representation::Double()); | 2692 set_representation(Representation::Double()); |
| 2699 break; | 2693 break; |
| 2700 default: | 2694 default: |
| (...skipping 1321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4022 virtual int RedefinedOperandIndex() V8_OVERRIDE { return 0; } | 4016 virtual int RedefinedOperandIndex() V8_OVERRIDE { return 0; } |
| 4023 virtual bool IsPurelyInformativeDefinition() V8_OVERRIDE { | 4017 virtual bool IsPurelyInformativeDefinition() V8_OVERRIDE { |
| 4024 return skip_check(); | 4018 return skip_check(); |
| 4025 } | 4019 } |
| 4026 | 4020 |
| 4027 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) | 4021 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) |
| 4028 | 4022 |
| 4029 protected: | 4023 protected: |
| 4030 friend class HBoundsCheckBaseIndexInformation; | 4024 friend class HBoundsCheckBaseIndexInformation; |
| 4031 | 4025 |
| 4026 virtual Range* InferRange(Zone* zone) V8_OVERRIDE; |
| 4027 |
| 4032 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } | 4028 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } |
| 4033 bool skip_check_; | 4029 bool skip_check_; |
| 4034 HValue* base_; | 4030 HValue* base_; |
| 4035 int offset_; | 4031 int offset_; |
| 4036 int scale_; | 4032 int scale_; |
| 4037 bool allow_equality_; | 4033 bool allow_equality_; |
| 4038 | 4034 |
| 4039 private: | 4035 private: |
| 4040 // Normally HBoundsCheck should be created using the | 4036 // Normally HBoundsCheck should be created using the |
| 4041 // HGraphBuilder::AddBoundsCheck() helper. | 4037 // HGraphBuilder::AddBoundsCheck() helper. |
| (...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4725 | 4721 |
| 4726 class HAdd V8_FINAL : public HArithmeticBinaryOperation { | 4722 class HAdd V8_FINAL : public HArithmeticBinaryOperation { |
| 4727 public: | 4723 public: |
| 4728 static HInstruction* New(Zone* zone, | 4724 static HInstruction* New(Zone* zone, |
| 4729 HValue* context, | 4725 HValue* context, |
| 4730 HValue* left, | 4726 HValue* left, |
| 4731 HValue* right); | 4727 HValue* right); |
| 4732 | 4728 |
| 4733 // Add is only commutative if two integer values are added and not if two | 4729 // Add is only commutative if two integer values are added and not if two |
| 4734 // tagged values are added (because it might be a String concatenation). | 4730 // tagged values are added (because it might be a String concatenation). |
| 4731 // We also do not commute (pointer + offset). |
| 4735 virtual bool IsCommutative() const V8_OVERRIDE { | 4732 virtual bool IsCommutative() const V8_OVERRIDE { |
| 4736 return !representation().IsTagged(); | 4733 return !representation().IsTagged() && !representation().IsExternal(); |
| 4737 } | 4734 } |
| 4738 | 4735 |
| 4739 virtual HValue* EnsureAndPropagateNotMinusZero( | 4736 virtual HValue* EnsureAndPropagateNotMinusZero( |
| 4740 BitVector* visited) V8_OVERRIDE; | 4737 BitVector* visited) V8_OVERRIDE; |
| 4741 | 4738 |
| 4742 virtual HValue* Canonicalize() V8_OVERRIDE; | 4739 virtual HValue* Canonicalize() V8_OVERRIDE; |
| 4743 | 4740 |
| 4744 virtual bool TryDecompose(DecompositionResult* decomposition) V8_OVERRIDE { | 4741 virtual bool TryDecompose(DecompositionResult* decomposition) V8_OVERRIDE { |
| 4745 if (left()->IsInteger32Constant()) { | 4742 if (left()->IsInteger32Constant()) { |
| 4746 decomposition->Apply(right(), left()->GetInteger32Constant()); | 4743 decomposition->Apply(right(), left()->GetInteger32Constant()); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 4762 (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved() || | 4759 (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved() || |
| 4763 left()->ToStringCanBeObserved() || right()->ToStringCanBeObserved())) { | 4760 left()->ToStringCanBeObserved() || right()->ToStringCanBeObserved())) { |
| 4764 SetAllSideEffects(); | 4761 SetAllSideEffects(); |
| 4765 ClearFlag(kUseGVN); | 4762 ClearFlag(kUseGVN); |
| 4766 } else { | 4763 } else { |
| 4767 ClearAllSideEffects(); | 4764 ClearAllSideEffects(); |
| 4768 SetFlag(kUseGVN); | 4765 SetFlag(kUseGVN); |
| 4769 } | 4766 } |
| 4770 } | 4767 } |
| 4771 | 4768 |
| 4769 virtual Representation RepresentationFromInputs() V8_OVERRIDE; |
| 4770 |
| 4771 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE; |
| 4772 |
| 4772 DECLARE_CONCRETE_INSTRUCTION(Add) | 4773 DECLARE_CONCRETE_INSTRUCTION(Add) |
| 4773 | 4774 |
| 4774 protected: | 4775 protected: |
| 4775 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } | 4776 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } |
| 4776 | 4777 |
| 4777 virtual Range* InferRange(Zone* zone) V8_OVERRIDE; | 4778 virtual Range* InferRange(Zone* zone) V8_OVERRIDE; |
| 4778 | 4779 |
| 4779 private: | 4780 private: |
| 4780 HAdd(HValue* context, HValue* left, HValue* right) | 4781 HAdd(HValue* context, HValue* left, HValue* right) |
| 4781 : HArithmeticBinaryOperation(context, left, right) { | 4782 : HArithmeticBinaryOperation(context, left, right) { |
| (...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5425 }; | 5426 }; |
| 5426 | 5427 |
| 5427 | 5428 |
| 5428 class HAllocate V8_FINAL : public HTemplateInstruction<2> { | 5429 class HAllocate V8_FINAL : public HTemplateInstruction<2> { |
| 5429 public: | 5430 public: |
| 5430 static HAllocate* New(Zone* zone, | 5431 static HAllocate* New(Zone* zone, |
| 5431 HValue* context, | 5432 HValue* context, |
| 5432 HValue* size, | 5433 HValue* size, |
| 5433 HType type, | 5434 HType type, |
| 5434 PretenureFlag pretenure_flag, | 5435 PretenureFlag pretenure_flag, |
| 5435 InstanceType instance_type) { | 5436 InstanceType instance_type, |
| 5437 Handle<AllocationSite> allocation_site = |
| 5438 Handle<AllocationSite>::null()) { |
| 5436 return new(zone) HAllocate(context, size, type, pretenure_flag, | 5439 return new(zone) HAllocate(context, size, type, pretenure_flag, |
| 5437 instance_type); | 5440 instance_type, allocation_site); |
| 5438 } | 5441 } |
| 5439 | 5442 |
| 5440 // Maximum instance size for which allocations will be inlined. | 5443 // Maximum instance size for which allocations will be inlined. |
| 5441 static const int kMaxInlineSize = 64 * kPointerSize; | 5444 static const int kMaxInlineSize = 64 * kPointerSize; |
| 5442 | 5445 |
| 5443 HValue* context() { return OperandAt(0); } | 5446 HValue* context() { return OperandAt(0); } |
| 5444 HValue* size() { return OperandAt(1); } | 5447 HValue* size() { return OperandAt(1); } |
| 5445 | 5448 |
| 5446 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 5449 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 5447 if (index == 0) { | 5450 if (index == 0) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5500 ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1, | 5503 ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1, |
| 5501 ALLOCATE_IN_OLD_POINTER_SPACE = 1 << 2, | 5504 ALLOCATE_IN_OLD_POINTER_SPACE = 1 << 2, |
| 5502 ALLOCATE_DOUBLE_ALIGNED = 1 << 3, | 5505 ALLOCATE_DOUBLE_ALIGNED = 1 << 3, |
| 5503 PREFILL_WITH_FILLER = 1 << 4 | 5506 PREFILL_WITH_FILLER = 1 << 4 |
| 5504 }; | 5507 }; |
| 5505 | 5508 |
| 5506 HAllocate(HValue* context, | 5509 HAllocate(HValue* context, |
| 5507 HValue* size, | 5510 HValue* size, |
| 5508 HType type, | 5511 HType type, |
| 5509 PretenureFlag pretenure_flag, | 5512 PretenureFlag pretenure_flag, |
| 5510 InstanceType instance_type) | 5513 InstanceType instance_type, |
| 5514 Handle<AllocationSite> allocation_site = |
| 5515 Handle<AllocationSite>::null()) |
| 5511 : HTemplateInstruction<2>(type), | 5516 : HTemplateInstruction<2>(type), |
| 5512 dominating_allocate_(NULL), | 5517 dominating_allocate_(NULL), |
| 5513 filler_free_space_size_(NULL), | 5518 filler_free_space_size_(NULL), |
| 5514 clear_next_map_word_(false) { | 5519 clear_next_map_word_(false) { |
| 5515 SetOperandAt(0, context); | 5520 SetOperandAt(0, context); |
| 5516 SetOperandAt(1, size); | 5521 SetOperandAt(1, size); |
| 5517 set_representation(Representation::Tagged()); | 5522 set_representation(Representation::Tagged()); |
| 5518 SetFlag(kTrackSideEffectDominators); | 5523 SetFlag(kTrackSideEffectDominators); |
| 5519 SetGVNFlag(kChangesNewSpacePromotion); | 5524 SetGVNFlag(kChangesNewSpacePromotion); |
| 5520 SetGVNFlag(kDependsOnNewSpacePromotion); | 5525 SetGVNFlag(kDependsOnNewSpacePromotion); |
| 5521 flags_ = pretenure_flag == TENURED | 5526 flags_ = pretenure_flag == TENURED |
| 5522 ? (Heap::TargetSpaceId(instance_type) == OLD_POINTER_SPACE | 5527 ? (Heap::TargetSpaceId(instance_type) == OLD_POINTER_SPACE |
| 5523 ? ALLOCATE_IN_OLD_POINTER_SPACE : ALLOCATE_IN_OLD_DATA_SPACE) | 5528 ? ALLOCATE_IN_OLD_POINTER_SPACE : ALLOCATE_IN_OLD_DATA_SPACE) |
| 5524 : ALLOCATE_IN_NEW_SPACE; | 5529 : ALLOCATE_IN_NEW_SPACE; |
| 5525 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) { | 5530 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) { |
| 5526 flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATE_DOUBLE_ALIGNED); | 5531 flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATE_DOUBLE_ALIGNED); |
| 5527 } | 5532 } |
| 5528 // We have to fill the allocated object with one word fillers if we do | 5533 // We have to fill the allocated object with one word fillers if we do |
| 5529 // not use allocation folding since some allocations may depend on each | 5534 // not use allocation folding since some allocations may depend on each |
| 5530 // other, i.e., have a pointer to each other. A GC in between these | 5535 // other, i.e., have a pointer to each other. A GC in between these |
| 5531 // allocations may leave such objects behind in a not completely initialized | 5536 // allocations may leave such objects behind in a not completely initialized |
| 5532 // state. | 5537 // state. |
| 5533 if (!FLAG_use_gvn || !FLAG_use_allocation_folding) { | 5538 if (!FLAG_use_gvn || !FLAG_use_allocation_folding) { |
| 5534 flags_ = static_cast<HAllocate::Flags>(flags_ | PREFILL_WITH_FILLER); | 5539 flags_ = static_cast<HAllocate::Flags>(flags_ | PREFILL_WITH_FILLER); |
| 5535 } | 5540 } |
| 5536 clear_next_map_word_ = pretenure_flag == NOT_TENURED && | 5541 clear_next_map_word_ = pretenure_flag == NOT_TENURED && |
| 5537 AllocationSite::CanTrack(instance_type); | 5542 AllocationSite::CanTrack(instance_type); |
| 5543 |
| 5544 if (FLAG_trace_pretenuring) { |
| 5545 PrintF("HAllocate with AllocationSite %p %s\n", |
| 5546 allocation_site.is_null() |
| 5547 ? static_cast<void*>(NULL) |
| 5548 : static_cast<void*>(*allocation_site), |
| 5549 pretenure_flag == TENURED ? "tenured" : "not tenured"); |
| 5550 } |
| 5538 } | 5551 } |
| 5539 | 5552 |
| 5540 void UpdateSize(HValue* size) { | 5553 void UpdateSize(HValue* size) { |
| 5541 SetOperandAt(1, size); | 5554 SetOperandAt(1, size); |
| 5542 } | 5555 } |
| 5543 | 5556 |
| 5544 HAllocate* GetFoldableDominator(HAllocate* dominator); | 5557 HAllocate* GetFoldableDominator(HAllocate* dominator); |
| 5545 | 5558 |
| 5546 void UpdateFreeSpaceFiller(int32_t filler_size); | 5559 void UpdateFreeSpaceFiller(int32_t filler_size); |
| 5547 | 5560 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5583 DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry) | 5596 DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry) |
| 5584 | 5597 |
| 5585 private: | 5598 private: |
| 5586 HStoreCodeEntry(HValue* function, HValue* code) { | 5599 HStoreCodeEntry(HValue* function, HValue* code) { |
| 5587 SetOperandAt(0, function); | 5600 SetOperandAt(0, function); |
| 5588 SetOperandAt(1, code); | 5601 SetOperandAt(1, code); |
| 5589 } | 5602 } |
| 5590 }; | 5603 }; |
| 5591 | 5604 |
| 5592 | 5605 |
| 5593 class HInnerAllocatedObject V8_FINAL: public HTemplateInstruction<1> { | 5606 class HInnerAllocatedObject V8_FINAL : public HTemplateInstruction<2> { |
| 5594 public: | 5607 public: |
| 5595 static HInnerAllocatedObject* New(Zone* zone, | 5608 static HInnerAllocatedObject* New(Zone* zone, |
| 5596 HValue* context, | 5609 HValue* context, |
| 5597 HValue* value, | 5610 HValue* value, |
| 5598 int offset, | 5611 HValue* offset, |
| 5599 HType type = HType::Tagged()) { | 5612 HType type = HType::Tagged()) { |
| 5600 return new(zone) HInnerAllocatedObject(value, offset, type); | 5613 return new(zone) HInnerAllocatedObject(value, offset, type); |
| 5601 } | 5614 } |
| 5602 | 5615 |
| 5603 HValue* base_object() { return OperandAt(0); } | 5616 HValue* base_object() { return OperandAt(0); } |
| 5604 int offset() { return offset_; } | 5617 HValue* offset() { return OperandAt(1); } |
| 5605 | 5618 |
| 5606 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 5619 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 5607 return Representation::Tagged(); | 5620 return index == 0 ? Representation::Tagged() : Representation::Integer32(); |
| 5608 } | 5621 } |
| 5609 | 5622 |
| 5610 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 5623 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 5611 | 5624 |
| 5612 DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject) | 5625 DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject) |
| 5613 | 5626 |
| 5614 private: | 5627 private: |
| 5615 HInnerAllocatedObject(HValue* value, int offset, HType type = HType::Tagged()) | 5628 HInnerAllocatedObject(HValue* value, |
| 5616 : HTemplateInstruction<1>(type), offset_(offset) { | 5629 HValue* offset, |
| 5630 HType type = HType::Tagged()) |
| 5631 : HTemplateInstruction<2>(type) { |
| 5617 ASSERT(value->IsAllocate()); | 5632 ASSERT(value->IsAllocate()); |
| 5618 SetOperandAt(0, value); | 5633 SetOperandAt(0, value); |
| 5634 SetOperandAt(1, offset); |
| 5619 set_type(type); | 5635 set_type(type); |
| 5620 set_representation(Representation::Tagged()); | 5636 set_representation(Representation::Tagged()); |
| 5621 } | 5637 } |
| 5622 | |
| 5623 int offset_; | |
| 5624 }; | 5638 }; |
| 5625 | 5639 |
| 5626 | 5640 |
| 5627 inline bool StoringValueNeedsWriteBarrier(HValue* value) { | 5641 inline bool StoringValueNeedsWriteBarrier(HValue* value) { |
| 5628 return !value->type().IsBoolean() | 5642 return !value->type().IsBoolean() |
| 5629 && !value->type().IsSmi() | 5643 && !value->type().IsSmi() |
| 5630 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable()); | 5644 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable()); |
| 5631 } | 5645 } |
| 5632 | 5646 |
| 5633 | 5647 |
| 5634 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, | 5648 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, |
| 5649 HValue* value, |
| 5635 HValue* new_space_dominator) { | 5650 HValue* new_space_dominator) { |
| 5636 if (object->IsInnerAllocatedObject()) { | 5651 while (object->IsInnerAllocatedObject()) { |
| 5637 return ReceiverObjectNeedsWriteBarrier( | 5652 object = HInnerAllocatedObject::cast(object)->base_object(); |
| 5638 HInnerAllocatedObject::cast(object)->base_object(), | |
| 5639 new_space_dominator); | |
| 5640 } | 5653 } |
| 5641 if (object->IsConstant() && HConstant::cast(object)->IsCell()) { | 5654 if (object->IsConstant() && HConstant::cast(object)->IsCell()) { |
| 5642 return false; | 5655 return false; |
| 5643 } | 5656 } |
| 5644 if (object->IsConstant() && | 5657 if (object->IsConstant() && |
| 5645 HConstant::cast(object)->HasExternalReferenceValue()) { | 5658 HConstant::cast(object)->HasExternalReferenceValue()) { |
| 5646 // Stores to external references require no write barriers | 5659 // Stores to external references require no write barriers |
| 5647 return false; | 5660 return false; |
| 5648 } | 5661 } |
| 5649 if (object != new_space_dominator) return true; | 5662 if (object != new_space_dominator) return true; |
| 5650 if (object->IsAllocate()) { | 5663 if (object->IsAllocate()) { |
| 5651 return !HAllocate::cast(object)->IsNewSpaceAllocation(); | 5664 // Stores to new space allocations require no write barriers if the object |
| 5665 // is the new space dominator. |
| 5666 if (HAllocate::cast(object)->IsNewSpaceAllocation()) { |
| 5667 return false; |
| 5668 } |
| 5669 // Likewise we don't need a write barrier if we store a value that |
| 5670 // originates from the same allocation (via allocation folding). |
| 5671 while (value->IsInnerAllocatedObject()) { |
| 5672 value = HInnerAllocatedObject::cast(value)->base_object(); |
| 5673 } |
| 5674 return object != value; |
| 5652 } | 5675 } |
| 5653 return true; | 5676 return true; |
| 5654 } | 5677 } |
| 5655 | 5678 |
| 5656 | 5679 |
| 5657 class HStoreGlobalCell V8_FINAL : public HUnaryOperation { | 5680 class HStoreGlobalCell V8_FINAL : public HUnaryOperation { |
| 5658 public: | 5681 public: |
| 5659 DECLARE_INSTRUCTION_FACTORY_P3(HStoreGlobalCell, HValue*, | 5682 DECLARE_INSTRUCTION_FACTORY_P3(HStoreGlobalCell, HValue*, |
| 5660 Handle<PropertyCell>, PropertyDetails); | 5683 Handle<PropertyCell>, PropertyDetails); |
| 5661 | 5684 |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5925 | 5948 |
| 5926 static HObjectAccess ForArrayLength(ElementsKind elements_kind) { | 5949 static HObjectAccess ForArrayLength(ElementsKind elements_kind) { |
| 5927 return HObjectAccess( | 5950 return HObjectAccess( |
| 5928 kArrayLengths, | 5951 kArrayLengths, |
| 5929 JSArray::kLengthOffset, | 5952 JSArray::kLengthOffset, |
| 5930 IsFastElementsKind(elements_kind) && | 5953 IsFastElementsKind(elements_kind) && |
| 5931 FLAG_track_fields | 5954 FLAG_track_fields |
| 5932 ? Representation::Smi() : Representation::Tagged()); | 5955 ? Representation::Smi() : Representation::Tagged()); |
| 5933 } | 5956 } |
| 5934 | 5957 |
| 5935 static HObjectAccess ForAllocationSiteOffset(int offset) { | 5958 static HObjectAccess ForAllocationSiteOffset(int offset); |
| 5936 ASSERT(offset >= HeapObject::kHeaderSize && offset < AllocationSite::kSize); | |
| 5937 return HObjectAccess(kInobject, offset); | |
| 5938 } | |
| 5939 | 5959 |
| 5940 static HObjectAccess ForAllocationSiteList() { | 5960 static HObjectAccess ForAllocationSiteList() { |
| 5941 return HObjectAccess(kExternalMemory, 0, Representation::Tagged()); | 5961 return HObjectAccess(kExternalMemory, 0, Representation::Tagged()); |
| 5942 } | 5962 } |
| 5943 | 5963 |
| 5944 static HObjectAccess ForFixedArrayLength() { | 5964 static HObjectAccess ForFixedArrayLength() { |
| 5945 return HObjectAccess( | 5965 return HObjectAccess( |
| 5946 kArrayLengths, | 5966 kArrayLengths, |
| 5947 FixedArray::kLengthOffset, | 5967 FixedArray::kLengthOffset, |
| 5948 FLAG_track_fields ? Representation::Smi() : Representation::Tagged()); | 5968 FLAG_track_fields ? Representation::Smi() : Representation::Tagged()); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6055 static HObjectAccess ForBackingStoreOffset(int offset, | 6075 static HObjectAccess ForBackingStoreOffset(int offset, |
| 6056 Representation representation = Representation::Tagged()); | 6076 Representation representation = Representation::Tagged()); |
| 6057 | 6077 |
| 6058 // Create an access to a resolved field (in-object or backing store). | 6078 // Create an access to a resolved field (in-object or backing store). |
| 6059 static HObjectAccess ForField(Handle<Map> map, | 6079 static HObjectAccess ForField(Handle<Map> map, |
| 6060 LookupResult *lookup, Handle<String> name = Handle<String>::null()); | 6080 LookupResult *lookup, Handle<String> name = Handle<String>::null()); |
| 6061 | 6081 |
| 6062 // Create an access for the payload of a Cell or JSGlobalPropertyCell. | 6082 // Create an access for the payload of a Cell or JSGlobalPropertyCell. |
| 6063 static HObjectAccess ForCellPayload(Isolate* isolate); | 6083 static HObjectAccess ForCellPayload(Isolate* isolate); |
| 6064 | 6084 |
| 6085 static HObjectAccess ForJSTypedArrayLength() { |
| 6086 return HObjectAccess::ForJSObjectOffset(JSTypedArray::kLengthOffset); |
| 6087 } |
| 6088 |
| 6089 static HObjectAccess ForJSArrayBufferBackingStore() { |
| 6090 return HObjectAccess::ForJSObjectOffset( |
| 6091 JSArrayBuffer::kBackingStoreOffset, Representation::External()); |
| 6092 } |
| 6093 |
| 6094 static HObjectAccess ForExternalArrayExternalPointer() { |
| 6095 return HObjectAccess::ForJSObjectOffset( |
| 6096 ExternalArray::kExternalPointerOffset, Representation::External()); |
| 6097 } |
| 6098 |
| 6099 static HObjectAccess ForJSArrayBufferViewWeakNext() { |
| 6100 return HObjectAccess::ForJSObjectOffset(JSArrayBufferView::kWeakNextOffset); |
| 6101 } |
| 6102 |
| 6103 static HObjectAccess ForJSArrayBufferWeakFirstView() { |
| 6104 return HObjectAccess::ForJSObjectOffset( |
| 6105 JSArrayBuffer::kWeakFirstViewOffset); |
| 6106 } |
| 6107 |
| 6108 static HObjectAccess ForJSArrayBufferViewBuffer() { |
| 6109 return HObjectAccess::ForJSObjectOffset(JSArrayBufferView::kBufferOffset); |
| 6110 } |
| 6111 |
| 6112 static HObjectAccess ForJSArrayBufferViewByteOffset() { |
| 6113 return HObjectAccess::ForJSObjectOffset( |
| 6114 JSArrayBufferView::kByteOffsetOffset); |
| 6115 } |
| 6116 |
| 6117 static HObjectAccess ForJSArrayBufferViewByteLength() { |
| 6118 return HObjectAccess::ForJSObjectOffset( |
| 6119 JSArrayBufferView::kByteLengthOffset); |
| 6120 } |
| 6121 |
| 6065 void PrintTo(StringStream* stream); | 6122 void PrintTo(StringStream* stream); |
| 6066 | 6123 |
| 6067 inline bool Equals(HObjectAccess that) const { | 6124 inline bool Equals(HObjectAccess that) const { |
| 6068 return value_ == that.value_; // portion and offset must match | 6125 return value_ == that.value_; // portion and offset must match |
| 6069 } | 6126 } |
| 6070 | 6127 |
| 6071 protected: | 6128 protected: |
| 6072 void SetGVNFlags(HValue *instr, bool is_store); | 6129 void SetGVNFlags(HValue *instr, bool is_store); |
| 6073 | 6130 |
| 6074 private: | 6131 private: |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6152 SetOperandAt(0, object); | 6209 SetOperandAt(0, object); |
| 6153 | 6210 |
| 6154 Representation representation = access.representation(); | 6211 Representation representation = access.representation(); |
| 6155 if (representation.IsInteger8() || | 6212 if (representation.IsInteger8() || |
| 6156 representation.IsUInteger8() || | 6213 representation.IsUInteger8() || |
| 6157 representation.IsInteger16() || | 6214 representation.IsInteger16() || |
| 6158 representation.IsUInteger16()) { | 6215 representation.IsUInteger16()) { |
| 6159 set_representation(Representation::Integer32()); | 6216 set_representation(Representation::Integer32()); |
| 6160 } else if (representation.IsSmi()) { | 6217 } else if (representation.IsSmi()) { |
| 6161 set_type(HType::Smi()); | 6218 set_type(HType::Smi()); |
| 6162 set_representation(representation); | 6219 if (SmiValuesAre32Bits()) { |
| 6220 set_representation(Representation::Integer32()); |
| 6221 } else { |
| 6222 set_representation(representation); |
| 6223 } |
| 6163 } else if (representation.IsDouble() || | 6224 } else if (representation.IsDouble() || |
| 6164 representation.IsExternal() || | 6225 representation.IsExternal() || |
| 6165 representation.IsInteger32()) { | 6226 representation.IsInteger32()) { |
| 6166 set_representation(representation); | 6227 set_representation(representation); |
| 6167 } else if (FLAG_track_heap_object_fields && | 6228 } else if (FLAG_track_heap_object_fields && |
| 6168 representation.IsHeapObject()) { | 6229 representation.IsHeapObject()) { |
| 6169 set_type(HType::NonPrimitive()); | 6230 set_type(HType::NonPrimitive()); |
| 6170 set_representation(Representation::Tagged()); | 6231 set_representation(Representation::Tagged()); |
| 6171 } else { | 6232 } else { |
| 6172 set_representation(Representation::Tagged()); | 6233 set_representation(Representation::Tagged()); |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6471 } else if (index == 1) { | 6532 } else if (index == 1) { |
| 6472 if (field_representation().IsInteger8() || | 6533 if (field_representation().IsInteger8() || |
| 6473 field_representation().IsUInteger8() || | 6534 field_representation().IsUInteger8() || |
| 6474 field_representation().IsInteger16() || | 6535 field_representation().IsInteger16() || |
| 6475 field_representation().IsUInteger16() || | 6536 field_representation().IsUInteger16() || |
| 6476 field_representation().IsInteger32()) { | 6537 field_representation().IsInteger32()) { |
| 6477 return Representation::Integer32(); | 6538 return Representation::Integer32(); |
| 6478 } else if (field_representation().IsDouble() || | 6539 } else if (field_representation().IsDouble() || |
| 6479 field_representation().IsSmi()) { | 6540 field_representation().IsSmi()) { |
| 6480 return field_representation(); | 6541 return field_representation(); |
| 6542 } else if (field_representation().IsExternal()) { |
| 6543 return Representation::External(); |
| 6481 } | 6544 } |
| 6482 } | 6545 } |
| 6483 return Representation::Tagged(); | 6546 return Representation::Tagged(); |
| 6484 } | 6547 } |
| 6485 virtual void HandleSideEffectDominator(GVNFlag side_effect, | 6548 virtual void HandleSideEffectDominator(GVNFlag side_effect, |
| 6486 HValue* dominator) V8_OVERRIDE { | 6549 HValue* dominator) V8_OVERRIDE { |
| 6487 ASSERT(side_effect == kChangesNewSpacePromotion); | 6550 ASSERT(side_effect == kChangesNewSpacePromotion); |
| 6488 new_space_dominator_ = dominator; | 6551 new_space_dominator_ = dominator; |
| 6489 } | 6552 } |
| 6490 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 6553 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6523 | 6586 |
| 6524 bool NeedsWriteBarrier() { | 6587 bool NeedsWriteBarrier() { |
| 6525 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) || | 6588 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) || |
| 6526 !has_transition()); | 6589 !has_transition()); |
| 6527 if (IsSkipWriteBarrier()) return false; | 6590 if (IsSkipWriteBarrier()) return false; |
| 6528 if (field_representation().IsDouble()) return false; | 6591 if (field_representation().IsDouble()) return false; |
| 6529 if (field_representation().IsSmi()) return false; | 6592 if (field_representation().IsSmi()) return false; |
| 6530 if (field_representation().IsInteger32()) return false; | 6593 if (field_representation().IsInteger32()) return false; |
| 6531 if (field_representation().IsExternal()) return false; | 6594 if (field_representation().IsExternal()) return false; |
| 6532 return StoringValueNeedsWriteBarrier(value()) && | 6595 return StoringValueNeedsWriteBarrier(value()) && |
| 6533 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 6596 ReceiverObjectNeedsWriteBarrier(object(), value(), |
| 6597 new_space_dominator()); |
| 6534 } | 6598 } |
| 6535 | 6599 |
| 6536 bool NeedsWriteBarrierForMap() { | 6600 bool NeedsWriteBarrierForMap() { |
| 6537 if (IsSkipWriteBarrier()) return false; | 6601 if (IsSkipWriteBarrier()) return false; |
| 6538 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 6602 return ReceiverObjectNeedsWriteBarrier(object(), transition(), |
| 6603 new_space_dominator()); |
| 6539 } | 6604 } |
| 6540 | 6605 |
| 6541 Representation field_representation() const { | 6606 Representation field_representation() const { |
| 6542 return access_.representation(); | 6607 return access_.representation(); |
| 6543 } | 6608 } |
| 6544 | 6609 |
| 6545 void UpdateValue(HValue* value) { | 6610 void UpdateValue(HValue* value) { |
| 6546 SetOperandAt(1, value); | 6611 SetOperandAt(1, value); |
| 6547 } | 6612 } |
| 6548 | 6613 |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6690 new_space_dominator_ = dominator; | 6755 new_space_dominator_ = dominator; |
| 6691 } | 6756 } |
| 6692 | 6757 |
| 6693 HValue* new_space_dominator() const { return new_space_dominator_; } | 6758 HValue* new_space_dominator() const { return new_space_dominator_; } |
| 6694 | 6759 |
| 6695 bool NeedsWriteBarrier() { | 6760 bool NeedsWriteBarrier() { |
| 6696 if (value_is_smi()) { | 6761 if (value_is_smi()) { |
| 6697 return false; | 6762 return false; |
| 6698 } else { | 6763 } else { |
| 6699 return StoringValueNeedsWriteBarrier(value()) && | 6764 return StoringValueNeedsWriteBarrier(value()) && |
| 6700 ReceiverObjectNeedsWriteBarrier(elements(), new_space_dominator()); | 6765 ReceiverObjectNeedsWriteBarrier(elements(), value(), |
| 6766 new_space_dominator()); |
| 6701 } | 6767 } |
| 6702 } | 6768 } |
| 6703 | 6769 |
| 6704 bool NeedsCanonicalization(); | 6770 bool NeedsCanonicalization(); |
| 6705 | 6771 |
| 6706 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 6772 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 6707 | 6773 |
| 6708 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) | 6774 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) |
| 6709 | 6775 |
| 6710 private: | 6776 private: |
| (...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7427 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 7493 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
| 7428 }; | 7494 }; |
| 7429 | 7495 |
| 7430 | 7496 |
| 7431 #undef DECLARE_INSTRUCTION | 7497 #undef DECLARE_INSTRUCTION |
| 7432 #undef DECLARE_CONCRETE_INSTRUCTION | 7498 #undef DECLARE_CONCRETE_INSTRUCTION |
| 7433 | 7499 |
| 7434 } } // namespace v8::internal | 7500 } } // namespace v8::internal |
| 7435 | 7501 |
| 7436 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 7502 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |