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