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#ifndef INCLUDE_V8_CPPGC_H_ 61cb0ef41Sopenharmony_ci#define INCLUDE_V8_CPPGC_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <cstdint> 91cb0ef41Sopenharmony_ci#include <memory> 101cb0ef41Sopenharmony_ci#include <vector> 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ci#include "cppgc/common.h" 131cb0ef41Sopenharmony_ci#include "cppgc/custom-space.h" 141cb0ef41Sopenharmony_ci#include "cppgc/heap-statistics.h" 151cb0ef41Sopenharmony_ci#include "cppgc/visitor.h" 161cb0ef41Sopenharmony_ci#include "v8-internal.h" // NOLINT(build/include_directory) 171cb0ef41Sopenharmony_ci#include "v8-platform.h" // NOLINT(build/include_directory) 181cb0ef41Sopenharmony_ci#include "v8-traced-handle.h" // NOLINT(build/include_directory) 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_cinamespace cppgc { 211cb0ef41Sopenharmony_ciclass AllocationHandle; 221cb0ef41Sopenharmony_ciclass HeapHandle; 231cb0ef41Sopenharmony_ci} // namespace cppgc 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_cinamespace v8 { 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ciclass Object; 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_cinamespace internal { 301cb0ef41Sopenharmony_ciclass CppHeap; 311cb0ef41Sopenharmony_ci} // namespace internal 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ciclass CustomSpaceStatisticsReceiver; 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci/** 361cb0ef41Sopenharmony_ci * Describes how V8 wrapper objects maintain references to garbage-collected C++ 371cb0ef41Sopenharmony_ci * objects. 381cb0ef41Sopenharmony_ci */ 391cb0ef41Sopenharmony_cistruct WrapperDescriptor final { 401cb0ef41Sopenharmony_ci /** 411cb0ef41Sopenharmony_ci * The index used on `v8::Ojbect::SetAlignedPointerFromInternalField()` and 421cb0ef41Sopenharmony_ci * related APIs to add additional data to an object which is used to identify 431cb0ef41Sopenharmony_ci * JS->C++ references. 441cb0ef41Sopenharmony_ci */ 451cb0ef41Sopenharmony_ci using InternalFieldIndex = int; 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci /** 481cb0ef41Sopenharmony_ci * Unknown embedder id. The value is reserved for internal usages and must not 491cb0ef41Sopenharmony_ci * be used with `CppHeap`. 501cb0ef41Sopenharmony_ci */ 511cb0ef41Sopenharmony_ci static constexpr uint16_t kUnknownEmbedderId = UINT16_MAX; 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci constexpr WrapperDescriptor(InternalFieldIndex wrappable_type_index, 541cb0ef41Sopenharmony_ci InternalFieldIndex wrappable_instance_index, 551cb0ef41Sopenharmony_ci uint16_t embedder_id_for_garbage_collected) 561cb0ef41Sopenharmony_ci : wrappable_type_index(wrappable_type_index), 571cb0ef41Sopenharmony_ci wrappable_instance_index(wrappable_instance_index), 581cb0ef41Sopenharmony_ci embedder_id_for_garbage_collected(embedder_id_for_garbage_collected) {} 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci /** 611cb0ef41Sopenharmony_ci * Index of the wrappable type. 621cb0ef41Sopenharmony_ci */ 631cb0ef41Sopenharmony_ci InternalFieldIndex wrappable_type_index; 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci /** 661cb0ef41Sopenharmony_ci * Index of the wrappable instance. 671cb0ef41Sopenharmony_ci */ 681cb0ef41Sopenharmony_ci InternalFieldIndex wrappable_instance_index; 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci /** 711cb0ef41Sopenharmony_ci * Embedder id identifying instances of garbage-collected objects. It is 721cb0ef41Sopenharmony_ci * expected that the first field of the wrappable type is a uint16_t holding 731cb0ef41Sopenharmony_ci * the id. Only references to instances of wrappables types with an id of 741cb0ef41Sopenharmony_ci * `embedder_id_for_garbage_collected` will be considered by CppHeap. 751cb0ef41Sopenharmony_ci */ 761cb0ef41Sopenharmony_ci uint16_t embedder_id_for_garbage_collected; 771cb0ef41Sopenharmony_ci}; 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_cistruct V8_EXPORT CppHeapCreateParams { 801cb0ef41Sopenharmony_ci CppHeapCreateParams(const CppHeapCreateParams&) = delete; 811cb0ef41Sopenharmony_ci CppHeapCreateParams& operator=(const CppHeapCreateParams&) = delete; 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci std::vector<std::unique_ptr<cppgc::CustomSpaceBase>> custom_spaces; 841cb0ef41Sopenharmony_ci WrapperDescriptor wrapper_descriptor; 851cb0ef41Sopenharmony_ci}; 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci/** 881cb0ef41Sopenharmony_ci * A heap for allocating managed C++ objects. 891cb0ef41Sopenharmony_ci */ 901cb0ef41Sopenharmony_ciclass V8_EXPORT CppHeap { 911cb0ef41Sopenharmony_ci public: 921cb0ef41Sopenharmony_ci static std::unique_ptr<CppHeap> Create(v8::Platform* platform, 931cb0ef41Sopenharmony_ci const CppHeapCreateParams& params); 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci virtual ~CppHeap() = default; 961cb0ef41Sopenharmony_ci 971cb0ef41Sopenharmony_ci /** 981cb0ef41Sopenharmony_ci * \returns the opaque handle for allocating objects using 991cb0ef41Sopenharmony_ci * `MakeGarbageCollected()`. 1001cb0ef41Sopenharmony_ci */ 1011cb0ef41Sopenharmony_ci cppgc::AllocationHandle& GetAllocationHandle(); 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ci /** 1041cb0ef41Sopenharmony_ci * \returns the opaque heap handle which may be used to refer to this heap in 1051cb0ef41Sopenharmony_ci * other APIs. Valid as long as the underlying `CppHeap` is alive. 1061cb0ef41Sopenharmony_ci */ 1071cb0ef41Sopenharmony_ci cppgc::HeapHandle& GetHeapHandle(); 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci /** 1101cb0ef41Sopenharmony_ci * Terminate clears all roots and performs multiple garbage collections to 1111cb0ef41Sopenharmony_ci * reclaim potentially newly created objects in destructors. 1121cb0ef41Sopenharmony_ci * 1131cb0ef41Sopenharmony_ci * After this call, object allocation is prohibited. 1141cb0ef41Sopenharmony_ci */ 1151cb0ef41Sopenharmony_ci void Terminate(); 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ci /** 1181cb0ef41Sopenharmony_ci * \param detail_level specifies whether should return detailed 1191cb0ef41Sopenharmony_ci * statistics or only brief summary statistics. 1201cb0ef41Sopenharmony_ci * \returns current CppHeap statistics regarding memory consumption 1211cb0ef41Sopenharmony_ci * and utilization. 1221cb0ef41Sopenharmony_ci */ 1231cb0ef41Sopenharmony_ci cppgc::HeapStatistics CollectStatistics( 1241cb0ef41Sopenharmony_ci cppgc::HeapStatistics::DetailLevel detail_level); 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_ci /** 1271cb0ef41Sopenharmony_ci * Collects statistics for the given spaces and reports them to the receiver. 1281cb0ef41Sopenharmony_ci * 1291cb0ef41Sopenharmony_ci * \param custom_spaces a collection of custom space indicies. 1301cb0ef41Sopenharmony_ci * \param receiver an object that gets the results. 1311cb0ef41Sopenharmony_ci */ 1321cb0ef41Sopenharmony_ci void CollectCustomSpaceStatisticsAtLastGC( 1331cb0ef41Sopenharmony_ci std::vector<cppgc::CustomSpaceIndex> custom_spaces, 1341cb0ef41Sopenharmony_ci std::unique_ptr<CustomSpaceStatisticsReceiver> receiver); 1351cb0ef41Sopenharmony_ci 1361cb0ef41Sopenharmony_ci /** 1371cb0ef41Sopenharmony_ci * Enables a detached mode that allows testing garbage collection using 1381cb0ef41Sopenharmony_ci * `cppgc::testing` APIs. Once used, the heap cannot be attached to an 1391cb0ef41Sopenharmony_ci * `Isolate` anymore. 1401cb0ef41Sopenharmony_ci */ 1411cb0ef41Sopenharmony_ci void EnableDetachedGarbageCollectionsForTesting(); 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ci /** 1441cb0ef41Sopenharmony_ci * Performs a stop-the-world garbage collection for testing purposes. 1451cb0ef41Sopenharmony_ci * 1461cb0ef41Sopenharmony_ci * \param stack_state The stack state to assume for the garbage collection. 1471cb0ef41Sopenharmony_ci */ 1481cb0ef41Sopenharmony_ci void CollectGarbageForTesting(cppgc::EmbedderStackState stack_state); 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci /** 1511cb0ef41Sopenharmony_ci * Performs a stop-the-world minor garbage collection for testing purposes. 1521cb0ef41Sopenharmony_ci * 1531cb0ef41Sopenharmony_ci * \param stack_state The stack state to assume for the garbage collection. 1541cb0ef41Sopenharmony_ci */ 1551cb0ef41Sopenharmony_ci void CollectGarbageInYoungGenerationForTesting( 1561cb0ef41Sopenharmony_ci cppgc::EmbedderStackState stack_state); 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_ci private: 1591cb0ef41Sopenharmony_ci CppHeap() = default; 1601cb0ef41Sopenharmony_ci 1611cb0ef41Sopenharmony_ci friend class internal::CppHeap; 1621cb0ef41Sopenharmony_ci}; 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_ciclass JSVisitor : public cppgc::Visitor { 1651cb0ef41Sopenharmony_ci public: 1661cb0ef41Sopenharmony_ci explicit JSVisitor(cppgc::Visitor::Key key) : cppgc::Visitor(key) {} 1671cb0ef41Sopenharmony_ci ~JSVisitor() override = default; 1681cb0ef41Sopenharmony_ci 1691cb0ef41Sopenharmony_ci void Trace(const TracedReferenceBase& ref) { 1701cb0ef41Sopenharmony_ci if (ref.IsEmptyThreadSafe()) return; 1711cb0ef41Sopenharmony_ci Visit(ref); 1721cb0ef41Sopenharmony_ci } 1731cb0ef41Sopenharmony_ci 1741cb0ef41Sopenharmony_ci protected: 1751cb0ef41Sopenharmony_ci using cppgc::Visitor::Visit; 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_ci virtual void Visit(const TracedReferenceBase& ref) {} 1781cb0ef41Sopenharmony_ci}; 1791cb0ef41Sopenharmony_ci 1801cb0ef41Sopenharmony_ci/** 1811cb0ef41Sopenharmony_ci * Provided as input to `CppHeap::CollectCustomSpaceStatisticsAtLastGC()`. 1821cb0ef41Sopenharmony_ci * 1831cb0ef41Sopenharmony_ci * Its method is invoked with the results of the statistic collection. 1841cb0ef41Sopenharmony_ci */ 1851cb0ef41Sopenharmony_ciclass CustomSpaceStatisticsReceiver { 1861cb0ef41Sopenharmony_ci public: 1871cb0ef41Sopenharmony_ci virtual ~CustomSpaceStatisticsReceiver() = default; 1881cb0ef41Sopenharmony_ci /** 1891cb0ef41Sopenharmony_ci * Reports the size of a space at the last GC. It is called for each space 1901cb0ef41Sopenharmony_ci * that was requested in `CollectCustomSpaceStatisticsAtLastGC()`. 1911cb0ef41Sopenharmony_ci * 1921cb0ef41Sopenharmony_ci * \param space_index The index of the space. 1931cb0ef41Sopenharmony_ci * \param bytes The total size of live objects in the space at the last GC. 1941cb0ef41Sopenharmony_ci * It is zero if there was no GC yet. 1951cb0ef41Sopenharmony_ci */ 1961cb0ef41Sopenharmony_ci virtual void AllocatedBytes(cppgc::CustomSpaceIndex space_index, 1971cb0ef41Sopenharmony_ci size_t bytes) = 0; 1981cb0ef41Sopenharmony_ci}; 1991cb0ef41Sopenharmony_ci 2001cb0ef41Sopenharmony_ci} // namespace v8 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_cinamespace cppgc { 2031cb0ef41Sopenharmony_ci 2041cb0ef41Sopenharmony_citemplate <typename T> 2051cb0ef41Sopenharmony_cistruct TraceTrait<v8::TracedReference<T>> { 2061cb0ef41Sopenharmony_ci static cppgc::TraceDescriptor GetTraceDescriptor(const void* self) { 2071cb0ef41Sopenharmony_ci return {nullptr, Trace}; 2081cb0ef41Sopenharmony_ci } 2091cb0ef41Sopenharmony_ci 2101cb0ef41Sopenharmony_ci static void Trace(Visitor* visitor, const void* self) { 2111cb0ef41Sopenharmony_ci static_cast<v8::JSVisitor*>(visitor)->Trace( 2121cb0ef41Sopenharmony_ci *static_cast<const v8::TracedReference<T>*>(self)); 2131cb0ef41Sopenharmony_ci } 2141cb0ef41Sopenharmony_ci}; 2151cb0ef41Sopenharmony_ci 2161cb0ef41Sopenharmony_ci} // namespace cppgc 2171cb0ef41Sopenharmony_ci 2181cb0ef41Sopenharmony_ci#endif // INCLUDE_V8_CPPGC_H_ 219