11cb0ef41Sopenharmony_ci// Copyright 2020 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/heap/cppgc-js/cpp-heap.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include <cstdint>
81cb0ef41Sopenharmony_ci#include <memory>
91cb0ef41Sopenharmony_ci#include <numeric>
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci#include "include/cppgc/heap-consistency.h"
121cb0ef41Sopenharmony_ci#include "include/cppgc/platform.h"
131cb0ef41Sopenharmony_ci#include "include/v8-isolate.h"
141cb0ef41Sopenharmony_ci#include "include/v8-local-handle.h"
151cb0ef41Sopenharmony_ci#include "include/v8-platform.h"
161cb0ef41Sopenharmony_ci#include "src/base/logging.h"
171cb0ef41Sopenharmony_ci#include "src/base/macros.h"
181cb0ef41Sopenharmony_ci#include "src/base/platform/platform.h"
191cb0ef41Sopenharmony_ci#include "src/base/platform/time.h"
201cb0ef41Sopenharmony_ci#include "src/execution/isolate-inl.h"
211cb0ef41Sopenharmony_ci#include "src/flags/flags.h"
221cb0ef41Sopenharmony_ci#include "src/handles/global-handles.h"
231cb0ef41Sopenharmony_ci#include "src/handles/handles.h"
241cb0ef41Sopenharmony_ci#include "src/heap/base/stack.h"
251cb0ef41Sopenharmony_ci#include "src/heap/cppgc-js/cpp-marking-state.h"
261cb0ef41Sopenharmony_ci#include "src/heap/cppgc-js/cpp-snapshot.h"
271cb0ef41Sopenharmony_ci#include "src/heap/cppgc-js/unified-heap-marking-state.h"
281cb0ef41Sopenharmony_ci#include "src/heap/cppgc-js/unified-heap-marking-verifier.h"
291cb0ef41Sopenharmony_ci#include "src/heap/cppgc-js/unified-heap-marking-visitor.h"
301cb0ef41Sopenharmony_ci#include "src/heap/cppgc/concurrent-marker.h"
311cb0ef41Sopenharmony_ci#include "src/heap/cppgc/gc-info-table.h"
321cb0ef41Sopenharmony_ci#include "src/heap/cppgc/heap-base.h"
331cb0ef41Sopenharmony_ci#include "src/heap/cppgc/heap-object-header.h"
341cb0ef41Sopenharmony_ci#include "src/heap/cppgc/marker.h"
351cb0ef41Sopenharmony_ci#include "src/heap/cppgc/marking-state.h"
361cb0ef41Sopenharmony_ci#include "src/heap/cppgc/marking-visitor.h"
371cb0ef41Sopenharmony_ci#include "src/heap/cppgc/metric-recorder.h"
381cb0ef41Sopenharmony_ci#include "src/heap/cppgc/object-allocator.h"
391cb0ef41Sopenharmony_ci#include "src/heap/cppgc/prefinalizer-handler.h"
401cb0ef41Sopenharmony_ci#include "src/heap/cppgc/raw-heap.h"
411cb0ef41Sopenharmony_ci#include "src/heap/cppgc/stats-collector.h"
421cb0ef41Sopenharmony_ci#include "src/heap/cppgc/sweeper.h"
431cb0ef41Sopenharmony_ci#include "src/heap/cppgc/unmarker.h"
441cb0ef41Sopenharmony_ci#include "src/heap/embedder-tracing-inl.h"
451cb0ef41Sopenharmony_ci#include "src/heap/embedder-tracing.h"
461cb0ef41Sopenharmony_ci#include "src/heap/gc-tracer.h"
471cb0ef41Sopenharmony_ci#include "src/heap/marking-worklist.h"
481cb0ef41Sopenharmony_ci#include "src/heap/sweeper.h"
491cb0ef41Sopenharmony_ci#include "src/init/v8.h"
501cb0ef41Sopenharmony_ci#include "src/profiler/heap-profiler.h"
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_cinamespace v8 {
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_cinamespace {
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ciclass V8ToCppGCReferencesVisitor final
571cb0ef41Sopenharmony_ci    : public v8::EmbedderHeapTracer::TracedGlobalHandleVisitor {
581cb0ef41Sopenharmony_ci public:
591cb0ef41Sopenharmony_ci  V8ToCppGCReferencesVisitor(
601cb0ef41Sopenharmony_ci      cppgc::internal::MutatorMarkingState& marking_state,
611cb0ef41Sopenharmony_ci      v8::internal::Isolate* isolate,
621cb0ef41Sopenharmony_ci      const v8::WrapperDescriptor& wrapper_descriptor)
631cb0ef41Sopenharmony_ci      : marking_state_(marking_state),
641cb0ef41Sopenharmony_ci        isolate_(isolate),
651cb0ef41Sopenharmony_ci        wrapper_descriptor_(wrapper_descriptor) {}
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci  void VisitTracedReference(const v8::TracedReference<v8::Value>& value) final {
681cb0ef41Sopenharmony_ci    VisitHandle(value, value.WrapperClassId());
691cb0ef41Sopenharmony_ci  }
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci private:
721cb0ef41Sopenharmony_ci  void VisitHandle(const v8::TracedReference<v8::Value>& value,
731cb0ef41Sopenharmony_ci                   uint16_t class_id) {
741cb0ef41Sopenharmony_ci    DCHECK(!value.IsEmpty());
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci    const internal::JSObject js_object =
771cb0ef41Sopenharmony_ci        *reinterpret_cast<const internal::JSObject* const&>(value);
781cb0ef41Sopenharmony_ci    if (!js_object.ptr() || js_object.IsSmi() ||
791cb0ef41Sopenharmony_ci        !js_object.MayHaveEmbedderFields())
801cb0ef41Sopenharmony_ci      return;
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci    internal::LocalEmbedderHeapTracer::WrapperInfo info;
831cb0ef41Sopenharmony_ci    if (!internal::LocalEmbedderHeapTracer::ExtractWrappableInfo(
841cb0ef41Sopenharmony_ci            isolate_, js_object, wrapper_descriptor_, &info))
851cb0ef41Sopenharmony_ci      return;
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci    marking_state_.MarkAndPush(
881cb0ef41Sopenharmony_ci        cppgc::internal::HeapObjectHeader::FromObject(info.second));
891cb0ef41Sopenharmony_ci  }
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci  cppgc::internal::MutatorMarkingState& marking_state_;
921cb0ef41Sopenharmony_ci  v8::internal::Isolate* isolate_;
931cb0ef41Sopenharmony_ci  const v8::WrapperDescriptor& wrapper_descriptor_;
941cb0ef41Sopenharmony_ci};
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_civoid TraceV8ToCppGCReferences(
971cb0ef41Sopenharmony_ci    v8::internal::Isolate* isolate,
981cb0ef41Sopenharmony_ci    cppgc::internal::MutatorMarkingState& marking_state,
991cb0ef41Sopenharmony_ci    const v8::WrapperDescriptor& wrapper_descriptor) {
1001cb0ef41Sopenharmony_ci  DCHECK(isolate);
1011cb0ef41Sopenharmony_ci  V8ToCppGCReferencesVisitor forwarding_visitor(marking_state, isolate,
1021cb0ef41Sopenharmony_ci                                                wrapper_descriptor);
1031cb0ef41Sopenharmony_ci  isolate->global_handles()->IterateTracedNodes(&forwarding_visitor);
1041cb0ef41Sopenharmony_ci}
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci}  // namespace
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci// static
1091cb0ef41Sopenharmony_ciconstexpr uint16_t WrapperDescriptor::kUnknownEmbedderId;
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_ci// static
1121cb0ef41Sopenharmony_cistd::unique_ptr<CppHeap> CppHeap::Create(v8::Platform* platform,
1131cb0ef41Sopenharmony_ci                                         const CppHeapCreateParams& params) {
1141cb0ef41Sopenharmony_ci  return std::make_unique<internal::CppHeap>(platform, params.custom_spaces,
1151cb0ef41Sopenharmony_ci                                             params.wrapper_descriptor);
1161cb0ef41Sopenharmony_ci}
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_cicppgc::AllocationHandle& CppHeap::GetAllocationHandle() {
1191cb0ef41Sopenharmony_ci  return internal::CppHeap::From(this)->object_allocator();
1201cb0ef41Sopenharmony_ci}
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_cicppgc::HeapHandle& CppHeap::GetHeapHandle() {
1231cb0ef41Sopenharmony_ci  return *internal::CppHeap::From(this);
1241cb0ef41Sopenharmony_ci}
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_civoid CppHeap::Terminate() { internal::CppHeap::From(this)->Terminate(); }
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_cicppgc::HeapStatistics CppHeap::CollectStatistics(
1291cb0ef41Sopenharmony_ci    cppgc::HeapStatistics::DetailLevel detail_level) {
1301cb0ef41Sopenharmony_ci  return internal::CppHeap::From(this)->AsBase().CollectStatistics(
1311cb0ef41Sopenharmony_ci      detail_level);
1321cb0ef41Sopenharmony_ci}
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_civoid CppHeap::CollectCustomSpaceStatisticsAtLastGC(
1351cb0ef41Sopenharmony_ci    std::vector<cppgc::CustomSpaceIndex> custom_spaces,
1361cb0ef41Sopenharmony_ci    std::unique_ptr<CustomSpaceStatisticsReceiver> receiver) {
1371cb0ef41Sopenharmony_ci  return internal::CppHeap::From(this)->CollectCustomSpaceStatisticsAtLastGC(
1381cb0ef41Sopenharmony_ci      std::move(custom_spaces), std::move(receiver));
1391cb0ef41Sopenharmony_ci}
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_civoid CppHeap::EnableDetachedGarbageCollectionsForTesting() {
1421cb0ef41Sopenharmony_ci  return internal::CppHeap::From(this)
1431cb0ef41Sopenharmony_ci      ->EnableDetachedGarbageCollectionsForTesting();
1441cb0ef41Sopenharmony_ci}
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_civoid CppHeap::CollectGarbageForTesting(cppgc::EmbedderStackState stack_state) {
1471cb0ef41Sopenharmony_ci  return internal::CppHeap::From(this)->CollectGarbageForTesting(
1481cb0ef41Sopenharmony_ci      internal::CppHeap::CollectionType::kMajor, stack_state);
1491cb0ef41Sopenharmony_ci}
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_civoid CppHeap::CollectGarbageInYoungGenerationForTesting(
1521cb0ef41Sopenharmony_ci    cppgc::EmbedderStackState stack_state) {
1531cb0ef41Sopenharmony_ci  return internal::CppHeap::From(this)->CollectGarbageForTesting(
1541cb0ef41Sopenharmony_ci      internal::CppHeap::CollectionType::kMinor, stack_state);
1551cb0ef41Sopenharmony_ci}
1561cb0ef41Sopenharmony_ci
1571cb0ef41Sopenharmony_cinamespace internal {
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_cinamespace {
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ciclass CppgcPlatformAdapter final : public cppgc::Platform {
1621cb0ef41Sopenharmony_ci public:
1631cb0ef41Sopenharmony_ci  explicit CppgcPlatformAdapter(v8::Platform* platform) : platform_(platform) {}
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_ci  CppgcPlatformAdapter(const CppgcPlatformAdapter&) = delete;
1661cb0ef41Sopenharmony_ci  CppgcPlatformAdapter& operator=(const CppgcPlatformAdapter&) = delete;
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ci  PageAllocator* GetPageAllocator() final {
1691cb0ef41Sopenharmony_ci    return platform_->GetPageAllocator();
1701cb0ef41Sopenharmony_ci  }
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ci  double MonotonicallyIncreasingTime() final {
1731cb0ef41Sopenharmony_ci    return platform_->MonotonicallyIncreasingTime();
1741cb0ef41Sopenharmony_ci  }
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ci  std::shared_ptr<TaskRunner> GetForegroundTaskRunner() final {
1771cb0ef41Sopenharmony_ci    // If no Isolate has been set, there's no task runner to leverage for
1781cb0ef41Sopenharmony_ci    // foreground tasks. In detached mode the original platform handles the
1791cb0ef41Sopenharmony_ci    // task runner retrieval.
1801cb0ef41Sopenharmony_ci    if (!isolate_ && !is_in_detached_mode_) return nullptr;
1811cb0ef41Sopenharmony_ci
1821cb0ef41Sopenharmony_ci    return platform_->GetForegroundTaskRunner(isolate_);
1831cb0ef41Sopenharmony_ci  }
1841cb0ef41Sopenharmony_ci
1851cb0ef41Sopenharmony_ci  std::unique_ptr<JobHandle> PostJob(TaskPriority priority,
1861cb0ef41Sopenharmony_ci                                     std::unique_ptr<JobTask> job_task) final {
1871cb0ef41Sopenharmony_ci    return platform_->PostJob(priority, std::move(job_task));
1881cb0ef41Sopenharmony_ci  }
1891cb0ef41Sopenharmony_ci
1901cb0ef41Sopenharmony_ci  TracingController* GetTracingController() override {
1911cb0ef41Sopenharmony_ci    return platform_->GetTracingController();
1921cb0ef41Sopenharmony_ci  }
1931cb0ef41Sopenharmony_ci
1941cb0ef41Sopenharmony_ci  void SetIsolate(v8::Isolate* isolate) { isolate_ = isolate; }
1951cb0ef41Sopenharmony_ci  void EnableDetachedModeForTesting() { is_in_detached_mode_ = true; }
1961cb0ef41Sopenharmony_ci
1971cb0ef41Sopenharmony_ci private:
1981cb0ef41Sopenharmony_ci  v8::Platform* platform_;
1991cb0ef41Sopenharmony_ci  v8::Isolate* isolate_ = nullptr;
2001cb0ef41Sopenharmony_ci  bool is_in_detached_mode_ = false;
2011cb0ef41Sopenharmony_ci};
2021cb0ef41Sopenharmony_ci
2031cb0ef41Sopenharmony_ciclass UnifiedHeapConcurrentMarker
2041cb0ef41Sopenharmony_ci    : public cppgc::internal::ConcurrentMarkerBase {
2051cb0ef41Sopenharmony_ci public:
2061cb0ef41Sopenharmony_ci  UnifiedHeapConcurrentMarker(
2071cb0ef41Sopenharmony_ci      cppgc::internal::HeapBase& heap, Heap* v8_heap,
2081cb0ef41Sopenharmony_ci      cppgc::internal::MarkingWorklists& marking_worklists,
2091cb0ef41Sopenharmony_ci      cppgc::internal::IncrementalMarkingSchedule& incremental_marking_schedule,
2101cb0ef41Sopenharmony_ci      cppgc::Platform* platform,
2111cb0ef41Sopenharmony_ci      UnifiedHeapMarkingState& unified_heap_marking_state)
2121cb0ef41Sopenharmony_ci      : cppgc::internal::ConcurrentMarkerBase(
2131cb0ef41Sopenharmony_ci            heap, marking_worklists, incremental_marking_schedule, platform),
2141cb0ef41Sopenharmony_ci        v8_heap_(v8_heap) {}
2151cb0ef41Sopenharmony_ci
2161cb0ef41Sopenharmony_ci  std::unique_ptr<cppgc::Visitor> CreateConcurrentMarkingVisitor(
2171cb0ef41Sopenharmony_ci      cppgc::internal::ConcurrentMarkingState&) const final;
2181cb0ef41Sopenharmony_ci
2191cb0ef41Sopenharmony_ci private:
2201cb0ef41Sopenharmony_ci  Heap* const v8_heap_;
2211cb0ef41Sopenharmony_ci};
2221cb0ef41Sopenharmony_ci
2231cb0ef41Sopenharmony_cistd::unique_ptr<cppgc::Visitor>
2241cb0ef41Sopenharmony_ciUnifiedHeapConcurrentMarker::CreateConcurrentMarkingVisitor(
2251cb0ef41Sopenharmony_ci    cppgc::internal::ConcurrentMarkingState& marking_state) const {
2261cb0ef41Sopenharmony_ci  return std::make_unique<ConcurrentUnifiedHeapMarkingVisitor>(heap(), v8_heap_,
2271cb0ef41Sopenharmony_ci                                                               marking_state);
2281cb0ef41Sopenharmony_ci}
2291cb0ef41Sopenharmony_ci
2301cb0ef41Sopenharmony_civoid FatalOutOfMemoryHandlerImpl(const std::string& reason,
2311cb0ef41Sopenharmony_ci                                 const SourceLocation&, HeapBase* heap) {
2321cb0ef41Sopenharmony_ci  FatalProcessOutOfMemory(static_cast<v8::internal::CppHeap*>(heap)->isolate(),
2331cb0ef41Sopenharmony_ci                          reason.c_str());
2341cb0ef41Sopenharmony_ci}
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ci}  // namespace
2371cb0ef41Sopenharmony_ci
2381cb0ef41Sopenharmony_ciclass UnifiedHeapMarker final : public cppgc::internal::MarkerBase {
2391cb0ef41Sopenharmony_ci public:
2401cb0ef41Sopenharmony_ci  UnifiedHeapMarker(Heap* v8_heap, cppgc::internal::HeapBase& cpp_heap,
2411cb0ef41Sopenharmony_ci                    cppgc::Platform* platform, MarkingConfig config);
2421cb0ef41Sopenharmony_ci
2431cb0ef41Sopenharmony_ci  ~UnifiedHeapMarker() final = default;
2441cb0ef41Sopenharmony_ci
2451cb0ef41Sopenharmony_ci  void AddObject(void*);
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_ci  cppgc::internal::MarkingWorklists& GetMarkingWorklists() {
2481cb0ef41Sopenharmony_ci    return marking_worklists_;
2491cb0ef41Sopenharmony_ci  }
2501cb0ef41Sopenharmony_ci
2511cb0ef41Sopenharmony_ci  cppgc::internal::MutatorMarkingState& GetMutatorMarkingState() {
2521cb0ef41Sopenharmony_ci    return static_cast<cppgc::internal::MutatorMarkingState&>(
2531cb0ef41Sopenharmony_ci        marking_visitor_->marking_state_);
2541cb0ef41Sopenharmony_ci  }
2551cb0ef41Sopenharmony_ci
2561cb0ef41Sopenharmony_ci  UnifiedHeapMarkingState& GetMutatorUnifiedHeapMarkingState() {
2571cb0ef41Sopenharmony_ci    return mutator_unified_heap_marking_state_;
2581cb0ef41Sopenharmony_ci  }
2591cb0ef41Sopenharmony_ci
2601cb0ef41Sopenharmony_ci protected:
2611cb0ef41Sopenharmony_ci  cppgc::Visitor& visitor() final { return *marking_visitor_; }
2621cb0ef41Sopenharmony_ci  cppgc::internal::ConservativeTracingVisitor& conservative_visitor() final {
2631cb0ef41Sopenharmony_ci    return conservative_marking_visitor_;
2641cb0ef41Sopenharmony_ci  }
2651cb0ef41Sopenharmony_ci  ::heap::base::StackVisitor& stack_visitor() final {
2661cb0ef41Sopenharmony_ci    return conservative_marking_visitor_;
2671cb0ef41Sopenharmony_ci  }
2681cb0ef41Sopenharmony_ci
2691cb0ef41Sopenharmony_ci private:
2701cb0ef41Sopenharmony_ci  UnifiedHeapMarkingState mutator_unified_heap_marking_state_;
2711cb0ef41Sopenharmony_ci  std::unique_ptr<MutatorUnifiedHeapMarkingVisitor> marking_visitor_;
2721cb0ef41Sopenharmony_ci  cppgc::internal::ConservativeMarkingVisitor conservative_marking_visitor_;
2731cb0ef41Sopenharmony_ci};
2741cb0ef41Sopenharmony_ci
2751cb0ef41Sopenharmony_ciUnifiedHeapMarker::UnifiedHeapMarker(Heap* v8_heap,
2761cb0ef41Sopenharmony_ci                                     cppgc::internal::HeapBase& heap,
2771cb0ef41Sopenharmony_ci                                     cppgc::Platform* platform,
2781cb0ef41Sopenharmony_ci                                     MarkingConfig config)
2791cb0ef41Sopenharmony_ci    : cppgc::internal::MarkerBase(heap, platform, config),
2801cb0ef41Sopenharmony_ci      mutator_unified_heap_marking_state_(v8_heap, nullptr),
2811cb0ef41Sopenharmony_ci      marking_visitor_(config.collection_type == CppHeap::CollectionType::kMajor
2821cb0ef41Sopenharmony_ci                           ? std::make_unique<MutatorUnifiedHeapMarkingVisitor>(
2831cb0ef41Sopenharmony_ci                                 heap, mutator_marking_state_,
2841cb0ef41Sopenharmony_ci                                 mutator_unified_heap_marking_state_)
2851cb0ef41Sopenharmony_ci                           : std::make_unique<MutatorMinorGCMarkingVisitor>(
2861cb0ef41Sopenharmony_ci                                 heap, mutator_marking_state_,
2871cb0ef41Sopenharmony_ci                                 mutator_unified_heap_marking_state_)),
2881cb0ef41Sopenharmony_ci      conservative_marking_visitor_(heap, mutator_marking_state_,
2891cb0ef41Sopenharmony_ci                                    *marking_visitor_) {
2901cb0ef41Sopenharmony_ci  concurrent_marker_ = std::make_unique<UnifiedHeapConcurrentMarker>(
2911cb0ef41Sopenharmony_ci      heap_, v8_heap, marking_worklists_, schedule_, platform_,
2921cb0ef41Sopenharmony_ci      mutator_unified_heap_marking_state_);
2931cb0ef41Sopenharmony_ci}
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_civoid UnifiedHeapMarker::AddObject(void* object) {
2961cb0ef41Sopenharmony_ci  mutator_marking_state_.MarkAndPush(
2971cb0ef41Sopenharmony_ci      cppgc::internal::HeapObjectHeader::FromObject(object));
2981cb0ef41Sopenharmony_ci}
2991cb0ef41Sopenharmony_ci
3001cb0ef41Sopenharmony_civoid CppHeap::MetricRecorderAdapter::AddMainThreadEvent(
3011cb0ef41Sopenharmony_ci    const GCCycle& cppgc_event) {
3021cb0ef41Sopenharmony_ci  auto* tracer = GetIsolate()->heap()->tracer();
3031cb0ef41Sopenharmony_ci  if (cppgc_event.type == MetricRecorder::GCCycle::Type::kMinor) {
3041cb0ef41Sopenharmony_ci    DCHECK(!last_young_gc_event_);
3051cb0ef41Sopenharmony_ci    last_young_gc_event_ = cppgc_event;
3061cb0ef41Sopenharmony_ci    tracer->NotifyYoungCppGCCompleted();
3071cb0ef41Sopenharmony_ci  } else {
3081cb0ef41Sopenharmony_ci    DCHECK(!last_full_gc_event_);
3091cb0ef41Sopenharmony_ci    last_full_gc_event_ = cppgc_event;
3101cb0ef41Sopenharmony_ci    tracer->NotifyFullCppGCCompleted();
3111cb0ef41Sopenharmony_ci  }
3121cb0ef41Sopenharmony_ci}
3131cb0ef41Sopenharmony_ci
3141cb0ef41Sopenharmony_civoid CppHeap::MetricRecorderAdapter::AddMainThreadEvent(
3151cb0ef41Sopenharmony_ci    const MainThreadIncrementalMark& cppgc_event) {
3161cb0ef41Sopenharmony_ci  // Incremental marking steps might be nested in V8 marking steps. In such
3171cb0ef41Sopenharmony_ci  // cases, stash the relevant values and delegate to V8 to report them. For
3181cb0ef41Sopenharmony_ci  // non-nested steps, report to the Recorder directly.
3191cb0ef41Sopenharmony_ci  if (cpp_heap_.is_in_v8_marking_step_) {
3201cb0ef41Sopenharmony_ci    last_incremental_mark_event_ = cppgc_event;
3211cb0ef41Sopenharmony_ci    return;
3221cb0ef41Sopenharmony_ci  }
3231cb0ef41Sopenharmony_ci  // This is a standalone incremental marking step.
3241cb0ef41Sopenharmony_ci  const std::shared_ptr<metrics::Recorder>& recorder =
3251cb0ef41Sopenharmony_ci      GetIsolate()->metrics_recorder();
3261cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(recorder);
3271cb0ef41Sopenharmony_ci  if (!recorder->HasEmbedderRecorder()) return;
3281cb0ef41Sopenharmony_ci  incremental_mark_batched_events_.events.emplace_back();
3291cb0ef41Sopenharmony_ci  incremental_mark_batched_events_.events.back().cpp_wall_clock_duration_in_us =
3301cb0ef41Sopenharmony_ci      cppgc_event.duration_us;
3311cb0ef41Sopenharmony_ci  if (incremental_mark_batched_events_.events.size() == kMaxBatchedEvents) {
3321cb0ef41Sopenharmony_ci    recorder->AddMainThreadEvent(std::move(incremental_mark_batched_events_),
3331cb0ef41Sopenharmony_ci                                 GetContextId());
3341cb0ef41Sopenharmony_ci    incremental_mark_batched_events_ = {};
3351cb0ef41Sopenharmony_ci  }
3361cb0ef41Sopenharmony_ci}
3371cb0ef41Sopenharmony_ci
3381cb0ef41Sopenharmony_civoid CppHeap::MetricRecorderAdapter::AddMainThreadEvent(
3391cb0ef41Sopenharmony_ci    const MainThreadIncrementalSweep& cppgc_event) {
3401cb0ef41Sopenharmony_ci  // Incremental sweeping steps are never nested inside V8 sweeping steps, so
3411cb0ef41Sopenharmony_ci  // report to the Recorder directly.
3421cb0ef41Sopenharmony_ci  const std::shared_ptr<metrics::Recorder>& recorder =
3431cb0ef41Sopenharmony_ci      GetIsolate()->metrics_recorder();
3441cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(recorder);
3451cb0ef41Sopenharmony_ci  if (!recorder->HasEmbedderRecorder()) return;
3461cb0ef41Sopenharmony_ci  incremental_sweep_batched_events_.events.emplace_back();
3471cb0ef41Sopenharmony_ci  incremental_sweep_batched_events_.events.back()
3481cb0ef41Sopenharmony_ci      .cpp_wall_clock_duration_in_us = cppgc_event.duration_us;
3491cb0ef41Sopenharmony_ci  if (incremental_sweep_batched_events_.events.size() == kMaxBatchedEvents) {
3501cb0ef41Sopenharmony_ci    recorder->AddMainThreadEvent(std::move(incremental_sweep_batched_events_),
3511cb0ef41Sopenharmony_ci                                 GetContextId());
3521cb0ef41Sopenharmony_ci    incremental_sweep_batched_events_ = {};
3531cb0ef41Sopenharmony_ci  }
3541cb0ef41Sopenharmony_ci}
3551cb0ef41Sopenharmony_ci
3561cb0ef41Sopenharmony_civoid CppHeap::MetricRecorderAdapter::FlushBatchedIncrementalEvents() {
3571cb0ef41Sopenharmony_ci  const std::shared_ptr<metrics::Recorder>& recorder =
3581cb0ef41Sopenharmony_ci      GetIsolate()->metrics_recorder();
3591cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(recorder);
3601cb0ef41Sopenharmony_ci  if (!incremental_mark_batched_events_.events.empty()) {
3611cb0ef41Sopenharmony_ci    recorder->AddMainThreadEvent(std::move(incremental_mark_batched_events_),
3621cb0ef41Sopenharmony_ci                                 GetContextId());
3631cb0ef41Sopenharmony_ci    incremental_mark_batched_events_ = {};
3641cb0ef41Sopenharmony_ci  }
3651cb0ef41Sopenharmony_ci  if (!incremental_sweep_batched_events_.events.empty()) {
3661cb0ef41Sopenharmony_ci    recorder->AddMainThreadEvent(std::move(incremental_sweep_batched_events_),
3671cb0ef41Sopenharmony_ci                                 GetContextId());
3681cb0ef41Sopenharmony_ci    incremental_sweep_batched_events_ = {};
3691cb0ef41Sopenharmony_ci  }
3701cb0ef41Sopenharmony_ci}
3711cb0ef41Sopenharmony_ci
3721cb0ef41Sopenharmony_cibool CppHeap::MetricRecorderAdapter::FullGCMetricsReportPending() const {
3731cb0ef41Sopenharmony_ci  return last_full_gc_event_.has_value();
3741cb0ef41Sopenharmony_ci}
3751cb0ef41Sopenharmony_ci
3761cb0ef41Sopenharmony_cibool CppHeap::MetricRecorderAdapter::YoungGCMetricsReportPending() const {
3771cb0ef41Sopenharmony_ci  return last_young_gc_event_.has_value();
3781cb0ef41Sopenharmony_ci}
3791cb0ef41Sopenharmony_ci
3801cb0ef41Sopenharmony_ciconst base::Optional<cppgc::internal::MetricRecorder::GCCycle>
3811cb0ef41Sopenharmony_ciCppHeap::MetricRecorderAdapter::ExtractLastFullGcEvent() {
3821cb0ef41Sopenharmony_ci  auto res = std::move(last_full_gc_event_);
3831cb0ef41Sopenharmony_ci  last_full_gc_event_.reset();
3841cb0ef41Sopenharmony_ci  return res;
3851cb0ef41Sopenharmony_ci}
3861cb0ef41Sopenharmony_ci
3871cb0ef41Sopenharmony_ciconst base::Optional<cppgc::internal::MetricRecorder::GCCycle>
3881cb0ef41Sopenharmony_ciCppHeap::MetricRecorderAdapter::ExtractLastYoungGcEvent() {
3891cb0ef41Sopenharmony_ci  auto res = std::move(last_young_gc_event_);
3901cb0ef41Sopenharmony_ci  last_young_gc_event_.reset();
3911cb0ef41Sopenharmony_ci  return res;
3921cb0ef41Sopenharmony_ci}
3931cb0ef41Sopenharmony_ci
3941cb0ef41Sopenharmony_ciconst base::Optional<cppgc::internal::MetricRecorder::MainThreadIncrementalMark>
3951cb0ef41Sopenharmony_ciCppHeap::MetricRecorderAdapter::ExtractLastIncrementalMarkEvent() {
3961cb0ef41Sopenharmony_ci  auto res = std::move(last_incremental_mark_event_);
3971cb0ef41Sopenharmony_ci  last_incremental_mark_event_.reset();
3981cb0ef41Sopenharmony_ci  return res;
3991cb0ef41Sopenharmony_ci}
4001cb0ef41Sopenharmony_ci
4011cb0ef41Sopenharmony_civoid CppHeap::MetricRecorderAdapter::ClearCachedEvents() {
4021cb0ef41Sopenharmony_ci  incremental_mark_batched_events_.events.clear();
4031cb0ef41Sopenharmony_ci  incremental_sweep_batched_events_.events.clear();
4041cb0ef41Sopenharmony_ci  last_incremental_mark_event_.reset();
4051cb0ef41Sopenharmony_ci  last_full_gc_event_.reset();
4061cb0ef41Sopenharmony_ci  last_young_gc_event_.reset();
4071cb0ef41Sopenharmony_ci}
4081cb0ef41Sopenharmony_ci
4091cb0ef41Sopenharmony_ciIsolate* CppHeap::MetricRecorderAdapter::GetIsolate() const {
4101cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(cpp_heap_.isolate());
4111cb0ef41Sopenharmony_ci  return reinterpret_cast<Isolate*>(cpp_heap_.isolate());
4121cb0ef41Sopenharmony_ci}
4131cb0ef41Sopenharmony_ci
4141cb0ef41Sopenharmony_civ8::metrics::Recorder::ContextId CppHeap::MetricRecorderAdapter::GetContextId()
4151cb0ef41Sopenharmony_ci    const {
4161cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(GetIsolate());
4171cb0ef41Sopenharmony_ci  if (GetIsolate()->context().is_null())
4181cb0ef41Sopenharmony_ci    return v8::metrics::Recorder::ContextId::Empty();
4191cb0ef41Sopenharmony_ci  HandleScope scope(GetIsolate());
4201cb0ef41Sopenharmony_ci  return GetIsolate()->GetOrRegisterRecorderContextId(
4211cb0ef41Sopenharmony_ci      GetIsolate()->native_context());
4221cb0ef41Sopenharmony_ci}
4231cb0ef41Sopenharmony_ci
4241cb0ef41Sopenharmony_ciCppHeap::CppHeap(
4251cb0ef41Sopenharmony_ci    v8::Platform* platform,
4261cb0ef41Sopenharmony_ci    const std::vector<std::unique_ptr<cppgc::CustomSpaceBase>>& custom_spaces,
4271cb0ef41Sopenharmony_ci    const v8::WrapperDescriptor& wrapper_descriptor)
4281cb0ef41Sopenharmony_ci    : cppgc::internal::HeapBase(
4291cb0ef41Sopenharmony_ci          std::make_shared<CppgcPlatformAdapter>(platform), custom_spaces,
4301cb0ef41Sopenharmony_ci          cppgc::internal::HeapBase::StackSupport::
4311cb0ef41Sopenharmony_ci              kSupportsConservativeStackScan,
4321cb0ef41Sopenharmony_ci          FLAG_single_threaded_gc ? MarkingType::kIncremental
4331cb0ef41Sopenharmony_ci                                  : MarkingType::kIncrementalAndConcurrent,
4341cb0ef41Sopenharmony_ci          FLAG_single_threaded_gc ? SweepingType::kIncremental
4351cb0ef41Sopenharmony_ci                                  : SweepingType::kIncrementalAndConcurrent),
4361cb0ef41Sopenharmony_ci      wrapper_descriptor_(wrapper_descriptor) {
4371cb0ef41Sopenharmony_ci  CHECK_NE(WrapperDescriptor::kUnknownEmbedderId,
4381cb0ef41Sopenharmony_ci           wrapper_descriptor_.embedder_id_for_garbage_collected);
4391cb0ef41Sopenharmony_ci  // Enter no GC scope. `AttachIsolate()` removes this and allows triggering
4401cb0ef41Sopenharmony_ci  // garbage collections.
4411cb0ef41Sopenharmony_ci  no_gc_scope_++;
4421cb0ef41Sopenharmony_ci  stats_collector()->RegisterObserver(this);
4431cb0ef41Sopenharmony_ci}
4441cb0ef41Sopenharmony_ci
4451cb0ef41Sopenharmony_ciCppHeap::~CppHeap() {
4461cb0ef41Sopenharmony_ci  if (isolate_) {
4471cb0ef41Sopenharmony_ci    isolate_->heap()->DetachCppHeap();
4481cb0ef41Sopenharmony_ci  }
4491cb0ef41Sopenharmony_ci}
4501cb0ef41Sopenharmony_ci
4511cb0ef41Sopenharmony_civoid CppHeap::Terminate() {
4521cb0ef41Sopenharmony_ci  // Must not be attached to a heap when invoking termination GCs.
4531cb0ef41Sopenharmony_ci  CHECK(!isolate_);
4541cb0ef41Sopenharmony_ci  // Gracefully terminate the C++ heap invoking destructors.
4551cb0ef41Sopenharmony_ci  HeapBase::Terminate();
4561cb0ef41Sopenharmony_ci}
4571cb0ef41Sopenharmony_ci
4581cb0ef41Sopenharmony_civoid CppHeap::AttachIsolate(Isolate* isolate) {
4591cb0ef41Sopenharmony_ci  CHECK(!in_detached_testing_mode_);
4601cb0ef41Sopenharmony_ci  CHECK_NULL(isolate_);
4611cb0ef41Sopenharmony_ci  isolate_ = isolate;
4621cb0ef41Sopenharmony_ci  static_cast<CppgcPlatformAdapter*>(platform())
4631cb0ef41Sopenharmony_ci      ->SetIsolate(reinterpret_cast<v8::Isolate*>(isolate_));
4641cb0ef41Sopenharmony_ci  if (isolate_->heap_profiler()) {
4651cb0ef41Sopenharmony_ci    isolate_->heap_profiler()->AddBuildEmbedderGraphCallback(
4661cb0ef41Sopenharmony_ci        &CppGraphBuilder::Run, this);
4671cb0ef41Sopenharmony_ci  }
4681cb0ef41Sopenharmony_ci  SetMetricRecorder(std::make_unique<MetricRecorderAdapter>(*this));
4691cb0ef41Sopenharmony_ci  isolate_->global_handles()->SetStackStart(base::Stack::GetStackStart());
4701cb0ef41Sopenharmony_ci  oom_handler().SetCustomHandler(&FatalOutOfMemoryHandlerImpl);
4711cb0ef41Sopenharmony_ci  no_gc_scope_--;
4721cb0ef41Sopenharmony_ci}
4731cb0ef41Sopenharmony_ci
4741cb0ef41Sopenharmony_civoid CppHeap::DetachIsolate() {
4751cb0ef41Sopenharmony_ci  // TODO(chromium:1056170): Investigate whether this can be enforced with a
4761cb0ef41Sopenharmony_ci  // CHECK across all relevant embedders and setups.
4771cb0ef41Sopenharmony_ci  if (!isolate_) return;
4781cb0ef41Sopenharmony_ci
4791cb0ef41Sopenharmony_ci  // Delegate to existing EmbedderHeapTracer API to finish any ongoing garbage
4801cb0ef41Sopenharmony_ci  // collection.
4811cb0ef41Sopenharmony_ci  if (isolate_->heap()->incremental_marking()->IsMarking()) {
4821cb0ef41Sopenharmony_ci    isolate_->heap()->FinalizeIncrementalMarkingAtomically(
4831cb0ef41Sopenharmony_ci        i::GarbageCollectionReason::kExternalFinalize);
4841cb0ef41Sopenharmony_ci  }
4851cb0ef41Sopenharmony_ci  sweeper_.FinishIfRunning();
4861cb0ef41Sopenharmony_ci
4871cb0ef41Sopenharmony_ci  auto* heap_profiler = isolate_->heap_profiler();
4881cb0ef41Sopenharmony_ci  if (heap_profiler) {
4891cb0ef41Sopenharmony_ci    heap_profiler->RemoveBuildEmbedderGraphCallback(&CppGraphBuilder::Run,
4901cb0ef41Sopenharmony_ci                                                    this);
4911cb0ef41Sopenharmony_ci  }
4921cb0ef41Sopenharmony_ci  SetMetricRecorder(nullptr);
4931cb0ef41Sopenharmony_ci  isolate_ = nullptr;
4941cb0ef41Sopenharmony_ci  // Any future garbage collections will ignore the V8->C++ references.
4951cb0ef41Sopenharmony_ci  oom_handler().SetCustomHandler(nullptr);
4961cb0ef41Sopenharmony_ci  // Enter no GC scope.
4971cb0ef41Sopenharmony_ci  no_gc_scope_++;
4981cb0ef41Sopenharmony_ci}
4991cb0ef41Sopenharmony_ci
5001cb0ef41Sopenharmony_cinamespace {
5011cb0ef41Sopenharmony_ci
5021cb0ef41Sopenharmony_cibool IsMemoryReducingGC(CppHeap::GarbageCollectionFlags flags) {
5031cb0ef41Sopenharmony_ci  return flags & CppHeap::GarbageCollectionFlagValues::kReduceMemory;
5041cb0ef41Sopenharmony_ci}
5051cb0ef41Sopenharmony_ci
5061cb0ef41Sopenharmony_cibool IsForceGC(CppHeap::GarbageCollectionFlags flags) {
5071cb0ef41Sopenharmony_ci  return flags & CppHeap::GarbageCollectionFlagValues::kForced;
5081cb0ef41Sopenharmony_ci}
5091cb0ef41Sopenharmony_ci
5101cb0ef41Sopenharmony_cibool ShouldReduceMemory(CppHeap::GarbageCollectionFlags flags) {
5111cb0ef41Sopenharmony_ci  return IsMemoryReducingGC(flags) || IsForceGC(flags);
5121cb0ef41Sopenharmony_ci}
5131cb0ef41Sopenharmony_ci
5141cb0ef41Sopenharmony_ci}  // namespace
5151cb0ef41Sopenharmony_ci
5161cb0ef41Sopenharmony_ciCppHeap::MarkingType CppHeap::SelectMarkingType() const {
5171cb0ef41Sopenharmony_ci  // For now, force atomic marking for minor collections.
5181cb0ef41Sopenharmony_ci  if (*collection_type_ == CollectionType::kMinor) return MarkingType::kAtomic;
5191cb0ef41Sopenharmony_ci
5201cb0ef41Sopenharmony_ci  if (IsForceGC(current_gc_flags_) && !force_incremental_marking_for_testing_)
5211cb0ef41Sopenharmony_ci    return MarkingType::kAtomic;
5221cb0ef41Sopenharmony_ci
5231cb0ef41Sopenharmony_ci  return marking_support();
5241cb0ef41Sopenharmony_ci}
5251cb0ef41Sopenharmony_ci
5261cb0ef41Sopenharmony_ciCppHeap::SweepingType CppHeap::SelectSweepingType() const {
5271cb0ef41Sopenharmony_ci  if (IsForceGC(current_gc_flags_)) return SweepingType::kAtomic;
5281cb0ef41Sopenharmony_ci
5291cb0ef41Sopenharmony_ci  return sweeping_support();
5301cb0ef41Sopenharmony_ci}
5311cb0ef41Sopenharmony_ci
5321cb0ef41Sopenharmony_civoid CppHeap::InitializeTracing(CollectionType collection_type,
5331cb0ef41Sopenharmony_ci                                GarbageCollectionFlags gc_flags) {
5341cb0ef41Sopenharmony_ci  CHECK(!sweeper_.IsSweepingInProgress());
5351cb0ef41Sopenharmony_ci
5361cb0ef41Sopenharmony_ci  // Check that previous cycle metrics for the same collection type have been
5371cb0ef41Sopenharmony_ci  // reported.
5381cb0ef41Sopenharmony_ci  if (GetMetricRecorder()) {
5391cb0ef41Sopenharmony_ci    if (collection_type == CollectionType::kMajor)
5401cb0ef41Sopenharmony_ci      DCHECK(!GetMetricRecorder()->FullGCMetricsReportPending());
5411cb0ef41Sopenharmony_ci    else
5421cb0ef41Sopenharmony_ci      DCHECK(!GetMetricRecorder()->YoungGCMetricsReportPending());
5431cb0ef41Sopenharmony_ci  }
5441cb0ef41Sopenharmony_ci
5451cb0ef41Sopenharmony_ci  DCHECK(!collection_type_);
5461cb0ef41Sopenharmony_ci  collection_type_ = collection_type;
5471cb0ef41Sopenharmony_ci
5481cb0ef41Sopenharmony_ci#if defined(CPPGC_YOUNG_GENERATION)
5491cb0ef41Sopenharmony_ci  if (*collection_type_ == CollectionType::kMajor)
5501cb0ef41Sopenharmony_ci    cppgc::internal::SequentialUnmarker unmarker(raw_heap());
5511cb0ef41Sopenharmony_ci#endif  // defined(CPPGC_YOUNG_GENERATION)
5521cb0ef41Sopenharmony_ci
5531cb0ef41Sopenharmony_ci  current_gc_flags_ = gc_flags;
5541cb0ef41Sopenharmony_ci
5551cb0ef41Sopenharmony_ci  const UnifiedHeapMarker::MarkingConfig marking_config{
5561cb0ef41Sopenharmony_ci      *collection_type_, StackState::kNoHeapPointers, SelectMarkingType(),
5571cb0ef41Sopenharmony_ci      IsForceGC(current_gc_flags_)
5581cb0ef41Sopenharmony_ci          ? UnifiedHeapMarker::MarkingConfig::IsForcedGC::kForced
5591cb0ef41Sopenharmony_ci          : UnifiedHeapMarker::MarkingConfig::IsForcedGC::kNotForced};
5601cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(!isolate_,
5611cb0ef41Sopenharmony_ci                 (MarkingType::kAtomic == marking_config.marking_type) ||
5621cb0ef41Sopenharmony_ci                     force_incremental_marking_for_testing_);
5631cb0ef41Sopenharmony_ci  if (ShouldReduceMemory(current_gc_flags_)) {
5641cb0ef41Sopenharmony_ci    // Only enable compaction when in a memory reduction garbage collection as
5651cb0ef41Sopenharmony_ci    // it may significantly increase the final garbage collection pause.
5661cb0ef41Sopenharmony_ci    compactor_.InitializeIfShouldCompact(marking_config.marking_type,
5671cb0ef41Sopenharmony_ci                                         marking_config.stack_state);
5681cb0ef41Sopenharmony_ci  }
5691cb0ef41Sopenharmony_ci  marker_ = std::make_unique<UnifiedHeapMarker>(
5701cb0ef41Sopenharmony_ci      isolate_ ? isolate()->heap() : nullptr, AsBase(), platform_.get(),
5711cb0ef41Sopenharmony_ci      marking_config);
5721cb0ef41Sopenharmony_ci}
5731cb0ef41Sopenharmony_ci
5741cb0ef41Sopenharmony_civoid CppHeap::StartTracing() {
5751cb0ef41Sopenharmony_ci  if (isolate_) {
5761cb0ef41Sopenharmony_ci    // Reuse the same local worklist for the mutator marking state which results
5771cb0ef41Sopenharmony_ci    // in directly processing the objects by the JS logic. Also avoids
5781cb0ef41Sopenharmony_ci    // publishing local objects.
5791cb0ef41Sopenharmony_ci    static_cast<UnifiedHeapMarker*>(marker_.get())
5801cb0ef41Sopenharmony_ci        ->GetMutatorUnifiedHeapMarkingState()
5811cb0ef41Sopenharmony_ci        .Update(isolate_->heap()
5821cb0ef41Sopenharmony_ci                    ->mark_compact_collector()
5831cb0ef41Sopenharmony_ci                    ->local_marking_worklists());
5841cb0ef41Sopenharmony_ci  }
5851cb0ef41Sopenharmony_ci  marker_->StartMarking();
5861cb0ef41Sopenharmony_ci  marking_done_ = false;
5871cb0ef41Sopenharmony_ci}
5881cb0ef41Sopenharmony_ci
5891cb0ef41Sopenharmony_cibool CppHeap::AdvanceTracing(double max_duration) {
5901cb0ef41Sopenharmony_ci  is_in_v8_marking_step_ = true;
5911cb0ef41Sopenharmony_ci  cppgc::internal::StatsCollector::EnabledScope stats_scope(
5921cb0ef41Sopenharmony_ci      stats_collector(),
5931cb0ef41Sopenharmony_ci      in_atomic_pause_ ? cppgc::internal::StatsCollector::kAtomicMark
5941cb0ef41Sopenharmony_ci                       : cppgc::internal::StatsCollector::kIncrementalMark);
5951cb0ef41Sopenharmony_ci  const v8::base::TimeDelta deadline =
5961cb0ef41Sopenharmony_ci      in_atomic_pause_ ? v8::base::TimeDelta::Max()
5971cb0ef41Sopenharmony_ci                       : v8::base::TimeDelta::FromMillisecondsD(max_duration);
5981cb0ef41Sopenharmony_ci  const size_t marked_bytes_limit = in_atomic_pause_ ? SIZE_MAX : 0;
5991cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(marker_);
6001cb0ef41Sopenharmony_ci  // TODO(chromium:1056170): Replace when unified heap transitions to
6011cb0ef41Sopenharmony_ci  // bytes-based deadline.
6021cb0ef41Sopenharmony_ci  marking_done_ =
6031cb0ef41Sopenharmony_ci      marker_->AdvanceMarkingWithLimits(deadline, marked_bytes_limit);
6041cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(in_atomic_pause_, marking_done_);
6051cb0ef41Sopenharmony_ci  is_in_v8_marking_step_ = false;
6061cb0ef41Sopenharmony_ci  return marking_done_;
6071cb0ef41Sopenharmony_ci}
6081cb0ef41Sopenharmony_ci
6091cb0ef41Sopenharmony_cibool CppHeap::IsTracingDone() { return marking_done_; }
6101cb0ef41Sopenharmony_ci
6111cb0ef41Sopenharmony_civoid CppHeap::EnterFinalPause(cppgc::EmbedderStackState stack_state) {
6121cb0ef41Sopenharmony_ci  CHECK(!in_disallow_gc_scope());
6131cb0ef41Sopenharmony_ci  in_atomic_pause_ = true;
6141cb0ef41Sopenharmony_ci  marker_->EnterAtomicPause(stack_state);
6151cb0ef41Sopenharmony_ci  if (isolate_ && *collection_type_ == CollectionType::kMinor) {
6161cb0ef41Sopenharmony_ci    // Visit V8 -> cppgc references.
6171cb0ef41Sopenharmony_ci    TraceV8ToCppGCReferences(isolate_,
6181cb0ef41Sopenharmony_ci                             static_cast<UnifiedHeapMarker*>(marker_.get())
6191cb0ef41Sopenharmony_ci                                 ->GetMutatorMarkingState(),
6201cb0ef41Sopenharmony_ci                             wrapper_descriptor_);
6211cb0ef41Sopenharmony_ci  }
6221cb0ef41Sopenharmony_ci  compactor_.CancelIfShouldNotCompact(MarkingType::kAtomic, stack_state);
6231cb0ef41Sopenharmony_ci}
6241cb0ef41Sopenharmony_ci
6251cb0ef41Sopenharmony_cibool CppHeap::FinishConcurrentMarkingIfNeeded() {
6261cb0ef41Sopenharmony_ci  return marker_->JoinConcurrentMarkingIfNeeded();
6271cb0ef41Sopenharmony_ci}
6281cb0ef41Sopenharmony_ci
6291cb0ef41Sopenharmony_civoid CppHeap::TraceEpilogue() {
6301cb0ef41Sopenharmony_ci  CHECK(in_atomic_pause_);
6311cb0ef41Sopenharmony_ci  CHECK(marking_done_);
6321cb0ef41Sopenharmony_ci  {
6331cb0ef41Sopenharmony_ci    cppgc::subtle::DisallowGarbageCollectionScope disallow_gc_scope(*this);
6341cb0ef41Sopenharmony_ci    marker_->LeaveAtomicPause();
6351cb0ef41Sopenharmony_ci  }
6361cb0ef41Sopenharmony_ci  marker_.reset();
6371cb0ef41Sopenharmony_ci  if (isolate_) {
6381cb0ef41Sopenharmony_ci    auto* tracer = isolate_->heap()->local_embedder_heap_tracer();
6391cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(tracer);
6401cb0ef41Sopenharmony_ci    tracer->UpdateRemoteStats(
6411cb0ef41Sopenharmony_ci        stats_collector_->marked_bytes(),
6421cb0ef41Sopenharmony_ci        stats_collector_->marking_time().InMillisecondsF());
6431cb0ef41Sopenharmony_ci  }
6441cb0ef41Sopenharmony_ci  // The allocated bytes counter in v8 was reset to the current marked bytes, so
6451cb0ef41Sopenharmony_ci  // any pending allocated bytes updates should be discarded.
6461cb0ef41Sopenharmony_ci  buffered_allocated_bytes_ = 0;
6471cb0ef41Sopenharmony_ci  const size_t bytes_allocated_in_prefinalizers = ExecutePreFinalizers();
6481cb0ef41Sopenharmony_ci#if CPPGC_VERIFY_HEAP
6491cb0ef41Sopenharmony_ci  UnifiedHeapMarkingVerifier verifier(*this, *collection_type_);
6501cb0ef41Sopenharmony_ci  verifier.Run(stack_state_of_prev_gc(), stack_end_of_current_gc(),
6511cb0ef41Sopenharmony_ci               stats_collector()->marked_bytes_on_current_cycle() +
6521cb0ef41Sopenharmony_ci                   bytes_allocated_in_prefinalizers);
6531cb0ef41Sopenharmony_ci#endif  // CPPGC_VERIFY_HEAP
6541cb0ef41Sopenharmony_ci  USE(bytes_allocated_in_prefinalizers);
6551cb0ef41Sopenharmony_ci
6561cb0ef41Sopenharmony_ci#if defined(CPPGC_YOUNG_GENERATION)
6571cb0ef41Sopenharmony_ci  ResetRememberedSet();
6581cb0ef41Sopenharmony_ci#endif  // defined(CPPGC_YOUNG_GENERATION)
6591cb0ef41Sopenharmony_ci
6601cb0ef41Sopenharmony_ci  {
6611cb0ef41Sopenharmony_ci    cppgc::subtle::NoGarbageCollectionScope no_gc(*this);
6621cb0ef41Sopenharmony_ci    cppgc::internal::Sweeper::SweepingConfig::CompactableSpaceHandling
6631cb0ef41Sopenharmony_ci        compactable_space_handling = compactor_.CompactSpacesIfEnabled();
6641cb0ef41Sopenharmony_ci    const cppgc::internal::Sweeper::SweepingConfig sweeping_config{
6651cb0ef41Sopenharmony_ci        SelectSweepingType(), compactable_space_handling,
6661cb0ef41Sopenharmony_ci        ShouldReduceMemory(current_gc_flags_)
6671cb0ef41Sopenharmony_ci            ? cppgc::internal::Sweeper::SweepingConfig::FreeMemoryHandling::
6681cb0ef41Sopenharmony_ci                  kDiscardWherePossible
6691cb0ef41Sopenharmony_ci            : cppgc::internal::Sweeper::SweepingConfig::FreeMemoryHandling::
6701cb0ef41Sopenharmony_ci                  kDoNotDiscard};
6711cb0ef41Sopenharmony_ci    DCHECK_IMPLIES(!isolate_,
6721cb0ef41Sopenharmony_ci                   SweepingType::kAtomic == sweeping_config.sweeping_type);
6731cb0ef41Sopenharmony_ci    sweeper().Start(sweeping_config);
6741cb0ef41Sopenharmony_ci  }
6751cb0ef41Sopenharmony_ci  in_atomic_pause_ = false;
6761cb0ef41Sopenharmony_ci  collection_type_.reset();
6771cb0ef41Sopenharmony_ci  sweeper().NotifyDoneIfNeeded();
6781cb0ef41Sopenharmony_ci}
6791cb0ef41Sopenharmony_ci
6801cb0ef41Sopenharmony_civoid CppHeap::RunMinorGC(StackState stack_state) {
6811cb0ef41Sopenharmony_ci  DCHECK(!sweeper_.IsSweepingInProgress());
6821cb0ef41Sopenharmony_ci
6831cb0ef41Sopenharmony_ci  if (in_no_gc_scope()) return;
6841cb0ef41Sopenharmony_ci  // Minor GC does not support nesting in full GCs.
6851cb0ef41Sopenharmony_ci  if (IsMarking()) return;
6861cb0ef41Sopenharmony_ci  // Minor GCs with the stack are currently not supported.
6871cb0ef41Sopenharmony_ci  if (stack_state == StackState::kMayContainHeapPointers) return;
6881cb0ef41Sopenharmony_ci
6891cb0ef41Sopenharmony_ci  // Notify GC tracer that CppGC started young GC cycle.
6901cb0ef41Sopenharmony_ci  isolate_->heap()->tracer()->NotifyYoungCppGCRunning();
6911cb0ef41Sopenharmony_ci
6921cb0ef41Sopenharmony_ci  SetStackEndOfCurrentGC(v8::base::Stack::GetCurrentStackPosition());
6931cb0ef41Sopenharmony_ci
6941cb0ef41Sopenharmony_ci  // Perform an atomic GC, with starting incremental/concurrent marking and
6951cb0ef41Sopenharmony_ci  // immediately finalizing the garbage collection.
6961cb0ef41Sopenharmony_ci  InitializeTracing(CollectionType::kMinor,
6971cb0ef41Sopenharmony_ci                    GarbageCollectionFlagValues::kNoFlags);
6981cb0ef41Sopenharmony_ci  StartTracing();
6991cb0ef41Sopenharmony_ci  // TODO(chromium:1029379): Should be safe to run without stack.
7001cb0ef41Sopenharmony_ci  EnterFinalPause(cppgc::EmbedderStackState::kMayContainHeapPointers);
7011cb0ef41Sopenharmony_ci  CHECK(AdvanceTracing(std::numeric_limits<double>::infinity()));
7021cb0ef41Sopenharmony_ci  if (FinishConcurrentMarkingIfNeeded()) {
7031cb0ef41Sopenharmony_ci    CHECK(AdvanceTracing(std::numeric_limits<double>::infinity()));
7041cb0ef41Sopenharmony_ci  }
7051cb0ef41Sopenharmony_ci  TraceEpilogue();
7061cb0ef41Sopenharmony_ci}
7071cb0ef41Sopenharmony_ci
7081cb0ef41Sopenharmony_civoid CppHeap::AllocatedObjectSizeIncreased(size_t bytes) {
7091cb0ef41Sopenharmony_ci  buffered_allocated_bytes_ += static_cast<int64_t>(bytes);
7101cb0ef41Sopenharmony_ci  ReportBufferedAllocationSizeIfPossible();
7111cb0ef41Sopenharmony_ci}
7121cb0ef41Sopenharmony_ci
7131cb0ef41Sopenharmony_civoid CppHeap::AllocatedObjectSizeDecreased(size_t bytes) {
7141cb0ef41Sopenharmony_ci  buffered_allocated_bytes_ -= static_cast<int64_t>(bytes);
7151cb0ef41Sopenharmony_ci  ReportBufferedAllocationSizeIfPossible();
7161cb0ef41Sopenharmony_ci}
7171cb0ef41Sopenharmony_ci
7181cb0ef41Sopenharmony_civoid CppHeap::ReportBufferedAllocationSizeIfPossible() {
7191cb0ef41Sopenharmony_ci  // Avoid reporting to V8 in the following conditions as that may trigger GC
7201cb0ef41Sopenharmony_ci  // finalizations where not allowed.
7211cb0ef41Sopenharmony_ci  // - Recursive sweeping.
7221cb0ef41Sopenharmony_ci  // - GC forbidden scope.
7231cb0ef41Sopenharmony_ci  if (sweeper().IsSweepingOnMutatorThread() || in_no_gc_scope() || !isolate_) {
7241cb0ef41Sopenharmony_ci    return;
7251cb0ef41Sopenharmony_ci  }
7261cb0ef41Sopenharmony_ci
7271cb0ef41Sopenharmony_ci  // The calls below may trigger full GCs that are synchronous and also execute
7281cb0ef41Sopenharmony_ci  // epilogue callbacks. Since such callbacks may allocate, the counter must
7291cb0ef41Sopenharmony_ci  // already be zeroed by that time.
7301cb0ef41Sopenharmony_ci  const int64_t bytes_to_report = buffered_allocated_bytes_;
7311cb0ef41Sopenharmony_ci  buffered_allocated_bytes_ = 0;
7321cb0ef41Sopenharmony_ci
7331cb0ef41Sopenharmony_ci  auto* const tracer = isolate_->heap()->local_embedder_heap_tracer();
7341cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(tracer);
7351cb0ef41Sopenharmony_ci  if (bytes_to_report < 0) {
7361cb0ef41Sopenharmony_ci    tracer->DecreaseAllocatedSize(static_cast<size_t>(-bytes_to_report));
7371cb0ef41Sopenharmony_ci  } else {
7381cb0ef41Sopenharmony_ci    tracer->IncreaseAllocatedSize(static_cast<size_t>(bytes_to_report));
7391cb0ef41Sopenharmony_ci  }
7401cb0ef41Sopenharmony_ci}
7411cb0ef41Sopenharmony_ci
7421cb0ef41Sopenharmony_civoid CppHeap::CollectGarbageForTesting(CollectionType collection_type,
7431cb0ef41Sopenharmony_ci                                       StackState stack_state) {
7441cb0ef41Sopenharmony_ci  if (in_no_gc_scope()) return;
7451cb0ef41Sopenharmony_ci
7461cb0ef41Sopenharmony_ci  // Finish sweeping in case it is still running.
7471cb0ef41Sopenharmony_ci  sweeper().FinishIfRunning();
7481cb0ef41Sopenharmony_ci
7491cb0ef41Sopenharmony_ci  SetStackEndOfCurrentGC(v8::base::Stack::GetCurrentStackPosition());
7501cb0ef41Sopenharmony_ci
7511cb0ef41Sopenharmony_ci  if (isolate_) {
7521cb0ef41Sopenharmony_ci    reinterpret_cast<v8::Isolate*>(isolate_)
7531cb0ef41Sopenharmony_ci        ->RequestGarbageCollectionForTesting(
7541cb0ef41Sopenharmony_ci            v8::Isolate::kFullGarbageCollection, stack_state);
7551cb0ef41Sopenharmony_ci  } else {
7561cb0ef41Sopenharmony_ci    // Perform an atomic GC, with starting incremental/concurrent marking and
7571cb0ef41Sopenharmony_ci    // immediately finalizing the garbage collection.
7581cb0ef41Sopenharmony_ci    if (!IsMarking()) {
7591cb0ef41Sopenharmony_ci      InitializeTracing(collection_type, GarbageCollectionFlagValues::kForced);
7601cb0ef41Sopenharmony_ci      StartTracing();
7611cb0ef41Sopenharmony_ci    }
7621cb0ef41Sopenharmony_ci    EnterFinalPause(stack_state);
7631cb0ef41Sopenharmony_ci    CHECK(AdvanceTracing(std::numeric_limits<double>::infinity()));
7641cb0ef41Sopenharmony_ci    if (FinishConcurrentMarkingIfNeeded()) {
7651cb0ef41Sopenharmony_ci      CHECK(AdvanceTracing(std::numeric_limits<double>::infinity()));
7661cb0ef41Sopenharmony_ci    }
7671cb0ef41Sopenharmony_ci    TraceEpilogue();
7681cb0ef41Sopenharmony_ci  }
7691cb0ef41Sopenharmony_ci}
7701cb0ef41Sopenharmony_ci
7711cb0ef41Sopenharmony_civoid CppHeap::EnableDetachedGarbageCollectionsForTesting() {
7721cb0ef41Sopenharmony_ci  CHECK(!in_detached_testing_mode_);
7731cb0ef41Sopenharmony_ci  CHECK_NULL(isolate_);
7741cb0ef41Sopenharmony_ci  no_gc_scope_--;
7751cb0ef41Sopenharmony_ci  in_detached_testing_mode_ = true;
7761cb0ef41Sopenharmony_ci  static_cast<CppgcPlatformAdapter*>(platform())
7771cb0ef41Sopenharmony_ci      ->EnableDetachedModeForTesting();
7781cb0ef41Sopenharmony_ci}
7791cb0ef41Sopenharmony_ci
7801cb0ef41Sopenharmony_civoid CppHeap::StartIncrementalGarbageCollectionForTesting() {
7811cb0ef41Sopenharmony_ci  DCHECK(!in_no_gc_scope());
7821cb0ef41Sopenharmony_ci  DCHECK_NULL(isolate_);
7831cb0ef41Sopenharmony_ci  if (IsMarking()) return;
7841cb0ef41Sopenharmony_ci  force_incremental_marking_for_testing_ = true;
7851cb0ef41Sopenharmony_ci  InitializeTracing(CollectionType::kMajor,
7861cb0ef41Sopenharmony_ci                    GarbageCollectionFlagValues::kForced);
7871cb0ef41Sopenharmony_ci  StartTracing();
7881cb0ef41Sopenharmony_ci  force_incremental_marking_for_testing_ = false;
7891cb0ef41Sopenharmony_ci}
7901cb0ef41Sopenharmony_ci
7911cb0ef41Sopenharmony_civoid CppHeap::FinalizeIncrementalGarbageCollectionForTesting(
7921cb0ef41Sopenharmony_ci    cppgc::EmbedderStackState stack_state) {
7931cb0ef41Sopenharmony_ci  DCHECK(!in_no_gc_scope());
7941cb0ef41Sopenharmony_ci  DCHECK_NULL(isolate_);
7951cb0ef41Sopenharmony_ci  DCHECK(IsMarking());
7961cb0ef41Sopenharmony_ci  if (IsMarking()) {
7971cb0ef41Sopenharmony_ci    CollectGarbageForTesting(CollectionType::kMajor, stack_state);
7981cb0ef41Sopenharmony_ci  }
7991cb0ef41Sopenharmony_ci  sweeper_.FinishIfRunning();
8001cb0ef41Sopenharmony_ci}
8011cb0ef41Sopenharmony_ci
8021cb0ef41Sopenharmony_cinamespace {
8031cb0ef41Sopenharmony_ci
8041cb0ef41Sopenharmony_civoid ReportCustomSpaceStatistics(
8051cb0ef41Sopenharmony_ci    cppgc::internal::RawHeap& raw_heap,
8061cb0ef41Sopenharmony_ci    std::vector<cppgc::CustomSpaceIndex> custom_spaces,
8071cb0ef41Sopenharmony_ci    std::unique_ptr<CustomSpaceStatisticsReceiver> receiver) {
8081cb0ef41Sopenharmony_ci  for (auto custom_space_index : custom_spaces) {
8091cb0ef41Sopenharmony_ci    const cppgc::internal::BaseSpace* space =
8101cb0ef41Sopenharmony_ci        raw_heap.CustomSpace(custom_space_index);
8111cb0ef41Sopenharmony_ci    size_t allocated_bytes = std::accumulate(
8121cb0ef41Sopenharmony_ci        space->begin(), space->end(), 0, [](size_t sum, auto* page) {
8131cb0ef41Sopenharmony_ci          return sum + page->AllocatedBytesAtLastGC();
8141cb0ef41Sopenharmony_ci        });
8151cb0ef41Sopenharmony_ci    receiver->AllocatedBytes(custom_space_index, allocated_bytes);
8161cb0ef41Sopenharmony_ci  }
8171cb0ef41Sopenharmony_ci}
8181cb0ef41Sopenharmony_ci
8191cb0ef41Sopenharmony_ciclass CollectCustomSpaceStatisticsAtLastGCTask final : public v8::Task {
8201cb0ef41Sopenharmony_ci public:
8211cb0ef41Sopenharmony_ci  static constexpr v8::base::TimeDelta kTaskDelayMs =
8221cb0ef41Sopenharmony_ci      v8::base::TimeDelta::FromMilliseconds(10);
8231cb0ef41Sopenharmony_ci
8241cb0ef41Sopenharmony_ci  CollectCustomSpaceStatisticsAtLastGCTask(
8251cb0ef41Sopenharmony_ci      cppgc::internal::HeapBase& heap,
8261cb0ef41Sopenharmony_ci      std::vector<cppgc::CustomSpaceIndex> custom_spaces,
8271cb0ef41Sopenharmony_ci      std::unique_ptr<CustomSpaceStatisticsReceiver> receiver)
8281cb0ef41Sopenharmony_ci      : heap_(heap),
8291cb0ef41Sopenharmony_ci        custom_spaces_(std::move(custom_spaces)),
8301cb0ef41Sopenharmony_ci        receiver_(std::move(receiver)) {}
8311cb0ef41Sopenharmony_ci
8321cb0ef41Sopenharmony_ci  void Run() final {
8331cb0ef41Sopenharmony_ci    cppgc::internal::Sweeper& sweeper = heap_.sweeper();
8341cb0ef41Sopenharmony_ci    if (sweeper.PerformSweepOnMutatorThread(
8351cb0ef41Sopenharmony_ci            heap_.platform()->MonotonicallyIncreasingTime() +
8361cb0ef41Sopenharmony_ci            kStepSizeMs.InSecondsF())) {
8371cb0ef41Sopenharmony_ci      // Sweeping is done.
8381cb0ef41Sopenharmony_ci      DCHECK(!sweeper.IsSweepingInProgress());
8391cb0ef41Sopenharmony_ci      ReportCustomSpaceStatistics(heap_.raw_heap(), std::move(custom_spaces_),
8401cb0ef41Sopenharmony_ci                                  std::move(receiver_));
8411cb0ef41Sopenharmony_ci    } else {
8421cb0ef41Sopenharmony_ci      heap_.platform()->GetForegroundTaskRunner()->PostDelayedTask(
8431cb0ef41Sopenharmony_ci          std::make_unique<CollectCustomSpaceStatisticsAtLastGCTask>(
8441cb0ef41Sopenharmony_ci              heap_, std::move(custom_spaces_), std::move(receiver_)),
8451cb0ef41Sopenharmony_ci          kTaskDelayMs.InSecondsF());
8461cb0ef41Sopenharmony_ci    }
8471cb0ef41Sopenharmony_ci  }
8481cb0ef41Sopenharmony_ci
8491cb0ef41Sopenharmony_ci private:
8501cb0ef41Sopenharmony_ci  static constexpr v8::base::TimeDelta kStepSizeMs =
8511cb0ef41Sopenharmony_ci      v8::base::TimeDelta::FromMilliseconds(5);
8521cb0ef41Sopenharmony_ci
8531cb0ef41Sopenharmony_ci  cppgc::internal::HeapBase& heap_;
8541cb0ef41Sopenharmony_ci  std::vector<cppgc::CustomSpaceIndex> custom_spaces_;
8551cb0ef41Sopenharmony_ci  std::unique_ptr<CustomSpaceStatisticsReceiver> receiver_;
8561cb0ef41Sopenharmony_ci};
8571cb0ef41Sopenharmony_ci
8581cb0ef41Sopenharmony_ciconstexpr v8::base::TimeDelta
8591cb0ef41Sopenharmony_ci    CollectCustomSpaceStatisticsAtLastGCTask::kTaskDelayMs;
8601cb0ef41Sopenharmony_ciconstexpr v8::base::TimeDelta
8611cb0ef41Sopenharmony_ci    CollectCustomSpaceStatisticsAtLastGCTask::kStepSizeMs;
8621cb0ef41Sopenharmony_ci
8631cb0ef41Sopenharmony_ci}  // namespace
8641cb0ef41Sopenharmony_ci
8651cb0ef41Sopenharmony_civoid CppHeap::CollectCustomSpaceStatisticsAtLastGC(
8661cb0ef41Sopenharmony_ci    std::vector<cppgc::CustomSpaceIndex> custom_spaces,
8671cb0ef41Sopenharmony_ci    std::unique_ptr<CustomSpaceStatisticsReceiver> receiver) {
8681cb0ef41Sopenharmony_ci  if (sweeper().IsSweepingInProgress()) {
8691cb0ef41Sopenharmony_ci    platform()->GetForegroundTaskRunner()->PostDelayedTask(
8701cb0ef41Sopenharmony_ci        std::make_unique<CollectCustomSpaceStatisticsAtLastGCTask>(
8711cb0ef41Sopenharmony_ci            AsBase(), std::move(custom_spaces), std::move(receiver)),
8721cb0ef41Sopenharmony_ci        CollectCustomSpaceStatisticsAtLastGCTask::kTaskDelayMs.InSecondsF());
8731cb0ef41Sopenharmony_ci    return;
8741cb0ef41Sopenharmony_ci  }
8751cb0ef41Sopenharmony_ci  ReportCustomSpaceStatistics(raw_heap(), std::move(custom_spaces),
8761cb0ef41Sopenharmony_ci                              std::move(receiver));
8771cb0ef41Sopenharmony_ci}
8781cb0ef41Sopenharmony_ci
8791cb0ef41Sopenharmony_ciCppHeap::MetricRecorderAdapter* CppHeap::GetMetricRecorder() const {
8801cb0ef41Sopenharmony_ci  return static_cast<MetricRecorderAdapter*>(
8811cb0ef41Sopenharmony_ci      stats_collector_->GetMetricRecorder());
8821cb0ef41Sopenharmony_ci}
8831cb0ef41Sopenharmony_ci
8841cb0ef41Sopenharmony_civoid CppHeap::FinishSweepingIfRunning() { sweeper_.FinishIfRunning(); }
8851cb0ef41Sopenharmony_ci
8861cb0ef41Sopenharmony_civoid CppHeap::FinishSweepingIfOutOfWork() { sweeper_.FinishIfOutOfWork(); }
8871cb0ef41Sopenharmony_ci
8881cb0ef41Sopenharmony_cistd::unique_ptr<CppMarkingState> CppHeap::CreateCppMarkingState() {
8891cb0ef41Sopenharmony_ci  DCHECK(IsMarking());
8901cb0ef41Sopenharmony_ci  return std::make_unique<CppMarkingState>(
8911cb0ef41Sopenharmony_ci      isolate(), wrapper_descriptor_,
8921cb0ef41Sopenharmony_ci      std::make_unique<cppgc::internal::MarkingStateBase>(
8931cb0ef41Sopenharmony_ci          AsBase(),
8941cb0ef41Sopenharmony_ci          static_cast<UnifiedHeapMarker*>(marker())->GetMarkingWorklists()));
8951cb0ef41Sopenharmony_ci}
8961cb0ef41Sopenharmony_ci
8971cb0ef41Sopenharmony_cistd::unique_ptr<CppMarkingState>
8981cb0ef41Sopenharmony_ciCppHeap::CreateCppMarkingStateForMutatorThread() {
8991cb0ef41Sopenharmony_ci  DCHECK(IsMarking());
9001cb0ef41Sopenharmony_ci  return std::make_unique<CppMarkingState>(
9011cb0ef41Sopenharmony_ci      isolate(), wrapper_descriptor_,
9021cb0ef41Sopenharmony_ci      static_cast<UnifiedHeapMarker*>(marker())->GetMutatorMarkingState());
9031cb0ef41Sopenharmony_ci}
9041cb0ef41Sopenharmony_ci
9051cb0ef41Sopenharmony_ciCppHeap::PauseConcurrentMarkingScope::PauseConcurrentMarkingScope(
9061cb0ef41Sopenharmony_ci    CppHeap* cpp_heap) {
9071cb0ef41Sopenharmony_ci  if (cpp_heap && cpp_heap->marker()) {
9081cb0ef41Sopenharmony_ci    pause_scope_.emplace(*cpp_heap->marker());
9091cb0ef41Sopenharmony_ci  }
9101cb0ef41Sopenharmony_ci}
9111cb0ef41Sopenharmony_ci
9121cb0ef41Sopenharmony_ci}  // namespace internal
9131cb0ef41Sopenharmony_ci}  // namespace v8
914