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