11cb0ef41Sopenharmony_ci// Copyright 2021 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_CPPGC_EXPLICIT_MANAGEMENT_H_ 61cb0ef41Sopenharmony_ci#define INCLUDE_CPPGC_EXPLICIT_MANAGEMENT_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <cstddef> 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#include "cppgc/allocation.h" 111cb0ef41Sopenharmony_ci#include "cppgc/internal/logging.h" 121cb0ef41Sopenharmony_ci#include "cppgc/type-traits.h" 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_cinamespace cppgc { 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ciclass HeapHandle; 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_cinamespace subtle { 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_citemplate <typename T> 211cb0ef41Sopenharmony_civoid FreeUnreferencedObject(HeapHandle& heap_handle, T& object); 221cb0ef41Sopenharmony_citemplate <typename T> 231cb0ef41Sopenharmony_cibool Resize(T& object, AdditionalBytes additional_bytes); 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ci} // namespace subtle 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_cinamespace internal { 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ciclass ExplicitManagementImpl final { 301cb0ef41Sopenharmony_ci private: 311cb0ef41Sopenharmony_ci V8_EXPORT static void FreeUnreferencedObject(HeapHandle&, void*); 321cb0ef41Sopenharmony_ci V8_EXPORT static bool Resize(void*, size_t); 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci template <typename T> 351cb0ef41Sopenharmony_ci friend void subtle::FreeUnreferencedObject(HeapHandle&, T&); 361cb0ef41Sopenharmony_ci template <typename T> 371cb0ef41Sopenharmony_ci friend bool subtle::Resize(T&, AdditionalBytes); 381cb0ef41Sopenharmony_ci}; 391cb0ef41Sopenharmony_ci} // namespace internal 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_cinamespace subtle { 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci/** 441cb0ef41Sopenharmony_ci * Informs the garbage collector that `object` can be immediately reclaimed. The 451cb0ef41Sopenharmony_ci * destructor may not be invoked immediately but only on next garbage 461cb0ef41Sopenharmony_ci * collection. 471cb0ef41Sopenharmony_ci * 481cb0ef41Sopenharmony_ci * It is up to the embedder to guarantee that no other object holds a reference 491cb0ef41Sopenharmony_ci * to `object` after calling `FreeUnreferencedObject()`. In case such a 501cb0ef41Sopenharmony_ci * reference exists, it's use results in a use-after-free. 511cb0ef41Sopenharmony_ci * 521cb0ef41Sopenharmony_ci * To aid in using the API, `FreeUnreferencedObject()` may be called from 531cb0ef41Sopenharmony_ci * destructors on objects that would be reclaimed in the same garbage collection 541cb0ef41Sopenharmony_ci * cycle. 551cb0ef41Sopenharmony_ci * 561cb0ef41Sopenharmony_ci * \param heap_handle The corresponding heap. 571cb0ef41Sopenharmony_ci * \param object Reference to an object that is of type `GarbageCollected` and 581cb0ef41Sopenharmony_ci * should be immediately reclaimed. 591cb0ef41Sopenharmony_ci */ 601cb0ef41Sopenharmony_citemplate <typename T> 611cb0ef41Sopenharmony_civoid FreeUnreferencedObject(HeapHandle& heap_handle, T& object) { 621cb0ef41Sopenharmony_ci static_assert(IsGarbageCollectedTypeV<T>, 631cb0ef41Sopenharmony_ci "Object must be of type GarbageCollected."); 641cb0ef41Sopenharmony_ci internal::ExplicitManagementImpl::FreeUnreferencedObject(heap_handle, 651cb0ef41Sopenharmony_ci &object); 661cb0ef41Sopenharmony_ci} 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci/** 691cb0ef41Sopenharmony_ci * Tries to resize `object` of type `T` with additional bytes on top of 701cb0ef41Sopenharmony_ci * sizeof(T). Resizing is only useful with trailing inlined storage, see e.g. 711cb0ef41Sopenharmony_ci * `MakeGarbageCollected(AllocationHandle&, AdditionalBytes)`. 721cb0ef41Sopenharmony_ci * 731cb0ef41Sopenharmony_ci * `Resize()` performs growing or shrinking as needed and may skip the operation 741cb0ef41Sopenharmony_ci * for internal reasons, see return value. 751cb0ef41Sopenharmony_ci * 761cb0ef41Sopenharmony_ci * It is up to the embedder to guarantee that in case of shrinking a larger 771cb0ef41Sopenharmony_ci * object down, the reclaimed area is not used anymore. Any subsequent use 781cb0ef41Sopenharmony_ci * results in a use-after-free. 791cb0ef41Sopenharmony_ci * 801cb0ef41Sopenharmony_ci * The `object` must be live when calling `Resize()`. 811cb0ef41Sopenharmony_ci * 821cb0ef41Sopenharmony_ci * \param object Reference to an object that is of type `GarbageCollected` and 831cb0ef41Sopenharmony_ci * should be resized. 841cb0ef41Sopenharmony_ci * \param additional_bytes Bytes in addition to sizeof(T) that the object should 851cb0ef41Sopenharmony_ci * provide. 861cb0ef41Sopenharmony_ci * \returns true when the operation was successful and the result can be relied 871cb0ef41Sopenharmony_ci * on, and false otherwise. 881cb0ef41Sopenharmony_ci */ 891cb0ef41Sopenharmony_citemplate <typename T> 901cb0ef41Sopenharmony_cibool Resize(T& object, AdditionalBytes additional_bytes) { 911cb0ef41Sopenharmony_ci static_assert(IsGarbageCollectedTypeV<T>, 921cb0ef41Sopenharmony_ci "Object must be of type GarbageCollected."); 931cb0ef41Sopenharmony_ci return internal::ExplicitManagementImpl::Resize( 941cb0ef41Sopenharmony_ci &object, sizeof(T) + additional_bytes.value); 951cb0ef41Sopenharmony_ci} 961cb0ef41Sopenharmony_ci 971cb0ef41Sopenharmony_ci} // namespace subtle 981cb0ef41Sopenharmony_ci} // namespace cppgc 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci#endif // INCLUDE_CPPGC_EXPLICIT_MANAGEMENT_H_ 101