v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
pretenuring-handler-inl.h
Go to the documentation of this file.
1// Copyright 2022 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_HEAP_PRETENURING_HANDLER_INL_H_
6#define V8_HEAP_PRETENURING_HANDLER_INL_H_
7
9// Include the non-inl header before the rest of the headers.
10
13#include "src/heap/new-spaces.h"
15#include "src/heap/spaces.h"
18
19namespace v8::internal {
20
21// static
23 Heap* heap, Tagged<Map> map, Tagged<HeapObject> object, int object_size,
24 PretenuringFeedbackMap* pretenuring_feedback) {
25 DCHECK_NE(pretenuring_feedback,
26 &heap->pretenuring_handler()->global_pretenuring_feedback_);
27#ifdef DEBUG
29 // MemoryChunk::IsToPage() is not available with sticky mark-bits.
30 DCHECK_IMPLIES(v8_flags.sticky_mark_bits || chunk->IsToPage(),
31 v8_flags.minor_ms);
34#endif
35 if (V8_UNLIKELY(!v8_flags.allocation_site_pretenuring) ||
36 !AllocationSite::CanTrack(map->instance_type())) {
37 return;
38 }
39 Tagged<AllocationMemento> memento_candidate =
40 FindAllocationMemento<kForGC>(heap, map, object, object_size);
41 if (memento_candidate.is_null()) {
42 return;
43 }
44 DCHECK(IsJSObjectMap(map));
45
46 // Entering cached feedback is used in the parallel case. We are not allowed
47 // to dereference the allocation site and rather have to postpone all checks
48 // till actually merging the data.
49 Address key = memento_candidate->GetAllocationSiteUnchecked();
50 (*pretenuring_feedback)[UncheckedCast<AllocationSite>(Tagged<Object>(key))]++;
51}
52
53// static
54template <PretenuringHandler::FindMementoMode mode>
60
61// static
62template <PretenuringHandler::FindMementoMode mode>
64 Heap* heap, Tagged<Map> map, Tagged<HeapObject> object, int object_size) {
65 // For uses from within the GC, the size here may actually change when e.g.
66 // updating mementos during marking in the young generation collector. This is
67 // not an issue with Scavenger that stops the mutator.
69 object_size == object->SizeFromMap(map));
70 // For configurations where object size changes, we can check that it only
71 // shinks in case the sizes are not matching.
73 object_size >= object->SizeFromMap(map));
74 Address object_address = object.address();
75 Address memento_address =
76 object_address + ALIGN_TO_ALLOCATION_ALIGNMENT(object_size);
77 Address last_memento_word_address = memento_address + kTaggedSize;
78 // If the memento would be on another page, bail out immediately.
79 if (!PageMetadata::OnSamePage(object_address, last_memento_word_address)) {
80 return {};
81 }
82
83 // If the page is being swept, treat it as if the memento was already swept
84 // and bail out.
85 if constexpr (mode != FindMementoMode::kForGC) {
86 MemoryChunk* object_chunk = MemoryChunk::FromAddress(object_address);
87 PageMetadata* object_page = PageMetadata::cast(object_chunk->Metadata());
88 if (!object_page->SweepingDone()) {
89 return {};
90 }
91 }
92
93 Tagged<HeapObject> candidate = HeapObject::FromAddress(memento_address);
94 ObjectSlot candidate_map_slot = candidate->map_slot();
95 // This fast check may peek at an uninitialized word. However, the slow check
96 // below (memento_address == top) ensures that this is safe. Mark the word as
97 // initialized to silence MemorySanitizer warnings.
98 MSAN_MEMORY_IS_INITIALIZED(candidate_map_slot.address(), kTaggedSize);
99 if (!candidate_map_slot.Relaxed_ContainsMapValue(
100 ReadOnlyRoots(heap).allocation_memento_map().ptr())) {
101 return {};
102 }
103
104 // Bailout if memento is below the age mark. This is only possible for pinned
105 // pages in the scavenger. Full GC has page promotion but clears the
106 // NEW_SPACE_BELOW_AGE_MARK page flags before checking mementos.
107 if (!v8_flags.minor_ms &&
108 heap->semi_space_new_space()->IsAddressBelowAgeMark(object_address)) {
109 return {};
110 }
111
112 Tagged<AllocationMemento> memento_candidate =
113 Cast<AllocationMemento>(candidate);
114
115 // Depending on what the memento is used for, we might need to perform
116 // additional checks.
117 Address top;
118 switch (mode) {
119 case kForGC:
120 return memento_candidate;
121 case kForRuntime:
122 if (memento_candidate.is_null()) return {};
123 // Either the object is the last object in the new space, or there is
124 // another object of at least word size (the header map word) following
125 // it, so suffices to compare ptr and top here.
126 top = heap->NewSpaceTop();
127 DCHECK(memento_address >= heap->NewSpaceLimit() ||
128 memento_address +
130 top);
131 if ((memento_address != top) && memento_candidate->IsValid()) {
132 return memento_candidate;
133 }
134 return {};
135 default:
136 UNREACHABLE();
137 }
138 UNREACHABLE();
139}
140
141} // namespace v8::internal
142
143#endif // V8_HEAP_PRETENURING_HANDLER_INL_H_
ThreadLocalTop * top
static bool CanTrack(InstanceType type)
bool Relaxed_ContainsMapValue(Address raw_value) const
Definition slots-inl.h:40
static V8_INLINE bool InYoungGeneration(Tagged< Object > object)
static Tagged< HeapObject > FromAddress(Address address)
V8_INLINE bool IsFlagSet(Flag flag) const
V8_INLINE MemoryChunkMetadata * Metadata()
static V8_INLINE MemoryChunk * FromAddress(Address addr)
static V8_INLINE MemoryChunk * FromHeapObject(Tagged< HeapObject > object)
static PageMetadata * cast(MemoryChunkMetadata *metadata)
static bool OnSamePage(Address address1, Address address2)
std::unordered_map< Tagged< AllocationSite >, size_t, Object::Hasher > PretenuringFeedbackMap
static Tagged< AllocationMemento > FindAllocationMemento(Heap *heap, Tagged< Map > map, Tagged< HeapObject > object)
static void UpdateAllocationSite(Heap *heap, Tagged< Map > map, Tagged< HeapObject > object, int object_size, PretenuringFeedbackMap *pretenuring_feedback)
Address address() const
Definition slots.h:78
V8_INLINE constexpr bool is_null() const
Definition tagged.h:502
#define ALIGN_TO_ALLOCATION_ALIGNMENT(value)
Definition globals.h:1796
#define MSAN_MEMORY_IS_INITIALIZED(start, size)
Definition msan.h:37
constexpr int kTaggedSize
Definition globals.h:542
Handle< To > UncheckedCast(Handle< From > value)
Definition handles-inl.h:55
V8_EXPORT_PRIVATE FlagValues v8_flags
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
#define DCHECK_IMPLIES(v1, v2)
Definition logging.h:493
#define DCHECK_NE(v1, v2)
Definition logging.h:486
#define DCHECK(condition)
Definition logging.h:482
#define V8_UNLIKELY(condition)
Definition v8config.h:660