| OLD | NEW | 
|     1 // Copyright 2012 the V8 project authors. All rights reserved. |     1 // Copyright 2012 the V8 project authors. All rights reserved. | 
|     2 // Use of this source code is governed by a BSD-style license that can be |     2 // Use of this source code is governed by a BSD-style license that can be | 
|     3 // found in the LICENSE file. |     3 // found in the LICENSE file. | 
|     4  |     4  | 
|     5 #ifndef V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ |     5 #ifndef V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ | 
|     6 #define V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ |     6 #define V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ | 
|     7  |     7  | 
|     8 #include <cstring> |     8 #include <cstring> | 
|     9 #include <iosfwd> |     9 #include <iosfwd> | 
|    10  |    10  | 
| (...skipping 4921 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4932     set_representation(Representation::Tagged()); |  4932     set_representation(Representation::Tagged()); | 
|  4933     SetAllSideEffects(); |  4933     SetAllSideEffects(); | 
|  4934   } |  4934   } | 
|  4935  |  4935  | 
|  4936   Handle<String> name_; |  4936   Handle<String> name_; | 
|  4937   TypeofMode typeof_mode_; |  4937   TypeofMode typeof_mode_; | 
|  4938   Handle<TypeFeedbackVector> feedback_vector_; |  4938   Handle<TypeFeedbackVector> feedback_vector_; | 
|  4939   FeedbackVectorSlot slot_; |  4939   FeedbackVectorSlot slot_; | 
|  4940 }; |  4940 }; | 
|  4941  |  4941  | 
|  4942  |  4942 class HAllocate final : public HTemplateInstruction<3> { | 
|  4943 class HAllocate final : public HTemplateInstruction<2> { |  | 
|  4944  public: |  4943  public: | 
|  4945   static bool CompatibleInstanceTypes(InstanceType type1, |  4944   static bool CompatibleInstanceTypes(InstanceType type1, | 
|  4946                                       InstanceType type2) { |  4945                                       InstanceType type2) { | 
|  4947     return ComputeFlags(TENURED, type1) == ComputeFlags(TENURED, type2) && |  4946     return ComputeFlags(TENURED, type1) == ComputeFlags(TENURED, type2) && | 
|  4948         ComputeFlags(NOT_TENURED, type1) == ComputeFlags(NOT_TENURED, type2); |  4947         ComputeFlags(NOT_TENURED, type1) == ComputeFlags(NOT_TENURED, type2); | 
|  4949   } |  4948   } | 
|  4950  |  4949  | 
|  4951   static HAllocate* New( |  4950   static HAllocate* New( | 
|  4952       Isolate* isolate, Zone* zone, HValue* context, HValue* size, HType type, |  4951       Isolate* isolate, Zone* zone, HValue* context, HValue* size, HType type, | 
|  4953       PretenureFlag pretenure_flag, InstanceType instance_type, |  4952       PretenureFlag pretenure_flag, InstanceType instance_type, | 
 |  4953       HValue* dominator, | 
|  4954       Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null()) { |  4954       Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null()) { | 
|  4955     return new(zone) HAllocate(context, size, type, pretenure_flag, |  4955     return new (zone) HAllocate(context, size, type, pretenure_flag, | 
|  4956         instance_type, allocation_site); |  4956                                 instance_type, dominator, allocation_site); | 
|  4957   } |  4957   } | 
|  4958  |  4958  | 
|  4959   // Maximum instance size for which allocations will be inlined. |  4959   // Maximum instance size for which allocations will be inlined. | 
|  4960   static const int kMaxInlineSize = 64 * kPointerSize; |  4960   static const int kMaxInlineSize = 64 * kPointerSize; | 
|  4961  |  4961  | 
|  4962   HValue* context() const { return OperandAt(0); } |  4962   HValue* context() const { return OperandAt(0); } | 
|  4963   HValue* size() const { return OperandAt(1); } |  4963   HValue* size() const { return OperandAt(1); } | 
|  4964  |  4964   HValue* allocation_folding_dominator() const { return OperandAt(2); } | 
|  4965   bool has_size_upper_bound() { return size_upper_bound_ != NULL; } |  | 
|  4966   HConstant* size_upper_bound() { return size_upper_bound_; } |  | 
|  4967   void set_size_upper_bound(HConstant* value) { |  | 
|  4968     DCHECK(size_upper_bound_ == NULL); |  | 
|  4969     size_upper_bound_ = value; |  | 
|  4970   } |  | 
|  4971  |  4965  | 
|  4972   Representation RequiredInputRepresentation(int index) override { |  4966   Representation RequiredInputRepresentation(int index) override { | 
|  4973     if (index == 0) { |  4967     if (index == 0) { | 
|  4974       return Representation::Tagged(); |  4968       return Representation::Tagged(); | 
|  4975     } else { |  4969     } else { | 
|  4976       return Representation::Integer32(); |  4970       return Representation::Integer32(); | 
|  4977     } |  4971     } | 
|  4978   } |  4972   } | 
|  4979  |  4973  | 
|  4980   Handle<Map> GetMonomorphicJSObjectMap() override { |  4974   Handle<Map> GetMonomorphicJSObjectMap() override { | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
|  4998   } |  4992   } | 
|  4999  |  4993  | 
|  5000   bool MustPrefillWithFiller() const { |  4994   bool MustPrefillWithFiller() const { | 
|  5001     return (flags_ & PREFILL_WITH_FILLER) != 0; |  4995     return (flags_ & PREFILL_WITH_FILLER) != 0; | 
|  5002   } |  4996   } | 
|  5003  |  4997  | 
|  5004   void MakePrefillWithFiller() { |  4998   void MakePrefillWithFiller() { | 
|  5005     flags_ = static_cast<HAllocate::Flags>(flags_ | PREFILL_WITH_FILLER); |  4999     flags_ = static_cast<HAllocate::Flags>(flags_ | PREFILL_WITH_FILLER); | 
|  5006   } |  5000   } | 
|  5007  |  5001  | 
|  5008   bool MustClearNextMapWord() const { |  | 
|  5009     return (flags_ & CLEAR_NEXT_MAP_WORD) != 0; |  | 
|  5010   } |  | 
|  5011  |  | 
|  5012   void MakeDoubleAligned() { |  5002   void MakeDoubleAligned() { | 
|  5013     flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATE_DOUBLE_ALIGNED); |  5003     flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATE_DOUBLE_ALIGNED); | 
|  5014   } |  5004   } | 
|  5015  |  5005  | 
 |  5006   void MakeAllocationFoldingDominator() { | 
 |  5007     flags_ = | 
 |  5008         static_cast<HAllocate::Flags>(flags_ | ALLOCATION_FOLDING_DOMINATOR); | 
 |  5009   } | 
 |  5010  | 
 |  5011   bool IsAllocationFoldingDominator() { | 
 |  5012     return (flags_ & ALLOCATION_FOLDING_DOMINATOR) != 0; | 
 |  5013   } | 
 |  5014  | 
 |  5015   void MakeFoldedAllocation(HAllocate* dominator) { | 
 |  5016     flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATION_FOLDED); | 
 |  5017     ClearFlag(kTrackSideEffectDominators); | 
 |  5018     ClearChangesFlag(kNewSpacePromotion); | 
 |  5019     SetOperandAt(2, dominator); | 
 |  5020   } | 
 |  5021  | 
 |  5022   bool IsAllocationFolded() { return (flags_ & ALLOCATION_FOLDED) != 0; } | 
 |  5023  | 
