v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
allocation-site-inl.h
Go to the documentation of this file.
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
9// Include the non-inl header before the rest of the headers.
10
11#include <atomic>
12
13#include "src/common/globals.h"
17
18// Has to be the last include (doesn't have include guards):
20#include "src/objects/objects.h"
21
22namespace v8 {
23namespace internal {
24
25#include "torque-generated/src/objects/allocation-site-tq-inl.inc"
26
27NEVER_READ_ONLY_SPACE_IMPL(AllocationSite)
28
33
40 nested_site_.store(this, value, mode);
41}
42
47 WriteBarrierMode mode) {
48 dependent_code_.store(this, value, mode);
49}
50
52 return pretenure_data_.load(std::memory_order_relaxed);
53}
55 pretenure_data_.store(value, std::memory_order_relaxed);
56}
57
64
69
74
77 WriteBarrierMode mode) {
78 transition_info_or_boilerplate_.Release_Store(this, value, mode);
79}
80
83 return Cast<Smi>(transition_info_or_boilerplate_.Acquire_Load()).value();
84}
85
91
92inline bool AllocationSite::HasWeakNext() const {
93 return map() == GetReadOnlyRoots().allocation_site_map();
94}
95
105
106inline bool AllocationSite::IsZombie() const {
107 return pretenure_decision() == kZombie;
108}
109
110inline bool AllocationSite::IsMaybeTenure() const {
112}
113
117
123
127
131
132inline bool AllocationSite::CanInlineCall() const {
134}
135
139
141 Tagged<Object> raw_value = transition_info_or_boilerplate_.Acquire_Load();
142 DCHECK_EQ(!IsSmi(raw_value), IsJSArray(raw_value) || IsJSObject(raw_value));
143 return !IsSmi(raw_value);
144}
145
146// Heuristic: We only need to create allocation site info if the boilerplate
147// elements kind is the initial elements kind.
149 ElementsKind boilerplate_elements_kind) {
150 if (!V8_ALLOCATION_SITE_TRACKING_BOOL) return false;
151 return IsSmiElementsKind(boilerplate_elements_kind);
152}
153
155 if (!V8_ALLOCATION_SITE_TRACKING_BOOL) return false;
156 if (v8_flags.allocation_site_pretenuring) {
157 // TurboFan doesn't care at all about String pretenuring feedback,
158 // so don't bother even trying to track that.
159 return type == JS_ARRAY_TYPE || type == JS_OBJECT_TYPE;
160 }
161 return type == JS_ARRAY_TYPE;
162}
163
168
174
178
184
188
190 int32_t value = pretenure_data(kRelaxedLoad);
191 // Verify that we can count more mementos than we can possibly find in one
192 // new space collection.
193 DCHECK((GetHeap()->MaxSemiSpaceSize() /
194 (Heap::kMinObjectSizeInTaggedWords * kTaggedSize +
199}
200
202 return pretenure_create_count();
203}
204
208
210 DCHECK(!IsZombie());
211
212 int new_value = memento_found_count() + increment;
213 set_memento_found_count(new_value);
214 return new_value;
215}
216
218 DCHECK(v8_flags.allocation_site_pretenuring);
219 int value = memento_create_count();
220 set_memento_create_count(value + 1);
221}
222
225 return weak_next_.load();
226}
232
233inline bool AllocationMemento::IsValid() const {
234 return !allocation_site_.load()->IsZombie();
235}
236
245
247 return allocation_site_.load().ptr();
248}
249
250template <AllocationSiteUpdateMode update_or_check>
252 ElementsKind to_kind) {
253 Isolate* isolate = site->GetIsolate();
254 bool result = false;
255
256 if (site->PointsToLiteral() && IsJSArray(site->boilerplate())) {
258 isolate);
259 ElementsKind kind = boilerplate->GetElementsKind();
260 // if kind is holey ensure that to_kind is as well.
262 to_kind = GetHoleyElementsKind(to_kind);
263 }
265 // If the array is huge, it's not likely to be defined in a local
266 // function, so we shouldn't make new instances of it very often.
267 uint32_t length = 0;
268 CHECK(Object::ToArrayLength(boilerplate->length(), &length));
269 if (length <= kMaximumArrayBytesToPretransition) {
270 if (update_or_check == AllocationSiteUpdateMode::kCheckOnly) {
271 return true;
272 }
273 if (v8_flags.trace_track_allocation_sites) {
274 bool is_nested = site->IsNested();
275 PrintF("AllocationSite: JSArray %p boilerplate %supdated %s->%s\n",
276 reinterpret_cast<void*>(site->ptr()),
277 is_nested ? "(nested)" : " ", ElementsKindToString(kind),
278 ElementsKindToString(to_kind));
279 }
283 isolate, *site,
285 result = true;
286 }
287 }
288 } else {
289 // The AllocationSite is for a constructed Array.
290 ElementsKind kind = site->GetElementsKind();
291 // if kind is holey ensure that to_kind is as well.
293 to_kind = GetHoleyElementsKind(to_kind);
294 }
296 if (update_or_check == AllocationSiteUpdateMode::kCheckOnly) return true;
297 if (v8_flags.trace_track_allocation_sites) {
298 PrintF("AllocationSite: JSArray %p site updated %s->%s\n",
299 reinterpret_cast<void*>(site->ptr()), ElementsKindToString(kind),
300 ElementsKindToString(to_kind));
301 }
302 site->SetElementsKind(to_kind);
305 result = true;
306 }
307 }
308 return result;
309}
310
311} // namespace internal
312} // namespace v8
313
315
316#endif // V8_OBJECTS_ALLOCATION_SITE_INL_H_
Builtins::Kind kind
Definition builtins.cc:40
static constexpr U kMax
Definition bit-field.h:44
static constexpr T decode(U value)
Definition bit-field.h:66
static V8_NODISCARD constexpr U update(U previous, T value)
Definition bit-field.h:61
Tagged< AllocationSite > GetAllocationSite() const
void set_allocation_site(Tagged< AllocationSite > value, WriteBarrierMode mode=UPDATE_WRITE_BARRIER)
TaggedMember< AllocationSite > allocation_site_
void set_weak_next(Tagged< UnionOf< Undefined, AllocationSiteWithWeakNext > > value, WriteBarrierMode mode=UPDATE_WRITE_BARRIER)
TaggedMember< UnionOf< Undefined, AllocationSiteWithWeakNext > > weak_next_
Tagged< UnionOf< Undefined, AllocationSiteWithWeakNext > > weak_next() const
static NEVER_READ_ONLY_SPACE const uint32_t kMaximumArrayBytesToPretransition
TaggedMember< UnionOf< Smi, JSObject > > transition_info_or_boilerplate_
ElementsKind GetElementsKind() const
Tagged< UnionOf< Smi, JSObject > > transition_info_or_boilerplate() const
Tagged< UnionOf< Smi, AllocationSite > > nested_site() const
PretenureDecision pretenure_decision() const
void set_pretenure_decision(PretenureDecision decision)
static bool ShouldTrack(ElementsKind boilerplate_elements_kind)
static bool CanTrack(InstanceType type)
TaggedMember< UnionOf< Smi, AllocationSite > > nested_site_
Tagged< DependentCode > dependent_code() const
void set_pretenure_create_count(int32_t value)
int32_t pretenure_data(RelaxedLoadTag) const
static bool DigestTransitionFeedback(DirectHandle< AllocationSite > site, ElementsKind to_kind)
Tagged< JSObject > boilerplate() const
void set_pretenure_data(int32_t value, RelaxedStoreTag)
void set_boilerplate(Tagged< JSObject > value, ReleaseStoreTag, WriteBarrierMode mode=UPDATE_WRITE_BARRIER)
TaggedMember< DependentCode > dependent_code_
void set_dependent_code(Tagged< DependentCode > value, WriteBarrierMode mode=UPDATE_WRITE_BARRIER)
void set_nested_site(Tagged< UnionOf< Smi, AllocationSite > > value, WriteBarrierMode mode=UPDATE_WRITE_BARRIER)
int IncrementMementoFoundCount(int increment=1)
std::atomic< int32_t > pretenure_data_
void SetElementsKind(ElementsKind kind)
static V8_EXPORT_PRIVATE Tagged< DependentCode > empty_dependent_code(const ReadOnlyRoots &roots)
static void DeoptimizeDependencyGroups(Isolate *isolate, ObjectT object, DependencyGroups groups)
Tagged< Map > map() const
static V8_EXPORT_PRIVATE void TransitionElementsKind(DirectHandle< JSObject > object, ElementsKind to_kind)
static bool ToArrayLength(Tagged< Object > obj, uint32_t *index)
static constexpr Tagged< Smi > FromInt(int value)
Definition smi.h:38
static constexpr Tagged< Smi > zero()
Definition smi.h:99
#define V8_ALLOCATION_SITE_TRACKING_BOOL
double increment
ZoneVector< RpoNumber > & result
constexpr int kTaggedSize
Definition globals.h:542
@ SKIP_WRITE_BARRIER
Definition objects.h:52
constexpr bool IsHoleyElementsKind(ElementsKind kind)
bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind, ElementsKind to_kind)
ReadOnlyRoots GetReadOnlyRoots()
Definition roots-inl.h:86
void PrintF(const char *format,...)
Definition utils.cc:39
Tagged(T object) -> Tagged< T >
constexpr bool IsSmiElementsKind(ElementsKind kind)
V8_INLINE constexpr bool IsSmi(TaggedImpl< kRefType, StorageType > obj)
Definition objects.h:665
const char * ElementsKindToString(ElementsKind kind)
ElementsKind GetHoleyElementsKind(ElementsKind packed_kind)
typename detail::FlattenUnionHelper< Union<>, Ts... >::type UnionOf
Definition union.h:123
V8_EXPORT_PRIVATE FlagValues v8_flags
return value
Definition map-inl.h:893
ElementsKind GetInitialFastElementsKind()
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
static constexpr RelaxedLoadTag kRelaxedLoad
Definition globals.h:2909
static constexpr RelaxedStoreTag kRelaxedStore
Definition globals.h:2911
#define NEVER_READ_ONLY_SPACE_IMPL(Type)
#define CHECK(condition)
Definition logging.h:124
#define CHECK_NE(lhs, rhs)
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define DCHECK_EQ(v1, v2)
Definition logging.h:485