• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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