1 // Copyright 2018 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_OBJECTS_ALLOCATION_SITE_H_ 6 #define V8_OBJECTS_ALLOCATION_SITE_H_ 7 8 #include "src/objects/objects.h" 9 #include "src/objects/struct.h" 10 11 // Has to be the last include (doesn't have include guards): 12 #include "src/objects/object-macros.h" 13 14 namespace v8 { 15 namespace internal { 16 17 enum InstanceType : uint16_t; 18 19 #include "torque-generated/src/objects/allocation-site-tq.inc" 20 21 class AllocationSite : public Struct { 22 public: 23 NEVER_READ_ONLY_SPACE 24 static const uint32_t kMaximumArrayBytesToPretransition = 8 * 1024; 25 static const double kPretenureRatio; 26 static const int kPretenureMinimumCreated = 100; 27 28 // Values for pretenure decision field. 29 enum PretenureDecision { 30 kUndecided = 0, 31 kDontTenure = 1, 32 kMaybeTenure = 2, 33 kTenure = 3, 34 kZombie = 4, 35 kLastPretenureDecisionValue = kZombie 36 }; 37 38 const char* PretenureDecisionName(PretenureDecision decision); 39 40 // Contains either a Smi-encoded bitfield or a boilerplate. If it's a Smi the 41 // AllocationSite is for a constructed Array. 42 DECL_ACCESSORS(transition_info_or_boilerplate, Object) 43 DECL_ACCESSORS(boilerplate, JSObject) 44 DECL_INT_ACCESSORS(transition_info) 45 46 // nested_site threads a list of sites that represent nested literals 47 // walked in a particular order. So [[1, 2], 1, 2] will have one 48 // nested_site, but [[1, 2], 3, [4]] will have a list of two. 49 DECL_ACCESSORS(nested_site, Object) 50 51 // Bitfield containing pretenuring information. 52 DECL_INT32_ACCESSORS(pretenure_data) 53 54 DECL_INT32_ACCESSORS(pretenure_create_count) 55 DECL_ACCESSORS(dependent_code, DependentCode) 56 57 // heap->allocation_site_list() points to the last AllocationSite which form 58 // a linked list through the weak_next property. The GC might remove elements 59 // from the list by updateing weak_next. 60 DECL_ACCESSORS(weak_next, Object) 61 62 inline void Initialize(); 63 64 // Checks if the allocation site contain weak_next field; 65 inline bool HasWeakNext() const; 66 67 // This method is expensive, it should only be called for reporting. 68 bool IsNested(); 69 70 // transition_info bitfields, for constructed array transition info. 71 using ElementsKindBits = base::BitField<ElementsKind, 0, 5>; 72 using DoNotInlineBit = base::BitField<bool, 5, 1>; 73 // Unused bits 6-30. 74 75 // Bitfields for pretenure_data 76 using MementoFoundCountBits = base::BitField<int, 0, 26>; 77 using PretenureDecisionBits = base::BitField<PretenureDecision, 26, 3>; 78 using DeoptDependentCodeBit = base::BitField<bool, 29, 1>; 79 STATIC_ASSERT(PretenureDecisionBits::kMax >= kLastPretenureDecisionValue); 80 81 // Increments the mementos found counter and returns true when the first 82 // memento was found for a given allocation site. 83 inline bool IncrementMementoFoundCount(int increment = 1); 84 85 inline void IncrementMementoCreateCount(); 86 87 AllocationType GetAllocationType() const; 88 89 void ResetPretenureDecision(); 90 91 inline PretenureDecision pretenure_decision() const; 92 inline void set_pretenure_decision(PretenureDecision decision); 93 94 inline bool deopt_dependent_code() const; 95 inline void set_deopt_dependent_code(bool deopt); 96 97 inline int memento_found_count() const; 98 inline void set_memento_found_count(int count); 99 100 inline int memento_create_count() const; 101 inline void set_memento_create_count(int count); 102 103 // The pretenuring decision is made during gc, and the zombie state allows 104 // us to recognize when an allocation site is just being kept alive because 105 // a later traversal of new space may discover AllocationMementos that point 106 // to this AllocationSite. 107 inline bool IsZombie() const; 108 109 inline bool IsMaybeTenure() const; 110 111 inline void MarkZombie(); 112 113 inline bool MakePretenureDecision(PretenureDecision current_decision, 114 double ratio, bool maximum_size_scavenge); 115 116 inline bool DigestPretenuringFeedback(bool maximum_size_scavenge); 117 118 inline ElementsKind GetElementsKind() const; 119 inline void SetElementsKind(ElementsKind kind); 120 121 inline bool CanInlineCall() const; 122 inline void SetDoNotInlineCall(); 123 124 inline bool PointsToLiteral() const; 125 126 template <AllocationSiteUpdateMode update_or_check = 127 AllocationSiteUpdateMode::kUpdate> 128 static bool DigestTransitionFeedback(Handle<AllocationSite> site, 129 ElementsKind to_kind); 130 131 DECL_PRINTER(AllocationSite) 132 DECL_VERIFIER(AllocationSite) 133 134 DECL_CAST(AllocationSite) 135 static inline bool ShouldTrack(ElementsKind boilerplate_elements_kind); 136 static bool ShouldTrack(ElementsKind from, ElementsKind to); 137 static inline bool CanTrack(InstanceType type); 138 139 // Layout description. 140 // AllocationSite has to start with TransitionInfoOrboilerPlateOffset 141 // and end with WeakNext field. 142 #define ALLOCATION_SITE_FIELDS(V) \ 143 V(kStartOffset, 0) \ 144 V(kTransitionInfoOrBoilerplateOffset, kTaggedSize) \ 145 V(kNestedSiteOffset, kTaggedSize) \ 146 V(kDependentCodeOffset, kTaggedSize) \ 147 V(kCommonPointerFieldEndOffset, 0) \ 148 V(kPretenureDataOffset, kInt32Size) \ 149 V(kPretenureCreateCountOffset, kInt32Size) \ 150 /* Size of AllocationSite without WeakNext field */ \ 151 V(kSizeWithoutWeakNext, 0) \ 152 V(kWeakNextOffset, kTaggedSize) \ 153 /* Size of AllocationSite with WeakNext field */ \ 154 V(kSizeWithWeakNext, 0) 155 156 DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, ALLOCATION_SITE_FIELDS) 157 #undef ALLOCATION_SITE_FIELDS 158 159 class BodyDescriptor; 160 161 private: 162 inline bool PretenuringDecisionMade() const; 163 164 OBJECT_CONSTRUCTORS(AllocationSite, Struct); 165 }; 166 167 class AllocationMemento 168 : public TorqueGeneratedAllocationMemento<AllocationMemento, Struct> { 169 public: 170 DECL_ACCESSORS(allocation_site, Object) 171 172 inline bool IsValid() const; 173 inline AllocationSite GetAllocationSite() const; 174 inline Address GetAllocationSiteUnchecked() const; 175 176 DECL_PRINTER(AllocationMemento) 177 178 TQ_OBJECT_CONSTRUCTORS(AllocationMemento) 179 }; 180 181 } // namespace internal 182 } // namespace v8 183 184 #include "src/objects/object-macros-undef.h" 185 186 #endif // V8_OBJECTS_ALLOCATION_SITE_H_ 187