|  5016   bool HandleSideEffectDominator(GVNFlag side_effect, |  5024   bool HandleSideEffectDominator(GVNFlag side_effect, | 
|  5017                                  HValue* dominator) override; |  5025                                  HValue* dominator) override; | 
|  5018  |  5026  | 
|  5019   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT |  5027   std::ostream& PrintDataTo(std::ostream& os) const override;  // NOLINT | 
|  5020  |  5028  | 
|  5021   DECLARE_CONCRETE_INSTRUCTION(Allocate) |  5029   DECLARE_CONCRETE_INSTRUCTION(Allocate) | 
|  5022  |  5030  | 
|  5023  private: |  5031  private: | 
|  5024   enum Flags { |  5032   enum Flags { | 
|  5025     ALLOCATE_IN_NEW_SPACE = 1 << 0, |  5033     ALLOCATE_IN_NEW_SPACE = 1 << 0, | 
|  5026     ALLOCATE_IN_OLD_SPACE = 1 << 2, |  5034     ALLOCATE_IN_OLD_SPACE = 1 << 2, | 
|  5027     ALLOCATE_DOUBLE_ALIGNED = 1 << 3, |  5035     ALLOCATE_DOUBLE_ALIGNED = 1 << 3, | 
|  5028     PREFILL_WITH_FILLER = 1 << 4, |  5036     PREFILL_WITH_FILLER = 1 << 4, | 
|  5029     CLEAR_NEXT_MAP_WORD = 1 << 5 |  5037     ALLOCATION_FOLDING_DOMINATOR = 1 << 5, | 
 |  5038     ALLOCATION_FOLDED = 1 << 6 | 
|  5030   }; |  5039   }; | 
|  5031  |  5040  | 
|  5032   HAllocate(HValue* context, |  5041   HAllocate( | 
|  5033             HValue* size, |  5042       HValue* context, HValue* size, HType type, PretenureFlag pretenure_flag, | 
|  5034             HType type, |  5043       InstanceType instance_type, HValue* dominator, | 
|  5035             PretenureFlag pretenure_flag, |  5044       Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null()) | 
|  5036             InstanceType instance_type, |  5045       : HTemplateInstruction<3>(type), | 
|  5037             Handle<AllocationSite> allocation_site = |  5046         flags_(ComputeFlags(pretenure_flag, instance_type)) { | 
|  5038                 Handle<AllocationSite>::null()) |  | 
|  5039       : HTemplateInstruction<2>(type), |  | 
|  5040         flags_(ComputeFlags(pretenure_flag, instance_type)), |  | 
|  5041         dominating_allocate_(NULL), |  | 
|  5042         filler_free_space_size_(NULL), |  | 
|  5043         size_upper_bound_(NULL) { |  | 
|  5044     SetOperandAt(0, context); |  5047     SetOperandAt(0, context); | 
|  5045     UpdateSize(size); |  5048     UpdateSize(size); | 
 |  5049     SetOperandAt(2, dominator); | 
|  5046     set_representation(Representation::Tagged()); |  5050     set_representation(Representation::Tagged()); | 
|  5047     SetFlag(kTrackSideEffectDominators); |  5051     SetFlag(kTrackSideEffectDominators); | 
|  5048     SetChangesFlag(kNewSpacePromotion); |  5052     SetChangesFlag(kNewSpacePromotion); | 
|  5049     SetDependsOnFlag(kNewSpacePromotion); |  5053     SetDependsOnFlag(kNewSpacePromotion); | 
|  5050  |  5054  | 
|  5051     if (FLAG_trace_pretenuring) { |  5055     if (FLAG_trace_pretenuring) { | 
|  5052       PrintF("HAllocate with AllocationSite %p %s\n", |  5056       PrintF("HAllocate with AllocationSite %p %s\n", | 
|  5053              allocation_site.is_null() |  5057              allocation_site.is_null() | 
|  5054                  ? static_cast<void*>(NULL) |  5058                  ? static_cast<void*>(NULL) | 
|  5055                  : static_cast<void*>(*allocation_site), |  5059                  : static_cast<void*>(*allocation_site), | 
|  5056              pretenure_flag == TENURED ? "tenured" : "not tenured"); |  5060              pretenure_flag == TENURED ? "tenured" : "not tenured"); | 
|  5057     } |  5061     } | 
|  5058   } |  5062   } | 
|  5059  |  5063  | 
|  5060   static Flags ComputeFlags(PretenureFlag pretenure_flag, |  5064   static Flags ComputeFlags(PretenureFlag pretenure_flag, | 
|  5061                             InstanceType instance_type) { |  5065                             InstanceType instance_type) { | 
|  5062     Flags flags = pretenure_flag == TENURED ? ALLOCATE_IN_OLD_SPACE |  5066     Flags flags = pretenure_flag == TENURED ? ALLOCATE_IN_OLD_SPACE | 
|  5063                                             : ALLOCATE_IN_NEW_SPACE; |  5067                                             : ALLOCATE_IN_NEW_SPACE; | 
|  5064     if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) { |  5068     if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) { | 
|  5065       flags = static_cast<Flags>(flags | ALLOCATE_DOUBLE_ALIGNED); |  5069       flags = static_cast<Flags>(flags | ALLOCATE_DOUBLE_ALIGNED); | 
|  5066     } |  5070     } | 
|  5067     // We have to fill the allocated object with one word fillers if we do |  5071     // We have to fill the allocated object with one word fillers if we do | 
|  5068     // not use allocation folding since some allocations may depend on each |  5072     // not use allocation folding since some allocations may depend on each | 
|  5069     // other, i.e., have a pointer to each other. A GC in between these |  5073     // other, i.e., have a pointer to each other. A GC in between these | 
|  5070     // allocations may leave such objects behind in a not completely initialized |  5074     // allocations may leave such objects behind in a not completely initialized | 
|  5071     // state. |  5075     // state. | 
|  5072     if (!FLAG_use_gvn || !FLAG_use_allocation_folding) { |  5076     if (!FLAG_use_gvn || !FLAG_use_allocation_folding) { | 
|  5073       flags = static_cast<Flags>(flags | PREFILL_WITH_FILLER); |  5077       flags = static_cast<Flags>(flags | PREFILL_WITH_FILLER); | 
|  5074     } |  5078     } | 
|  5075     if (pretenure_flag == NOT_TENURED && |  | 
|  5076         AllocationSite::CanTrack(instance_type)) { |  | 
|  5077       flags = static_cast<Flags>(flags | CLEAR_NEXT_MAP_WORD); |  | 
|  5078     } |  | 
|  5079     return flags; |  5079     return flags; | 
|  5080   } |  5080   } | 
|  5081  |  5081  | 
|  5082   void UpdateClearNextMapWord(bool clear_next_map_word) { |  | 
|  5083     flags_ = static_cast<Flags>(clear_next_map_word |  | 
|  5084                                 ? flags_ | CLEAR_NEXT_MAP_WORD |  | 
|  5085                                 : flags_ & ~CLEAR_NEXT_MAP_WORD); |  | 
|  5086   } |  | 
|  5087  |  | 
|  5088   void UpdateSize(HValue* size) { |  5082   void UpdateSize(HValue* size) { | 
|  5089     SetOperandAt(1, size); |  5083     SetOperandAt(1, size); | 
|  5090     if (size->IsInteger32Constant()) { |  | 
|  5091       size_upper_bound_ = HConstant::cast(size); |  | 
|  5092     } else { |  | 
|  5093       size_upper_bound_ = NULL; |  | 
|  5094     } |  | 
|  5095   } |  5084   } | 
|  5096  |  5085  | 
|  5097   HAllocate* GetFoldableDominator(HAllocate* dominator); |  | 
|  5098  |  | 
|  5099   void UpdateFreeSpaceFiller(int32_t filler_size); |  | 
|  5100  |  | 
|  5101   void CreateFreeSpaceFiller(int32_t filler_size); |  | 
|  5102  |  | 
|  5103   bool IsFoldable(HAllocate* allocate) { |  5086   bool IsFoldable(HAllocate* allocate) { | 
|  5104     return (IsNewSpaceAllocation() && allocate->IsNewSpaceAllocation()) || |  5087     return (IsNewSpaceAllocation() && allocate->IsNewSpaceAllocation()) || | 
|  5105            (IsOldSpaceAllocation() && allocate->IsOldSpaceAllocation()); |  5088            (IsOldSpaceAllocation() && allocate->IsOldSpaceAllocation()); | 
|  5106   } |  5089   } | 
|  5107  |  5090  | 
|  5108   void ClearNextMapWord(int offset); |  | 
|  5109  |  | 
|  5110   Flags flags_; |  5091   Flags flags_; | 
|  5111   Handle<Map> known_initial_map_; |  5092   Handle<Map> known_initial_map_; | 
|  5112   HAllocate* dominating_allocate_; |  | 
|  5113   HStoreNamedField* filler_free_space_size_; |  | 
|  5114   HConstant* size_upper_bound_; |  | 
|  5115 }; |  5093 }; | 
|  5116  |  5094  | 
|  5117  |  5095  | 
|  5118 class HStoreCodeEntry final : public HTemplateInstruction<2> { |  5096 class HStoreCodeEntry final : public HTemplateInstruction<2> { | 
|  5119  public: |  5097  public: | 
|  5120   static HStoreCodeEntry* New(Isolate* isolate, Zone* zone, HValue* context, |  5098   static HStoreCodeEntry* New(Isolate* isolate, Zone* zone, HValue* context, | 
|  5121                               HValue* function, HValue* code) { |  5099                               HValue* function, HValue* code) { | 
|  5122     return new(zone) HStoreCodeEntry(function, code); |  5100     return new(zone) HStoreCodeEntry(function, code); | 
|  5123   } |  5101   } | 
|  5124  |  5102  | 
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5176       && !value->type().IsNull() |  5154       && !value->type().IsNull() | 
|  5177       && !value->type().IsBoolean() |  5155       && !value->type().IsBoolean() | 
|  5178       && !value->type().IsUndefined() |  5156       && !value->type().IsUndefined() | 
|  5179       && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable()); |  5157       && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable()); | 
|  5180 } |  5158 } | 
|  5181  |  5159  | 
|  5182  |  5160  | 
|  5183 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, |  5161 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, | 
|  5184                                             HValue* value, |  5162                                             HValue* value, | 
|  5185                                             HValue* dominator) { |  5163                                             HValue* dominator) { | 
 |  5164   // There may be multiple inner allocates dominated by one allocate. | 
|  5186   while (object->IsInnerAllocatedObject()) { |  5165   while (object->IsInnerAllocatedObject()) { | 
|  5187     object = HInnerAllocatedObject::cast(object)->base_object(); |  5166     object = HInnerAllocatedObject::cast(object)->base_object(); | 
|  5188   } |  5167   } | 
 |  5168  | 
 |  5169   if (object->IsAllocate()) { | 
 |  5170     HAllocate* allocate = HAllocate::cast(object); | 
 |  5171     if (allocate->IsAllocationFolded()) { | 
 |  5172       HValue* dominator = allocate->allocation_folding_dominator(); | 
 |  5173       DCHECK(HAllocate::cast(dominator)->IsAllocationFoldingDominator()); | 
 |  5174       object = dominator; | 
 |  5175     } | 
 |  5176   } | 
 |  5177  | 
|  5189   if (object->IsConstant() && |  5178   if (object->IsConstant() && | 
|  5190       HConstant::cast(object)->HasExternalReferenceValue()) { |  5179       HConstant::cast(object)->HasExternalReferenceValue()) { | 
|  5191     // Stores to external references require no write barriers |  5180     // Stores to external references require no write barriers | 
|  5192     return false; |  5181     return false; | 
|  5193   } |  5182   } | 
|  5194   // We definitely need a write barrier unless the object is the allocation |  5183   // We definitely need a write barrier unless the object is the allocation | 
|  5195   // dominator. |  5184   // dominator. | 
|  5196   if (object == dominator && object->IsAllocate()) { |  5185   if (object == dominator && object->IsAllocate()) { | 
|  5197     // Stores to new space allocations require no write barriers. |  5186     // Stores to new space allocations require no write barriers. | 
|  5198     if (HAllocate::cast(object)->IsNewSpaceAllocation()) { |  5187     if (HAllocate::cast(object)->IsNewSpaceAllocation()) { | 
| (...skipping 2038 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  7237   bool IsDeletable() const override { return true; } |  7226   bool IsDeletable() const override { return true; } | 
|  7238 }; |  7227 }; | 
|  7239  |  7228  | 
|  7240 #undef DECLARE_INSTRUCTION |  7229 #undef DECLARE_INSTRUCTION | 
|  7241 #undef DECLARE_CONCRETE_INSTRUCTION |  7230 #undef DECLARE_CONCRETE_INSTRUCTION | 
|  7242  |  7231  | 
|  7243 }  // namespace internal |  7232 }  // namespace internal | 
|  7244 }  // namespace v8 |  7233 }  // namespace v8 | 
|  7245  |  7234  | 
|  7246 #endif  // V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ |  7235 #endif  // V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ | 
| OLD | NEW |