%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/heap/
Upload File :
Create Path :
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_

Zerion Mini Shell 1.0