V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
allocation-site-inl.h
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_INL_H_
6 #define V8_OBJECTS_ALLOCATION_SITE_INL_H_
7 
8 #include "src/objects/allocation-site.h"
9 
10 #include "src/heap/heap-inl.h"
11 #include "src/objects/js-objects-inl.h"
12 
13 // Has to be the last include (doesn't have include guards):
14 #include "src/objects/object-macros.h"
15 
16 namespace v8 {
17 namespace internal {
18 
19 CAST_ACCESSOR(AllocationMemento)
20 CAST_ACCESSOR(AllocationSite)
21 
22 ACCESSORS(AllocationSite, transition_info_or_boilerplate, Object,
23  kTransitionInfoOrBoilerplateOffset)
24 ACCESSORS(AllocationSite, nested_site, Object, kNestedSiteOffset)
25 INT32_ACCESSORS(AllocationSite, pretenure_data, kPretenureDataOffset)
26 INT32_ACCESSORS(AllocationSite, pretenure_create_count,
27  kPretenureCreateCountOffset)
28 ACCESSORS(AllocationSite, dependent_code, DependentCode, kDependentCodeOffset)
29 ACCESSORS_CHECKED(AllocationSite, weak_next, Object, kWeakNextOffset,
30  HasWeakNext())
31 ACCESSORS(AllocationMemento, allocation_site, Object, kAllocationSiteOffset)
32 
33 JSObject* AllocationSite::boilerplate() const {
34  DCHECK(PointsToLiteral());
35  return JSObject::cast(transition_info_or_boilerplate());
36 }
37 
38 void AllocationSite::set_boilerplate(JSObject* object, WriteBarrierMode mode) {
39  set_transition_info_or_boilerplate(object, mode);
40 }
41 
42 int AllocationSite::transition_info() const {
43  DCHECK(!PointsToLiteral());
44  return Smi::cast(transition_info_or_boilerplate())->value();
45 }
46 
47 void AllocationSite::set_transition_info(int value) {
48  DCHECK(!PointsToLiteral());
49  set_transition_info_or_boilerplate(Smi::FromInt(value), SKIP_WRITE_BARRIER);
50 }
51 
52 bool AllocationSite::HasWeakNext() const {
53  return map() == GetReadOnlyRoots().allocation_site_map();
54 }
55 
56 void AllocationSite::Initialize() {
57  set_transition_info_or_boilerplate(Smi::kZero);
58  SetElementsKind(GetInitialFastElementsKind());
59  set_nested_site(Smi::kZero);
60  set_pretenure_data(0);
61  set_pretenure_create_count(0);
62  set_dependent_code(
63  DependentCode::cast(GetReadOnlyRoots().empty_weak_fixed_array()),
64  SKIP_WRITE_BARRIER);
65 }
66 
67 bool AllocationSite::IsZombie() const {
68  return pretenure_decision() == kZombie;
69 }
70 
71 bool AllocationSite::IsMaybeTenure() const {
72  return pretenure_decision() == kMaybeTenure;
73 }
74 
75 bool AllocationSite::PretenuringDecisionMade() const {
76  return pretenure_decision() != kUndecided;
77 }
78 
79 void AllocationSite::MarkZombie() {
80  DCHECK(!IsZombie());
81  Initialize();
82  set_pretenure_decision(kZombie);
83 }
84 
85 ElementsKind AllocationSite::GetElementsKind() const {
86  return ElementsKindBits::decode(transition_info());
87 }
88 
89 void AllocationSite::SetElementsKind(ElementsKind kind) {
90  set_transition_info(ElementsKindBits::update(transition_info(), kind));
91 }
92 
93 bool AllocationSite::CanInlineCall() const {
94  return DoNotInlineBit::decode(transition_info()) == 0;
95 }
96 
97 void AllocationSite::SetDoNotInlineCall() {
98  set_transition_info(DoNotInlineBit::update(transition_info(), true));
99 }
100 
101 bool AllocationSite::PointsToLiteral() const {
102  Object* raw_value = transition_info_or_boilerplate();
103  DCHECK_EQ(!raw_value->IsSmi(),
104  raw_value->IsJSArray() || raw_value->IsJSObject());
105  return !raw_value->IsSmi();
106 }
107 
108 // Heuristic: We only need to create allocation site info if the boilerplate
109 // elements kind is the initial elements kind.
110 bool AllocationSite::ShouldTrack(ElementsKind boilerplate_elements_kind) {
111  return IsSmiElementsKind(boilerplate_elements_kind);
112 }
113 
114 inline bool AllocationSite::CanTrack(InstanceType type) {
115  if (FLAG_allocation_site_pretenuring) {
116  // TurboFan doesn't care at all about String pretenuring feedback,
117  // so don't bother even trying to track that.
118  return type == JS_ARRAY_TYPE || type == JS_OBJECT_TYPE;
119  }
120  return type == JS_ARRAY_TYPE;
121 }
122 
123 AllocationSite::PretenureDecision AllocationSite::pretenure_decision() const {
124  return PretenureDecisionBits::decode(pretenure_data());
125 }
126 
127 void AllocationSite::set_pretenure_decision(PretenureDecision decision) {
128  int32_t value = pretenure_data();
129  set_pretenure_data(PretenureDecisionBits::update(value, decision));
130 }
131 
132 bool AllocationSite::deopt_dependent_code() const {
133  return DeoptDependentCodeBit::decode(pretenure_data());
134 }
135 
136 void AllocationSite::set_deopt_dependent_code(bool deopt) {
137  int32_t value = pretenure_data();
138  set_pretenure_data(DeoptDependentCodeBit::update(value, deopt));
139 }
140 
141 int AllocationSite::memento_found_count() const {
142  return MementoFoundCountBits::decode(pretenure_data());
143 }
144 
145 inline void AllocationSite::set_memento_found_count(int count) {
146  int32_t value = pretenure_data();
147  // Verify that we can count more mementos than we can possibly find in one
148  // new space collection.
149  DCHECK((GetHeap()->MaxSemiSpaceSize() /
150  (Heap::kMinObjectSizeInTaggedWords * kTaggedSize +
151  AllocationMemento::kSize)) < MementoFoundCountBits::kMax);
152  DCHECK_LT(count, MementoFoundCountBits::kMax);
153  set_pretenure_data(MementoFoundCountBits::update(value, count));
154 }
155 
156 int AllocationSite::memento_create_count() const {
157  return pretenure_create_count();
158 }
159 
160 void AllocationSite::set_memento_create_count(int count) {
161  set_pretenure_create_count(count);
162 }
163 
164 bool AllocationSite::IncrementMementoFoundCount(int increment) {
165  if (IsZombie()) return false;
166 
167  int value = memento_found_count();
168  set_memento_found_count(value + increment);
169  return memento_found_count() >= kPretenureMinimumCreated;
170 }
171 
172 inline void AllocationSite::IncrementMementoCreateCount() {
173  DCHECK(FLAG_allocation_site_pretenuring);
174  int value = memento_create_count();
175  set_memento_create_count(value + 1);
176 }
177 
178 bool AllocationMemento::IsValid() const {
179  return allocation_site()->IsAllocationSite() &&
180  !AllocationSite::cast(allocation_site())->IsZombie();
181 }
182 
183 AllocationSite* AllocationMemento::GetAllocationSite() const {
184  DCHECK(IsValid());
185  return AllocationSite::cast(allocation_site());
186 }
187 
188 Address AllocationMemento::GetAllocationSiteUnchecked() const {
189  return reinterpret_cast<Address>(allocation_site());
190 }
191 
192 } // namespace internal
193 } // namespace v8
194 
195 #include "src/objects/object-macros-undef.h"
196 
197 #endif // V8_OBJECTS_ALLOCATION_SITE_INL_H_
Definition: libplatform.h:13