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_CPPGC_PREFINALIZER_H_ 61cb0ef41Sopenharmony_ci#define INCLUDE_CPPGC_PREFINALIZER_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "cppgc/internal/compiler-specific.h" 91cb0ef41Sopenharmony_ci#include "cppgc/liveness-broker.h" 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_cinamespace cppgc { 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_cinamespace internal { 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ciclass V8_EXPORT PrefinalizerRegistration final { 161cb0ef41Sopenharmony_ci public: 171cb0ef41Sopenharmony_ci using Callback = bool (*)(const cppgc::LivenessBroker&, void*); 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ci PrefinalizerRegistration(void*, Callback); 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci void* operator new(size_t, void* location) = delete; 221cb0ef41Sopenharmony_ci void* operator new(size_t) = delete; 231cb0ef41Sopenharmony_ci}; 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ci} // namespace internal 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci/** 281cb0ef41Sopenharmony_ci * Macro must be used in the private section of `Class` and registers a 291cb0ef41Sopenharmony_ci * prefinalization callback `void Class::PreFinalizer()`. The callback is 301cb0ef41Sopenharmony_ci * invoked on garbage collection after the collector has found an object to be 311cb0ef41Sopenharmony_ci * dead. 321cb0ef41Sopenharmony_ci * 331cb0ef41Sopenharmony_ci * Callback properties: 341cb0ef41Sopenharmony_ci * - The callback is invoked before a possible destructor for the corresponding 351cb0ef41Sopenharmony_ci * object. 361cb0ef41Sopenharmony_ci * - The callback may access the whole object graph, irrespective of whether 371cb0ef41Sopenharmony_ci * objects are considered dead or alive. 381cb0ef41Sopenharmony_ci * - The callback is invoked on the same thread as the object was created on. 391cb0ef41Sopenharmony_ci * 401cb0ef41Sopenharmony_ci * Example: 411cb0ef41Sopenharmony_ci * \code 421cb0ef41Sopenharmony_ci * class WithPrefinalizer : public GarbageCollected<WithPrefinalizer> { 431cb0ef41Sopenharmony_ci * CPPGC_USING_PRE_FINALIZER(WithPrefinalizer, Dispose); 441cb0ef41Sopenharmony_ci * 451cb0ef41Sopenharmony_ci * public: 461cb0ef41Sopenharmony_ci * void Trace(Visitor*) const {} 471cb0ef41Sopenharmony_ci * void Dispose() { prefinalizer_called = true; } 481cb0ef41Sopenharmony_ci * ~WithPrefinalizer() { 491cb0ef41Sopenharmony_ci * // prefinalizer_called == true 501cb0ef41Sopenharmony_ci * } 511cb0ef41Sopenharmony_ci * private: 521cb0ef41Sopenharmony_ci * bool prefinalizer_called = false; 531cb0ef41Sopenharmony_ci * }; 541cb0ef41Sopenharmony_ci * \endcode 551cb0ef41Sopenharmony_ci */ 561cb0ef41Sopenharmony_ci#define CPPGC_USING_PRE_FINALIZER(Class, PreFinalizer) \ 571cb0ef41Sopenharmony_ci public: \ 581cb0ef41Sopenharmony_ci static bool InvokePreFinalizer(const cppgc::LivenessBroker& liveness_broker, \ 591cb0ef41Sopenharmony_ci void* object) { \ 601cb0ef41Sopenharmony_ci static_assert(cppgc::IsGarbageCollectedOrMixinTypeV<Class>, \ 611cb0ef41Sopenharmony_ci "Only garbage collected objects can have prefinalizers"); \ 621cb0ef41Sopenharmony_ci Class* self = static_cast<Class*>(object); \ 631cb0ef41Sopenharmony_ci if (liveness_broker.IsHeapObjectAlive(self)) return false; \ 641cb0ef41Sopenharmony_ci self->PreFinalizer(); \ 651cb0ef41Sopenharmony_ci return true; \ 661cb0ef41Sopenharmony_ci } \ 671cb0ef41Sopenharmony_ci \ 681cb0ef41Sopenharmony_ci private: \ 691cb0ef41Sopenharmony_ci CPPGC_NO_UNIQUE_ADDRESS cppgc::internal::PrefinalizerRegistration \ 701cb0ef41Sopenharmony_ci prefinalizer_dummy_{this, Class::InvokePreFinalizer}; \ 711cb0ef41Sopenharmony_ci static_assert(true, "Force semicolon.") 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci} // namespace cppgc 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci#endif // INCLUDE_CPPGC_PREFINALIZER_H_ 76