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