5#ifndef V8_HEAP_YOUNG_GENERATION_MARKING_VISITOR_INL_H_
6#define V8_HEAP_YOUNG_GENERATION_MARKING_VISITOR_INL_H_
24template <YoungGenerationMarkingVisitationMode marking_mode>
30 marking_worklists_local_(
31 heap->minor_mark_sweep_collector()->marking_worklists(),
33 ?
CppHeap::From(
heap->cpp_heap())->CreateCppMarkingState()
35 ephemeron_table_list_local_(
36 *
heap->minor_mark_sweep_collector()->ephemeron_table_list()),
37 pretenuring_handler_(
heap->pretenuring_handler()),
38 local_pretenuring_feedback_(local_pretenuring_feedback),
39 shortcut_strings_(
heap->CanShortcutStringsDuringGC(
42template <YoungGenerationMarkingVisitationMode marking_mode>
49 for (
auto& pair : live_bytes_data_) {
51 pair.first->IncrementLiveBytesAtomically(pair.second);
56template <YoungGenerationMarkingVisitationMode marking_mode>
59 if (!marking_worklists_local_.cpp_marking_state())
return;
65 marking_worklists_local_.cpp_marking_state()->MarkAndPush(
66 reinterpret_cast<void*
>(cpp_heap_pointer));
70template <YoungGenerationMarkingVisitationMode marking_mode>
74 object->YoungMarkExtension();
75 return Base::VisitJSArrayBuffer(map,
object, maybe_object_size);
78template <YoungGenerationMarkingVisitationMode marking_mode>
79template <
typename T,
typename TBodyDescriptor>
82 const int object_size =
83 static_cast<int>(Base::template VisitJSObjectSubclass<T, TBodyDescriptor>(
84 map,
object, maybe_object_size));
86 isolate_->
heap(), map,
object, object_size, local_pretenuring_feedback_);
90template <YoungGenerationMarkingVisitationMode marking_mode>
96 ephemeron_table_list_local_.Push(table);
99 table->RawFieldOfElementAt(EphemeronHashTable::EntryToValueIndex(
i));
100 VisitPointer(table, value_slot);
105#ifdef V8_COMPRESS_POINTERS
106template <YoungGenerationMarkingVisitationMode marking_mode>
117 if (!slot.HasExternalPointerHandle())
return;
121 ExternalPointerTable& table =
isolate_->external_pointer_table();
122 auto* space =
isolate_->
heap()->young_external_pointer_space();
131 RememberedSet<SURVIVOR_TO_EXTERNAL_POINTER>::template Insert<
136template <YoungGenerationMarkingVisitationMode marking_mode>
137template <
typename TSlot>
140 for (TSlot slot =
start; slot <
end; ++slot) {
141 if constexpr (marking_mode ==
143 VisitObjectViaSlot<ObjectVisitationMode::kPushToWorklist,
144 SlotTreatmentMode::kReadOnly>(slot);
146 VisitObjectViaSlot<ObjectVisitationMode::kPushToWorklist,
147 SlotTreatmentMode::kReadWrite>(slot);
152template <YoungGenerationMarkingVisitationMode marking_mode>
153template <
typename TSlot>
157 if constexpr (marking_mode ==
159 return VisitObjectViaSlot<ObjectVisitationMode::kPushToWorklist,
160 SlotTreatmentMode::kReadOnly>(slot);
162 return VisitObjectViaSlot<ObjectVisitationMode::kVisitDirectly,
163 SlotTreatmentMode::kReadWrite>(slot);
167template <YoungGenerationMarkingVisitationMode marking_mode>
169 marking_mode>::ObjectVisitationMode visitation_mode,
171 marking_mode>::SlotTreatmentMode slot_treatment_mode,
175 const std::optional<Tagged<Object>> optional_object =
176 this->GetObjectFilterReadOnlyAndSmiFast(slot);
177 if (!optional_object) {
180 typename TSlot::TObject target = *optional_object;
181#ifdef V8_ENABLE_DIRECT_HANDLE
186 if (!target.GetHeapObject(&heap_object)) {
190#ifdef THREAD_SANITIZER
198#ifdef V8_MINORMS_STRING_SHORTCUTTING
199 if (slot_treatment_mode == SlotTreatmentMode::kReadWrite &&
200 !ShortCutStrings(
reinterpret_cast<HeapObjectSlot&
>(slot), &heap_object)) {
205 if (!TryMark(heap_object))
return true;
209 if constexpr (visitation_mode == ObjectVisitationMode::kVisitDirectly) {
211 const size_t visited_size = Base::Visit(map, heap_object);
213 IncrementLiveBytesCached(
221 marking_worklists_local_.Push(heap_object);
226#ifdef V8_MINORMS_STRING_SHORTCUTTING
227template <YoungGenerationMarkingVisitationMode marking_mode>
231 if (shortcut_strings_) {
233#if V8_STATIC_ROOTS_BOOL
234 ObjectSlot map_slot = (*heap_object)->map_slot();
236 if (map_address == StaticReadOnlyRoot::kThinOneByteStringMap ||
237 map_address == StaticReadOnlyRoot::kThinTwoByteStringMap) {
241 VisitorId::kVisitThinString);
245 DCHECK(!Heap::InYoungGeneration(*heap_object));
248 }
else if (map_address == StaticReadOnlyRoot::kConsOneByteStringMap ||
249 map_address == StaticReadOnlyRoot::kConsTwoByteStringMap) {
255 if (visitor_id == VisitorId::kVisitShortcutCandidate) {
257 if (
static_cast<Tagged_t>(string->second().ptr()) ==
258 StaticReadOnlyRoot::kempty_string) {
259 *heap_object =
string->first();
261 if (!Heap::InYoungGeneration(*heap_object)) {
273template <YoungGenerationMarkingVisitationMode marking_mode>
280 auto& entry = live_bytes_data_[hash];
281 if (entry.first && entry.first != chunk) {
282 entry.first->IncrementLiveBytesAtomically(entry.second);
Address try_load(IsolateForPointerCompression isolate, CppHeapPointerTagRange tag_range) const
static int SizeOf(Tagged< Map > map, Tagged< HeapObject > object)
ExternalPointerTagRange tag_range() const
void StoreHeapObject(Tagged< HeapObject > value) const
Tagged< Map > load_map() const
static V8_INLINE bool InYoungGeneration(Tagged< Object > object)
static V8_INLINE MemoryChunk * FromHeapObject(Tagged< HeapObject > object)
static MutablePageMetadata * cast(MemoryChunkMetadata *metadata)
static V8_INLINE MutablePageMetadata * FromHeapObject(Tagged< HeapObject > o)
PtrComprCageBase cage_base() const
virtual void VisitExternalPointer(Tagged< HeapObject > host, ExternalPointerSlot slot)
std::unordered_map< Tagged< AllocationSite >, size_t, Object::Hasher > PretenuringFeedbackMap
static void UpdateAllocationSite(Heap *heap, Tagged< Map > map, Tagged< HeapObject > object, int object_size, PretenuringFeedbackMap *pretenuring_feedback)
V8_INLINE constexpr StorageType ptr() const
YoungGenerationMarkingVisitor(Heap *heap, PretenuringHandler::PretenuringFeedbackMap *local_pretenuring_feedback)
~YoungGenerationMarkingVisitor() override
V8_INLINE void VisitPointersImpl(Tagged< HeapObject > host, TSlot start, TSlot end)
V8_INLINE bool VisitObjectViaSlot(TSlot slot)
V8_INLINE void VisitCppHeapPointer(Tagged< HeapObject > host, CppHeapPointerSlot slot) override
V8_INLINE size_t VisitJSObjectSubclass(Tagged< Map > map, Tagged< T > object, MaybeObjectSize)
V8_INLINE size_t VisitEphemeronHashTable(Tagged< Map > map, Tagged< EphemeronHashTable > table, MaybeObjectSize)
V8_INLINE bool VisitObjectViaSlotInRememberedSet(TSlot slot)
V8_INLINE void IncrementLiveBytesCached(MutablePageMetadata *chunk, intptr_t by)
V8_INLINE size_t VisitJSArrayBuffer(Tagged< Map > map, Tagged< JSArrayBuffer > object, MaybeObjectSize)
#define V8_COMPRESS_POINTERS_8GB_BOOL
#define ALIGN_TO_ALLOCATION_ALIGNMENT(value)
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
constexpr Address kTaggedNullAddress
static V8_INLINE constexpr bool IsSharedExternalPointerType(ExternalPointerTagRange tag_range)
Tagged(T object) -> Tagged< T >
constexpr intptr_t kObjectAlignment8GbHeap
constexpr ExternalPointerHandle kNullExternalPointerHandle
V8_EXPORT_PRIVATE FlagValues v8_flags
uint32_t ExternalPointerHandle
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
constexpr CppHeapPointerTagRange kAnyCppHeapPointer(CppHeapPointerTag::kFirstTag, CppHeapPointerTag::kLastTag)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
constexpr bool IsAligned(T value, U alignment)
constexpr bool IsEmpty() const
#define V8_STATIC_ROOTS_BOOL