Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: src/crankshaft/hydrogen-instructions.h

Issue 1899813003: [crankshaft] Fragmentation-free allocation folding. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/crankshaft/hydrogen.cc ('k') | src/crankshaft/hydrogen-instructions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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_
OLDNEW
« no previous file with comments | « src/crankshaft/hydrogen.cc ('k') | src/crankshaft/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698