Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-04-02 08:54:42

0001 // Copyright 2020 the V8 project authors. All rights reserved.
0002 // Use of this source code is governed by a BSD-style license that can be
0003 // found in the LICENSE file.
0004 
0005 #ifndef INCLUDE_CPPGC_HEAP_CONSISTENCY_H_
0006 #define INCLUDE_CPPGC_HEAP_CONSISTENCY_H_
0007 
0008 #include <cstddef>
0009 
0010 #include "cppgc/internal/write-barrier.h"
0011 #include "cppgc/macros.h"
0012 #include "cppgc/member.h"
0013 #include "cppgc/trace-trait.h"
0014 #include "v8config.h"  // NOLINT(build/include_directory)
0015 
0016 namespace cppgc {
0017 
0018 class HeapHandle;
0019 
0020 namespace subtle {
0021 
0022 /**
0023  * **DO NOT USE: Use the appropriate managed types.**
0024  *
0025  * Consistency helpers that aid in maintaining a consistent internal state of
0026  * the garbage collector.
0027  */
0028 class HeapConsistency final {
0029  public:
0030   using WriteBarrierParams = internal::WriteBarrier::Params;
0031   using WriteBarrierType = internal::WriteBarrier::Type;
0032 
0033   /**
0034    * Gets the required write barrier type for a specific write.
0035    *
0036    * \param slot Slot containing the pointer to the object. The slot itself
0037    *   must reside in an object that has been allocated using
0038    *   `MakeGarbageCollected()`.
0039    * \param value The pointer to the object. May be an interior pointer to an
0040    *   interface of the actual object.
0041    * \param params Parameters that may be used for actual write barrier calls.
0042    *   Only filled if return value indicates that a write barrier is needed. The
0043    *   contents of the `params` are an implementation detail.
0044    * \returns whether a write barrier is needed and which barrier to invoke.
0045    */
0046   static V8_INLINE WriteBarrierType GetWriteBarrierType(
0047       const void* slot, const void* value, WriteBarrierParams& params) {
0048     return internal::WriteBarrier::GetWriteBarrierType(slot, value, params);
0049   }
0050 
0051   /**
0052    * Gets the required write barrier type for a specific write. This override is
0053    * only used for all the BasicMember types.
0054    *
0055    * \param slot Slot containing the pointer to the object. The slot itself
0056    *   must reside in an object that has been allocated using
0057    *   `MakeGarbageCollected()`.
0058    * \param value The pointer to the object held via `BasicMember`.
0059    * \param params Parameters that may be used for actual write barrier calls.
0060    *   Only filled if return value indicates that a write barrier is needed. The
0061    *   contents of the `params` are an implementation detail.
0062    * \returns whether a write barrier is needed and which barrier to invoke.
0063    */
0064   template <typename T, typename WeaknessTag, typename WriteBarrierPolicy,
0065             typename CheckingPolicy, typename StorageType>
0066   static V8_INLINE WriteBarrierType GetWriteBarrierType(
0067       const internal::BasicMember<T, WeaknessTag, WriteBarrierPolicy,
0068                                   CheckingPolicy, StorageType>& value,
0069       WriteBarrierParams& params) {
0070     return internal::WriteBarrier::GetWriteBarrierType(
0071         value.GetRawSlot(), value.GetRawStorage(), params);
0072   }
0073 
0074   /**
0075    * Gets the required write barrier type for a specific write.
0076    *
0077    * \param slot Slot to some part of an object. The object must not necessarily
0078        have been allocated using `MakeGarbageCollected()` but can also live
0079        off-heap or on stack.
0080    * \param params Parameters that may be used for actual write barrier calls.
0081    *   Only filled if return value indicates that a write barrier is needed. The
0082    *   contents of the `params` are an implementation detail.
0083    * \param callback Callback returning the corresponding heap handle. The
0084    *   callback is only invoked if the heap cannot otherwise be figured out. The
0085    *   callback must not allocate.
0086    * \returns whether a write barrier is needed and which barrier to invoke.
0087    */
0088   template <typename HeapHandleCallback>
0089   static V8_INLINE WriteBarrierType
0090   GetWriteBarrierType(const void* slot, WriteBarrierParams& params,
0091                       HeapHandleCallback callback) {
0092     return internal::WriteBarrier::GetWriteBarrierType(slot, params, callback);
0093   }
0094 
0095   /**
0096    * Gets the required write barrier type for a specific write.
0097    * This version is meant to be used in conjunction with with a marking write
0098    * barrier barrier which doesn't consider the slot.
0099    *
0100    * \param value The pointer to the object. May be an interior pointer to an
0101    *   interface of the actual object.
0102    * \param params Parameters that may be used for actual write barrier calls.
0103    *   Only filled if return value indicates that a write barrier is needed. The
0104    *   contents of the `params` are an implementation detail.
0105    * \returns whether a write barrier is needed and which barrier to invoke.
0106    */
0107   static V8_INLINE WriteBarrierType
0108   GetWriteBarrierType(const void* value, WriteBarrierParams& params) {
0109     return internal::WriteBarrier::GetWriteBarrierType(value, params);
0110   }
0111 
0112   /**
0113    * Conservative Dijkstra-style write barrier that processes an object if it
0114    * has not yet been processed.
0115    *
0116    * \param params The parameters retrieved from `GetWriteBarrierType()`.
0117    * \param object The pointer to the object. May be an interior pointer to a
0118    *   an interface of the actual object.
0119    */
0120   static V8_INLINE void DijkstraWriteBarrier(const WriteBarrierParams& params,
0121                                              const void* object) {
0122     internal::WriteBarrier::DijkstraMarkingBarrier(params, object);
0123   }
0124 
0125   /**
0126    * Conservative Dijkstra-style write barrier that processes a range of
0127    * elements if they have not yet been processed.
0128    *
0129    * \param params The parameters retrieved from `GetWriteBarrierType()`.
0130    * \param first_element Pointer to the first element that should be processed.
0131    *   The slot itself must reside in an object that has been allocated using
0132    *   `MakeGarbageCollected()`.
0133    * \param element_size Size of the element in bytes.
0134    * \param number_of_elements Number of elements that should be processed,
0135    *   starting with `first_element`.
0136    * \param trace_callback The trace callback that should be invoked for each
0137    *   element if necessary.
0138    */
0139   static V8_INLINE void DijkstraWriteBarrierRange(
0140       const WriteBarrierParams& params, const void* first_element,
0141       size_t element_size, size_t number_of_elements,
0142       TraceCallback trace_callback) {
0143     internal::WriteBarrier::DijkstraMarkingBarrierRange(
0144         params, first_element, element_size, number_of_elements,
0145         trace_callback);
0146   }
0147 
0148   /**
0149    * Steele-style write barrier that re-processes an object if it has already
0150    * been processed.
0151    *
0152    * \param params The parameters retrieved from `GetWriteBarrierType()`.
0153    * \param object The pointer to the object which must point to an object that
0154    *   has been allocated using `MakeGarbageCollected()`. Interior pointers are
0155    *   not supported.
0156    */
0157   static V8_INLINE void SteeleWriteBarrier(const WriteBarrierParams& params,
0158                                            const void* object) {
0159     internal::WriteBarrier::SteeleMarkingBarrier(params, object);
0160   }
0161 
0162   /**
0163    * Generational barrier for maintaining consistency when running with multiple
0164    * generations.
0165    *
0166    * \param params The parameters retrieved from `GetWriteBarrierType()`.
0167    * \param slot Slot containing the pointer to the object. The slot itself
0168    *   must reside in an object that has been allocated using
0169    *   `MakeGarbageCollected()`.
0170    */
0171   static V8_INLINE void GenerationalBarrier(const WriteBarrierParams& params,
0172                                             const void* slot) {
0173     internal::WriteBarrier::GenerationalBarrier<
0174         internal::WriteBarrier::GenerationalBarrierType::kPreciseSlot>(params,
0175                                                                        slot);
0176   }
0177 
0178   /**
0179    * Generational barrier for maintaining consistency when running with multiple
0180    * generations. This version is used when slot contains uncompressed pointer.
0181    *
0182    * \param params The parameters retrieved from `GetWriteBarrierType()`.
0183    * \param slot Uncompressed slot containing the direct pointer to the object.
0184    * The slot itself must reside in an object that has been allocated using
0185    *   `MakeGarbageCollected()`.
0186    */
0187   static V8_INLINE void GenerationalBarrierForUncompressedSlot(
0188       const WriteBarrierParams& params, const void* uncompressed_slot) {
0189     internal::WriteBarrier::GenerationalBarrier<
0190         internal::WriteBarrier::GenerationalBarrierType::
0191             kPreciseUncompressedSlot>(params, uncompressed_slot);
0192   }
0193 
0194   /**
0195    * Generational barrier for source object that may contain outgoing pointers
0196    * to objects in young generation.
0197    *
0198    * \param params The parameters retrieved from `GetWriteBarrierType()`.
0199    * \param inner_pointer Pointer to the source object.
0200    */
0201   static V8_INLINE void GenerationalBarrierForSourceObject(
0202       const WriteBarrierParams& params, const void* inner_pointer) {
0203     internal::WriteBarrier::GenerationalBarrier<
0204         internal::WriteBarrier::GenerationalBarrierType::kImpreciseSlot>(
0205         params, inner_pointer);
0206   }
0207 
0208  private:
0209   HeapConsistency() = delete;
0210 };
0211 
0212 /**
0213  * Disallows garbage collection finalizations. Any garbage collection triggers
0214  * result in a crash when in this scope.
0215  *
0216  * Note that the garbage collector already covers paths that can lead to garbage
0217  * collections, so user code does not require checking
0218  * `IsGarbageCollectionAllowed()` before allocations.
0219  */
0220 class V8_EXPORT V8_NODISCARD DisallowGarbageCollectionScope final {
0221   CPPGC_STACK_ALLOCATED();
0222 
0223  public:
0224   /**
0225    * \returns whether garbage collections are currently allowed.
0226    */
0227   static bool IsGarbageCollectionAllowed(HeapHandle& heap_handle);
0228 
0229   /**
0230    * Enters a disallow garbage collection scope. Must be paired with `Leave()`.
0231    * Prefer a scope instance of `DisallowGarbageCollectionScope`.
0232    *
0233    * \param heap_handle The corresponding heap.
0234    */
0235   static void Enter(HeapHandle& heap_handle);
0236 
0237   /**
0238    * Leaves a disallow garbage collection scope. Must be paired with `Enter()`.
0239    * Prefer a scope instance of `DisallowGarbageCollectionScope`.
0240    *
0241    * \param heap_handle The corresponding heap.
0242    */
0243   static void Leave(HeapHandle& heap_handle);
0244 
0245   /**
0246    * Constructs a scoped object that automatically enters and leaves a disallow
0247    * garbage collection scope based on its lifetime.
0248    *
0249    * \param heap_handle The corresponding heap.
0250    */
0251   explicit DisallowGarbageCollectionScope(HeapHandle& heap_handle);
0252   ~DisallowGarbageCollectionScope();
0253 
0254   DisallowGarbageCollectionScope(const DisallowGarbageCollectionScope&) =
0255       delete;
0256   DisallowGarbageCollectionScope& operator=(
0257       const DisallowGarbageCollectionScope&) = delete;
0258 
0259  private:
0260   HeapHandle& heap_handle_;
0261 };
0262 
0263 /**
0264  * Avoids invoking garbage collection finalizations. Already running garbage
0265  * collection phase are unaffected by this scope.
0266  *
0267  * Should only be used temporarily as the scope has an impact on memory usage
0268  * and follow up garbage collections.
0269  */
0270 class V8_EXPORT V8_NODISCARD NoGarbageCollectionScope final {
0271   CPPGC_STACK_ALLOCATED();
0272 
0273  public:
0274   /**
0275    * Enters a no garbage collection scope. Must be paired with `Leave()`. Prefer
0276    * a scope instance of `NoGarbageCollectionScope`.
0277    *
0278    * \param heap_handle The corresponding heap.
0279    */
0280   static void Enter(HeapHandle& heap_handle);
0281 
0282   /**
0283    * Leaves a no garbage collection scope. Must be paired with `Enter()`. Prefer
0284    * a scope instance of `NoGarbageCollectionScope`.
0285    *
0286    * \param heap_handle The corresponding heap.
0287    */
0288   static void Leave(HeapHandle& heap_handle);
0289 
0290   /**
0291    * Constructs a scoped object that automatically enters and leaves a no
0292    * garbage collection scope based on its lifetime.
0293    *
0294    * \param heap_handle The corresponding heap.
0295    */
0296   explicit NoGarbageCollectionScope(HeapHandle& heap_handle);
0297   ~NoGarbageCollectionScope();
0298 
0299   NoGarbageCollectionScope(const NoGarbageCollectionScope&) = delete;
0300   NoGarbageCollectionScope& operator=(const NoGarbageCollectionScope&) = delete;
0301 
0302  private:
0303   HeapHandle& heap_handle_;
0304 };
0305 
0306 }  // namespace subtle
0307 }  // namespace cppgc
0308 
0309 #endif  // INCLUDE_CPPGC_HEAP_CONSISTENCY_H_