%PDF- %PDF-
Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/heap/ |
Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/heap/minor-mark-sweep-inl.h |
// Copyright 2023 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_HEAP_MINOR_MARK_SWEEP_INL_H_ #define V8_HEAP_MINOR_MARK_SWEEP_INL_H_ #include <atomic> #include "src/base/build_config.h" #include "src/common/globals.h" #include "src/heap/memory-chunk.h" #include "src/heap/minor-mark-sweep.h" #include "src/heap/remembered-set-inl.h" #include "src/heap/young-generation-marking-visitor-inl.h" #include "src/objects/heap-object.h" #include "src/objects/map.h" #include "src/objects/string.h" #include "src/roots/static-roots.h" namespace v8 { namespace internal { void YoungGenerationRootMarkingVisitor::VisitRootPointer( Root root, const char* description, FullObjectSlot p) { VisitPointersImpl(root, p, p + 1); } void YoungGenerationRootMarkingVisitor::VisitRootPointers( Root root, const char* description, FullObjectSlot start, FullObjectSlot end) { VisitPointersImpl(root, start, end); } template <typename TSlot> void YoungGenerationRootMarkingVisitor::VisitPointersImpl(Root root, TSlot start, TSlot end) { if (root == Root::kStackRoots) { for (TSlot slot = start; slot < end; ++slot) { main_marking_visitor_->VisitObjectViaSlot< YoungGenerationMainMarkingVisitor::ObjectVisitationMode:: kPushToWorklist, YoungGenerationMainMarkingVisitor::SlotTreatmentMode::kReadOnly>( slot); } } else { for (TSlot slot = start; slot < end; ++slot) { main_marking_visitor_->VisitObjectViaSlot< YoungGenerationMainMarkingVisitor::ObjectVisitationMode:: kPushToWorklist, YoungGenerationMainMarkingVisitor::SlotTreatmentMode::kReadWrite>( slot); } } } template <typename Visitor> bool YoungGenerationRememberedSetsMarkingWorklist::ProcessNextItem( Visitor* visitor, base::Optional<size_t>& index) { if (remaining_remembered_sets_marking_items_.load( std::memory_order_relaxed) == 0) { return false; } while (true) { if (index && (index < remembered_sets_marking_items_.size())) { auto& work_item = remembered_sets_marking_items_[*index]; if (work_item.TryAcquire()) { remaining_remembered_sets_marking_items_.fetch_sub( 1, std::memory_order_relaxed); work_item.Process(visitor); (*index)++; return true; } } index = remembered_sets_marking_index_generator_.GetNext(); if (!index) return false; } } template <typename Visitor> void YoungGenerationRememberedSetsMarkingWorklist::MarkingItem::Process( Visitor* visitor) { CodePageHeaderModificationScope header_modification_scope( "Marking modifies the remembered sets in the page header"); if (slots_type_ == SlotsType::kRegularSlots) { MarkUntypedPointers(visitor); } else { MarkTypedPointers(visitor); } } void YoungGenerationRememberedSetsMarkingWorklist::MarkingItem:: CheckOldToNewSlotForSharedUntyped(MemoryChunk* chunk, Address slot_address, MaybeObject object) { Tagged<HeapObject> heap_object; if (!object.GetHeapObject(&heap_object)) return; #ifdef THREAD_SANITIZER BasicMemoryChunk::FromHeapObject(heap_object)->SynchronizedHeapLoad(); #endif // THREAD_SANITIZER if (heap_object.InWritableSharedSpace()) { RememberedSet<OLD_TO_SHARED>::Insert<AccessMode::ATOMIC>(chunk, slot_address); } } void YoungGenerationRememberedSetsMarkingWorklist::MarkingItem:: CheckOldToNewSlotForSharedTyped(MemoryChunk* chunk, SlotType slot_type, Address slot_address, MaybeObject new_target) { Tagged<HeapObject> heap_object; if (!new_target.GetHeapObject(&heap_object)) return; #ifdef THREAD_SANITIZER BasicMemoryChunk::FromHeapObject(heap_object)->SynchronizedHeapLoad(); #endif // THREAD_SANITIZER if (heap_object.InWritableSharedSpace()) { const uintptr_t offset = slot_address - chunk->address(); DCHECK_LT(offset, static_cast<uintptr_t>(TypedSlotSet::kMaxOffset)); RememberedSet<OLD_TO_SHARED>::InsertTyped(chunk, slot_type, static_cast<uint32_t>(offset)); } } template <typename Visitor> void YoungGenerationRememberedSetsMarkingWorklist::MarkingItem:: MarkUntypedPointers(Visitor* visitor) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.gc"), "MarkingItem::MarkUntypedPointers"); const bool record_old_to_shared_slots = chunk_->heap()->isolate()->has_shared_space(); auto callback = [this, visitor, record_old_to_shared_slots](MaybeObjectSlot slot) { SlotCallbackResult result = CheckAndMarkObject(visitor, slot); if (result == REMOVE_SLOT && record_old_to_shared_slots) { MaybeObject object; if constexpr (Visitor::EnableConcurrentVisitation()) { object = slot.Relaxed_Load(visitor->cage_base()); } else { object = *slot; } CheckOldToNewSlotForSharedUntyped(chunk_, slot.address(), object); } return result; }; if (slot_set_) { const auto slot_count = RememberedSet<OLD_TO_NEW>::template Iterate<AccessMode::NON_ATOMIC>( slot_set_, chunk_, callback, SlotSet::FREE_EMPTY_BUCKETS); if (slot_count == 0) { SlotSet::Delete(slot_set_, chunk_->buckets()); slot_set_ = nullptr; } } if (background_slot_set_) { const auto slot_count = RememberedSet<OLD_TO_NEW_BACKGROUND>::template Iterate< AccessMode::NON_ATOMIC>(background_slot_set_, chunk_, callback, SlotSet::FREE_EMPTY_BUCKETS); if (slot_count == 0) { SlotSet::Delete(background_slot_set_, chunk_->buckets()); background_slot_set_ = nullptr; } } } template <typename Visitor> void YoungGenerationRememberedSetsMarkingWorklist::MarkingItem:: MarkTypedPointers(Visitor* visitor) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.gc"), "MarkingItem::MarkTypedPointers"); const bool record_old_to_shared_slots = chunk_->heap()->isolate()->has_shared_space(); DCHECK_NULL(background_slot_set_); DCHECK_NOT_NULL(typed_slot_set_); const auto slot_count = RememberedSet<OLD_TO_NEW>::IterateTyped( typed_slot_set_, [this, visitor, record_old_to_shared_slots]( SlotType slot_type, Address slot_address) { return UpdateTypedSlotHelper::UpdateTypedSlot( heap(), slot_type, slot_address, [this, visitor, record_old_to_shared_slots, slot_address, slot_type](FullMaybeObjectSlot slot) { SlotCallbackResult result = CheckAndMarkObject(visitor, slot); if (result == REMOVE_SLOT && record_old_to_shared_slots) { MaybeObject object; if constexpr (Visitor::EnableConcurrentVisitation()) { object = slot.Relaxed_Load(visitor->cage_base()); } else { object = *slot; } CheckOldToNewSlotForSharedTyped(chunk_, slot_type, slot_address, object); } return result; }); }); if (slot_count == 0) { delete typed_slot_set_; typed_slot_set_ = nullptr; } } template <typename Visitor, typename TSlot> V8_INLINE SlotCallbackResult YoungGenerationRememberedSetsMarkingWorklist::MarkingItem::CheckAndMarkObject( Visitor* visitor, TSlot slot) { static_assert( std::is_same<TSlot, FullMaybeObjectSlot>::value || std::is_same<TSlot, MaybeObjectSlot>::value, "Only FullMaybeObjectSlot and MaybeObjectSlot are expected here"); return visitor->VisitObjectViaSlotInRememberedSet(slot) ? KEEP_SLOT : REMOVE_SLOT; } } // namespace internal } // namespace v8 #endif // V8_HEAP_MINOR_MARK_SWEEP_INL_H_