xref: /third_party/node/deps/v8/src/handles/handles.h (revision 1cb0ef41)
11cb0ef41Sopenharmony_ci// Copyright 2011 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 V8_HANDLES_HANDLES_H_
61cb0ef41Sopenharmony_ci#define V8_HANDLES_HANDLES_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include <type_traits>
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci#include "src/base/functional.h"
111cb0ef41Sopenharmony_ci#include "src/base/macros.h"
121cb0ef41Sopenharmony_ci#include "src/common/checks.h"
131cb0ef41Sopenharmony_ci#include "src/common/globals.h"
141cb0ef41Sopenharmony_ci#include "src/zone/zone.h"
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_cinamespace v8 {
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ciclass HandleScope;
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_cinamespace internal {
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci// Forward declarations.
231cb0ef41Sopenharmony_ciclass HandleScopeImplementer;
241cb0ef41Sopenharmony_ciclass Isolate;
251cb0ef41Sopenharmony_ciclass LocalHeap;
261cb0ef41Sopenharmony_ciclass LocalIsolate;
271cb0ef41Sopenharmony_citemplate <typename T>
281cb0ef41Sopenharmony_ciclass MaybeHandle;
291cb0ef41Sopenharmony_ciclass Object;
301cb0ef41Sopenharmony_ciclass OrderedHashMap;
311cb0ef41Sopenharmony_ciclass OrderedHashSet;
321cb0ef41Sopenharmony_ciclass OrderedNameDictionary;
331cb0ef41Sopenharmony_ciclass RootVisitor;
341cb0ef41Sopenharmony_ciclass SmallOrderedHashMap;
351cb0ef41Sopenharmony_ciclass SmallOrderedHashSet;
361cb0ef41Sopenharmony_ciclass SmallOrderedNameDictionary;
371cb0ef41Sopenharmony_ciclass SwissNameDictionary;
381cb0ef41Sopenharmony_ciclass WasmExportedFunctionData;
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci// ----------------------------------------------------------------------------
411cb0ef41Sopenharmony_ci// Base class for Handle instantiations.  Don't use directly.
421cb0ef41Sopenharmony_ciclass HandleBase {
431cb0ef41Sopenharmony_ci public:
441cb0ef41Sopenharmony_ci  V8_INLINE explicit HandleBase(Address* location) : location_(location) {}
451cb0ef41Sopenharmony_ci  V8_INLINE explicit HandleBase(Address object, Isolate* isolate);
461cb0ef41Sopenharmony_ci  V8_INLINE explicit HandleBase(Address object, LocalIsolate* isolate);
471cb0ef41Sopenharmony_ci  V8_INLINE explicit HandleBase(Address object, LocalHeap* local_heap);
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci  // Check if this handle refers to the exact same object as the other handle.
501cb0ef41Sopenharmony_ci  V8_INLINE bool is_identical_to(const HandleBase that) const;
511cb0ef41Sopenharmony_ci  V8_INLINE bool is_null() const { return location_ == nullptr; }
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci  // Returns the raw address where this handle is stored. This should only be
541cb0ef41Sopenharmony_ci  // used for hashing handles; do not ever try to dereference it.
551cb0ef41Sopenharmony_ci  V8_INLINE Address address() const { return bit_cast<Address>(location_); }
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci  // Returns the address to where the raw pointer is stored.
581cb0ef41Sopenharmony_ci  // TODO(leszeks): This should probably be a const Address*, to encourage using
591cb0ef41Sopenharmony_ci  // PatchValue for modifying the handle's value.
601cb0ef41Sopenharmony_ci  V8_INLINE Address* location() const {
611cb0ef41Sopenharmony_ci    SLOW_DCHECK(location_ == nullptr || IsDereferenceAllowed());
621cb0ef41Sopenharmony_ci    return location_;
631cb0ef41Sopenharmony_ci  }
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci protected:
661cb0ef41Sopenharmony_ci#ifdef DEBUG
671cb0ef41Sopenharmony_ci  bool V8_EXPORT_PRIVATE IsDereferenceAllowed() const;
681cb0ef41Sopenharmony_ci#else
691cb0ef41Sopenharmony_ci  V8_INLINE
701cb0ef41Sopenharmony_ci  bool V8_EXPORT_PRIVATE IsDereferenceAllowed() const { return true; }
711cb0ef41Sopenharmony_ci#endif  // DEBUG
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci  // This uses type Address* as opposed to a pointer type to a typed
741cb0ef41Sopenharmony_ci  // wrapper class, because it doesn't point to instances of such a
751cb0ef41Sopenharmony_ci  // wrapper class. Design overview: https://goo.gl/Ph4CGz
761cb0ef41Sopenharmony_ci  Address* location_;
771cb0ef41Sopenharmony_ci};
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci// ----------------------------------------------------------------------------
801cb0ef41Sopenharmony_ci// A Handle provides a reference to an object that survives relocation by
811cb0ef41Sopenharmony_ci// the garbage collector.
821cb0ef41Sopenharmony_ci//
831cb0ef41Sopenharmony_ci// Handles are only valid within a HandleScope. When a handle is created
841cb0ef41Sopenharmony_ci// for an object a cell is allocated in the current HandleScope.
851cb0ef41Sopenharmony_ci//
861cb0ef41Sopenharmony_ci// Also note that Handles do not provide default equality comparison or hashing
871cb0ef41Sopenharmony_ci// operators on purpose. Such operators would be misleading, because intended
881cb0ef41Sopenharmony_ci// semantics is ambiguous between Handle location and object identity. Instead
891cb0ef41Sopenharmony_ci// use either {is_identical_to} or {location} explicitly.
901cb0ef41Sopenharmony_citemplate <typename T>
911cb0ef41Sopenharmony_ciclass Handle final : public HandleBase {
921cb0ef41Sopenharmony_ci public:
931cb0ef41Sopenharmony_ci  // {ObjectRef} is returned by {Handle::operator->}. It should never be stored
941cb0ef41Sopenharmony_ci  // anywhere or used in any other code; no one should ever have to spell out
951cb0ef41Sopenharmony_ci  // {ObjectRef} in code. Its only purpose is to be dereferenced immediately by
961cb0ef41Sopenharmony_ci  // "operator-> chaining". Returning the address of the field is valid because
971cb0ef41Sopenharmony_ci  // this objects lifetime only ends at the end of the full statement.
981cb0ef41Sopenharmony_ci  class ObjectRef {
991cb0ef41Sopenharmony_ci   public:
1001cb0ef41Sopenharmony_ci    T* operator->() { return &object_; }
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci   private:
1031cb0ef41Sopenharmony_ci    friend class Handle<T>;
1041cb0ef41Sopenharmony_ci    explicit ObjectRef(T object) : object_(object) {}
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci    T object_;
1071cb0ef41Sopenharmony_ci  };
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ci  V8_INLINE explicit Handle() : HandleBase(nullptr) {
1101cb0ef41Sopenharmony_ci    // Skip static type check in order to allow Handle<XXX>::null() as default
1111cb0ef41Sopenharmony_ci    // parameter values in non-inl header files without requiring full
1121cb0ef41Sopenharmony_ci    // definition of type XXX.
1131cb0ef41Sopenharmony_ci  }
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci  V8_INLINE explicit Handle(Address* location) : HandleBase(location) {
1161cb0ef41Sopenharmony_ci    // This static type check also fails for forward class declarations.
1171cb0ef41Sopenharmony_ci    static_assert(std::is_convertible<T*, Object*>::value,
1181cb0ef41Sopenharmony_ci                  "static type violation");
1191cb0ef41Sopenharmony_ci    // TODO(jkummerow): Runtime type check here as a SLOW_DCHECK?
1201cb0ef41Sopenharmony_ci  }
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci  V8_INLINE Handle(T object, Isolate* isolate);
1231cb0ef41Sopenharmony_ci  V8_INLINE Handle(T object, LocalIsolate* isolate);
1241cb0ef41Sopenharmony_ci  V8_INLINE Handle(T object, LocalHeap* local_heap);
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ci  // Allocate a new handle for the object, do not canonicalize.
1271cb0ef41Sopenharmony_ci  V8_INLINE static Handle<T> New(T object, Isolate* isolate);
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci  // Constructor for handling automatic up casting.
1301cb0ef41Sopenharmony_ci  // Ex. Handle<JSFunction> can be passed when Handle<Object> is expected.
1311cb0ef41Sopenharmony_ci  template <typename S, typename = typename std::enable_if<
1321cb0ef41Sopenharmony_ci                            std::is_convertible<S*, T*>::value>::type>
1331cb0ef41Sopenharmony_ci  V8_INLINE Handle(Handle<S> handle) : HandleBase(handle) {}
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci  V8_INLINE ObjectRef operator->() const { return ObjectRef{**this}; }
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci  V8_INLINE T operator*() const {
1381cb0ef41Sopenharmony_ci    // unchecked_cast because we rather trust Handle<T> to contain a T than
1391cb0ef41Sopenharmony_ci    // include all the respective -inl.h headers for SLOW_DCHECKs.
1401cb0ef41Sopenharmony_ci    SLOW_DCHECK(IsDereferenceAllowed());
1411cb0ef41Sopenharmony_ci    return T::unchecked_cast(Object(*location()));
1421cb0ef41Sopenharmony_ci  }
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ci  template <typename S>
1451cb0ef41Sopenharmony_ci  inline static const Handle<T> cast(Handle<S> that);
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_ci  // Consider declaring values that contain empty handles as
1481cb0ef41Sopenharmony_ci  // MaybeHandle to force validation before being used as handles.
1491cb0ef41Sopenharmony_ci  static const Handle<T> null() { return Handle<T>(); }
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ci  // Location equality.
1521cb0ef41Sopenharmony_ci  bool equals(Handle<T> other) const { return address() == other.address(); }
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci  // Patches this Handle's value, in-place, with a new value. All handles with
1551cb0ef41Sopenharmony_ci  // the same location will see this update.
1561cb0ef41Sopenharmony_ci  void PatchValue(T new_value) {
1571cb0ef41Sopenharmony_ci    SLOW_DCHECK(location_ != nullptr && IsDereferenceAllowed());
1581cb0ef41Sopenharmony_ci    *location_ = new_value.ptr();
1591cb0ef41Sopenharmony_ci  }
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ci  // Provide function object for location equality comparison.
1621cb0ef41Sopenharmony_ci  struct equal_to {
1631cb0ef41Sopenharmony_ci    V8_INLINE bool operator()(Handle<T> lhs, Handle<T> rhs) const {
1641cb0ef41Sopenharmony_ci      return lhs.equals(rhs);
1651cb0ef41Sopenharmony_ci    }
1661cb0ef41Sopenharmony_ci  };
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ci  // Provide function object for location hashing.
1691cb0ef41Sopenharmony_ci  struct hash {
1701cb0ef41Sopenharmony_ci    V8_INLINE size_t operator()(Handle<T> const& handle) const {
1711cb0ef41Sopenharmony_ci      return base::hash<Address>()(handle.address());
1721cb0ef41Sopenharmony_ci    }
1731cb0ef41Sopenharmony_ci  };
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ci private:
1761cb0ef41Sopenharmony_ci  // Handles of different classes are allowed to access each other's location_.
1771cb0ef41Sopenharmony_ci  template <typename>
1781cb0ef41Sopenharmony_ci  friend class Handle;
1791cb0ef41Sopenharmony_ci  // MaybeHandle is allowed to access location_.
1801cb0ef41Sopenharmony_ci  template <typename>
1811cb0ef41Sopenharmony_ci  friend class MaybeHandle;
1821cb0ef41Sopenharmony_ci};
1831cb0ef41Sopenharmony_ci
1841cb0ef41Sopenharmony_citemplate <typename T>
1851cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& os, Handle<T> handle);
1861cb0ef41Sopenharmony_ci
1871cb0ef41Sopenharmony_ci// ----------------------------------------------------------------------------
1881cb0ef41Sopenharmony_ci// A stack-allocated class that governs a number of local handles.
1891cb0ef41Sopenharmony_ci// After a handle scope has been created, all local handles will be
1901cb0ef41Sopenharmony_ci// allocated within that handle scope until either the handle scope is
1911cb0ef41Sopenharmony_ci// deleted or another handle scope is created.  If there is already a
1921cb0ef41Sopenharmony_ci// handle scope and a new one is created, all allocations will take
1931cb0ef41Sopenharmony_ci// place in the new handle scope until it is deleted.  After that,
1941cb0ef41Sopenharmony_ci// new handles will again be allocated in the original handle scope.
1951cb0ef41Sopenharmony_ci//
1961cb0ef41Sopenharmony_ci// After the handle scope of a local handle has been deleted the
1971cb0ef41Sopenharmony_ci// garbage collector will no longer track the object stored in the
1981cb0ef41Sopenharmony_ci// handle and may deallocate it.  The behavior of accessing a handle
1991cb0ef41Sopenharmony_ci// for which the handle scope has been deleted is undefined.
2001cb0ef41Sopenharmony_ciclass V8_NODISCARD HandleScope {
2011cb0ef41Sopenharmony_ci public:
2021cb0ef41Sopenharmony_ci  explicit V8_INLINE HandleScope(Isolate* isolate);
2031cb0ef41Sopenharmony_ci  inline HandleScope(HandleScope&& other) V8_NOEXCEPT;
2041cb0ef41Sopenharmony_ci  HandleScope(const HandleScope&) = delete;
2051cb0ef41Sopenharmony_ci  HandleScope& operator=(const HandleScope&) = delete;
2061cb0ef41Sopenharmony_ci
2071cb0ef41Sopenharmony_ci  // Allow placement new.
2081cb0ef41Sopenharmony_ci  void* operator new(size_t size, void* storage) {
2091cb0ef41Sopenharmony_ci    return ::operator new(size, storage);
2101cb0ef41Sopenharmony_ci  }
2111cb0ef41Sopenharmony_ci
2121cb0ef41Sopenharmony_ci  // Prevent heap allocation or illegal handle scopes.
2131cb0ef41Sopenharmony_ci  void* operator new(size_t size) = delete;
2141cb0ef41Sopenharmony_ci  void operator delete(void* size_t) = delete;
2151cb0ef41Sopenharmony_ci
2161cb0ef41Sopenharmony_ci  V8_INLINE ~HandleScope();
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_ci  inline HandleScope& operator=(HandleScope&& other) V8_NOEXCEPT;
2191cb0ef41Sopenharmony_ci
2201cb0ef41Sopenharmony_ci  // Counts the number of allocated handles.
2211cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE static int NumberOfHandles(Isolate* isolate);
2221cb0ef41Sopenharmony_ci
2231cb0ef41Sopenharmony_ci  // Create a new handle or lookup a canonical handle.
2241cb0ef41Sopenharmony_ci  V8_INLINE static Address* GetHandle(Isolate* isolate, Address value);
2251cb0ef41Sopenharmony_ci
2261cb0ef41Sopenharmony_ci  // Creates a new handle with the given value.
2271cb0ef41Sopenharmony_ci  V8_INLINE static Address* CreateHandle(Isolate* isolate, Address value);
2281cb0ef41Sopenharmony_ci
2291cb0ef41Sopenharmony_ci  // Deallocates any extensions used by the current scope.
2301cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE static void DeleteExtensions(Isolate* isolate);
2311cb0ef41Sopenharmony_ci
2321cb0ef41Sopenharmony_ci  static Address current_next_address(Isolate* isolate);
2331cb0ef41Sopenharmony_ci  static Address current_limit_address(Isolate* isolate);
2341cb0ef41Sopenharmony_ci  static Address current_level_address(Isolate* isolate);
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ci  // Closes the HandleScope (invalidating all handles
2371cb0ef41Sopenharmony_ci  // created in the scope of the HandleScope) and returns
2381cb0ef41Sopenharmony_ci  // a Handle backed by the parent scope holding the
2391cb0ef41Sopenharmony_ci  // value of the argument handle.
2401cb0ef41Sopenharmony_ci  template <typename T>
2411cb0ef41Sopenharmony_ci  Handle<T> CloseAndEscape(Handle<T> handle_value);
2421cb0ef41Sopenharmony_ci
2431cb0ef41Sopenharmony_ci  Isolate* isolate() { return isolate_; }
2441cb0ef41Sopenharmony_ci
2451cb0ef41Sopenharmony_ci  // Limit for number of handles with --check-handle-count. This is
2461cb0ef41Sopenharmony_ci  // large enough to compile natives and pass unit tests with some
2471cb0ef41Sopenharmony_ci  // slack for future changes to natives.
2481cb0ef41Sopenharmony_ci  static const int kCheckHandleThreshold = 30 * 1024;
2491cb0ef41Sopenharmony_ci
2501cb0ef41Sopenharmony_ci private:
2511cb0ef41Sopenharmony_ci  Isolate* isolate_;
2521cb0ef41Sopenharmony_ci  Address* prev_next_;
2531cb0ef41Sopenharmony_ci  Address* prev_limit_;
2541cb0ef41Sopenharmony_ci
2551cb0ef41Sopenharmony_ci  // Close the handle scope resetting limits to a previous state.
2561cb0ef41Sopenharmony_ci  static V8_INLINE void CloseScope(Isolate* isolate, Address* prev_next,
2571cb0ef41Sopenharmony_ci                                   Address* prev_limit);
2581cb0ef41Sopenharmony_ci
2591cb0ef41Sopenharmony_ci  // Extend the handle scope making room for more handles.
2601cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE static Address* Extend(Isolate* isolate);
2611cb0ef41Sopenharmony_ci
2621cb0ef41Sopenharmony_ci#ifdef ENABLE_HANDLE_ZAPPING
2631cb0ef41Sopenharmony_ci  // Zaps the handles in the half-open interval [start, end).
2641cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE static void ZapRange(Address* start, Address* end);
2651cb0ef41Sopenharmony_ci#endif
2661cb0ef41Sopenharmony_ci
2671cb0ef41Sopenharmony_ci  friend class v8::HandleScope;
2681cb0ef41Sopenharmony_ci  friend class HandleScopeImplementer;
2691cb0ef41Sopenharmony_ci  friend class Isolate;
2701cb0ef41Sopenharmony_ci  friend class LocalHandles;
2711cb0ef41Sopenharmony_ci  friend class LocalHandleScope;
2721cb0ef41Sopenharmony_ci  friend class PersistentHandles;
2731cb0ef41Sopenharmony_ci};
2741cb0ef41Sopenharmony_ci
2751cb0ef41Sopenharmony_ci// Forward declarations for CanonicalHandleScope.
2761cb0ef41Sopenharmony_citemplate <typename V, class AllocationPolicy>
2771cb0ef41Sopenharmony_ciclass IdentityMap;
2781cb0ef41Sopenharmony_ciclass RootIndexMap;
2791cb0ef41Sopenharmony_ciclass OptimizedCompilationInfo;
2801cb0ef41Sopenharmony_ci
2811cb0ef41Sopenharmony_cinamespace maglev {
2821cb0ef41Sopenharmony_ciclass ExportedMaglevCompilationInfo;
2831cb0ef41Sopenharmony_ci}  // namespace maglev
2841cb0ef41Sopenharmony_ci
2851cb0ef41Sopenharmony_ciusing CanonicalHandlesMap = IdentityMap<Address*, ZoneAllocationPolicy>;
2861cb0ef41Sopenharmony_ci
2871cb0ef41Sopenharmony_ci// A CanonicalHandleScope does not open a new HandleScope. It changes the
2881cb0ef41Sopenharmony_ci// existing HandleScope so that Handles created within are canonicalized.
2891cb0ef41Sopenharmony_ci// This does not apply to nested inner HandleScopes unless a nested
2901cb0ef41Sopenharmony_ci// CanonicalHandleScope is introduced. Handles are only canonicalized within
2911cb0ef41Sopenharmony_ci// the same CanonicalHandleScope, but not across nested ones.
2921cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE V8_NODISCARD CanonicalHandleScope {
2931cb0ef41Sopenharmony_ci public:
2941cb0ef41Sopenharmony_ci  // If no Zone is passed to this constructor, we create (and own) a new zone.
2951cb0ef41Sopenharmony_ci  // To properly dispose of said zone, we need to first free the identity_map_
2961cb0ef41Sopenharmony_ci  // which is done manually even though identity_map_ is a unique_ptr.
2971cb0ef41Sopenharmony_ci  explicit CanonicalHandleScope(Isolate* isolate, Zone* zone = nullptr);
2981cb0ef41Sopenharmony_ci  ~CanonicalHandleScope();
2991cb0ef41Sopenharmony_ci
3001cb0ef41Sopenharmony_ci protected:
3011cb0ef41Sopenharmony_ci  std::unique_ptr<CanonicalHandlesMap> DetachCanonicalHandles();
3021cb0ef41Sopenharmony_ci
3031cb0ef41Sopenharmony_ci  Zone* zone_;  // *Not* const, may be mutated by subclasses.
3041cb0ef41Sopenharmony_ci
3051cb0ef41Sopenharmony_ci private:
3061cb0ef41Sopenharmony_ci  Address* Lookup(Address object);
3071cb0ef41Sopenharmony_ci
3081cb0ef41Sopenharmony_ci  Isolate* const isolate_;
3091cb0ef41Sopenharmony_ci  RootIndexMap* root_index_map_;
3101cb0ef41Sopenharmony_ci  std::unique_ptr<CanonicalHandlesMap> identity_map_;
3111cb0ef41Sopenharmony_ci  // Ordinary nested handle scopes within the current one are not canonical.
3121cb0ef41Sopenharmony_ci  int canonical_level_;
3131cb0ef41Sopenharmony_ci  // We may have nested canonical scopes. Handles are canonical within each one.
3141cb0ef41Sopenharmony_ci  CanonicalHandleScope* prev_canonical_scope_;
3151cb0ef41Sopenharmony_ci
3161cb0ef41Sopenharmony_ci  friend class HandleScope;
3171cb0ef41Sopenharmony_ci};
3181cb0ef41Sopenharmony_ci
3191cb0ef41Sopenharmony_citemplate <class CompilationInfoT>
3201cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE V8_NODISCARD CanonicalHandleScopeForOptimization final
3211cb0ef41Sopenharmony_ci    : public CanonicalHandleScope {
3221cb0ef41Sopenharmony_ci public:
3231cb0ef41Sopenharmony_ci  // We created the
3241cb0ef41Sopenharmony_ci  // CanonicalHandlesMap on the compilation info's zone(). In the
3251cb0ef41Sopenharmony_ci  // CanonicalHandleScope destructor we hand off the canonical handle map to the
3261cb0ef41Sopenharmony_ci  // compilation info. The compilation info is responsible for the disposal.
3271cb0ef41Sopenharmony_ci  explicit CanonicalHandleScopeForOptimization(Isolate* isolate,
3281cb0ef41Sopenharmony_ci                                               CompilationInfoT* info);
3291cb0ef41Sopenharmony_ci  ~CanonicalHandleScopeForOptimization();
3301cb0ef41Sopenharmony_ci
3311cb0ef41Sopenharmony_ci private:
3321cb0ef41Sopenharmony_ci  CompilationInfoT* const info_;
3331cb0ef41Sopenharmony_ci};
3341cb0ef41Sopenharmony_ci
3351cb0ef41Sopenharmony_ciusing CanonicalHandleScopeForTurbofan =
3361cb0ef41Sopenharmony_ci    CanonicalHandleScopeForOptimization<OptimizedCompilationInfo>;
3371cb0ef41Sopenharmony_ciusing CanonicalHandleScopeForMaglev =
3381cb0ef41Sopenharmony_ci    CanonicalHandleScopeForOptimization<maglev::ExportedMaglevCompilationInfo>;
3391cb0ef41Sopenharmony_ci
3401cb0ef41Sopenharmony_ci// Seal off the current HandleScope so that new handles can only be created
3411cb0ef41Sopenharmony_ci// if a new HandleScope is entered.
3421cb0ef41Sopenharmony_ciclass V8_NODISCARD SealHandleScope final {
3431cb0ef41Sopenharmony_ci public:
3441cb0ef41Sopenharmony_ci#ifndef DEBUG
3451cb0ef41Sopenharmony_ci  explicit SealHandleScope(Isolate* isolate) {}
3461cb0ef41Sopenharmony_ci  ~SealHandleScope() = default;
3471cb0ef41Sopenharmony_ci#else
3481cb0ef41Sopenharmony_ci  explicit inline SealHandleScope(Isolate* isolate);
3491cb0ef41Sopenharmony_ci  inline ~SealHandleScope();
3501cb0ef41Sopenharmony_ci
3511cb0ef41Sopenharmony_ci private:
3521cb0ef41Sopenharmony_ci  Isolate* isolate_;
3531cb0ef41Sopenharmony_ci  Address* prev_limit_;
3541cb0ef41Sopenharmony_ci  int prev_sealed_level_;
3551cb0ef41Sopenharmony_ci#endif
3561cb0ef41Sopenharmony_ci};
3571cb0ef41Sopenharmony_ci
3581cb0ef41Sopenharmony_cistruct HandleScopeData final {
3591cb0ef41Sopenharmony_ci  Address* next;
3601cb0ef41Sopenharmony_ci  Address* limit;
3611cb0ef41Sopenharmony_ci  int level;
3621cb0ef41Sopenharmony_ci  int sealed_level;
3631cb0ef41Sopenharmony_ci  CanonicalHandleScope* canonical_scope;
3641cb0ef41Sopenharmony_ci
3651cb0ef41Sopenharmony_ci  void Initialize() {
3661cb0ef41Sopenharmony_ci    next = limit = nullptr;
3671cb0ef41Sopenharmony_ci    sealed_level = level = 0;
3681cb0ef41Sopenharmony_ci    canonical_scope = nullptr;
3691cb0ef41Sopenharmony_ci  }
3701cb0ef41Sopenharmony_ci};
3711cb0ef41Sopenharmony_ci
3721cb0ef41Sopenharmony_ci}  // namespace internal
3731cb0ef41Sopenharmony_ci}  // namespace v8
3741cb0ef41Sopenharmony_ci
3751cb0ef41Sopenharmony_ci#endif  // V8_HANDLES_HANDLES_H_
376