66#include < type_traits> // std::remove_reference
77#include " cppgc/garbage-collected.h"
88#include " cppgc/name-provider.h"
9- #include " env.h"
109#include " memory_tracker.h"
10+ #include " util.h"
1111#include " v8-cppgc.h"
1212#include " v8-sandbox.h"
1313#include " v8.h"
1414
1515namespace node {
1616
17+ class Environment ;
18+ class Realm ;
19+ class CppgcWrapperList ;
20+
1721/* *
1822 * This is a helper mixin with a BaseObject-like interface to help
1923 * implementing wrapper objects managed by V8's cppgc (Oilpan) library.
@@ -47,8 +51,7 @@ namespace node {
4751 * // Do cleanup that relies on a living Environemnt.
4852 * }
4953 */
50- class CppgcMixin : public cppgc ::GarbageCollectedMixin,
51- public CppgcWrapperListNode {
54+ class CppgcMixin : public cppgc ::GarbageCollectedMixin, public MemoryRetainer {
5255 public:
5356 // To help various callbacks access wrapper objects with different memory
5457 // management, cppgc-managed objects share the same layout as BaseObjects.
@@ -58,71 +61,55 @@ class CppgcMixin : public cppgc::GarbageCollectedMixin,
5861 // invoked from the child class constructor, per cppgc::GarbageCollectedMixin
5962 // rules.
6063 template <typename T>
61- static void Wrap (T* ptr, Environment* env, v8::Local<v8::Object> obj) {
62- CHECK_GE (obj->InternalFieldCount (), T::kInternalFieldCount );
63- ptr->env_ = env;
64- v8::Isolate* isolate = env->isolate ();
65- ptr->traced_reference_ = v8::TracedReference<v8::Object>(isolate, obj);
66- v8::Object::Wrap<v8::CppHeapPointerTag::kDefaultTag >(isolate, obj, ptr);
67- // Keep the layout consistent with BaseObjects.
68- obj->SetAlignedPointerInInternalField (
69- kEmbedderType , env->isolate_data ()->embedder_id_for_cppgc ());
70- obj->SetAlignedPointerInInternalField (kSlot , ptr);
71- env->cppgc_wrapper_list ()->PushFront (ptr);
72- }
64+ static inline void Wrap (T* ptr, Realm* realm, v8::Local<v8::Object> obj);
65+ template <typename T>
66+ static inline void Wrap (T* ptr, Environment* env, v8::Local<v8::Object> obj);
7367
74- v8::Local<v8::Object> object () const {
75- return traced_reference_.Get (env_->isolate ());
68+ inline v8::Local<v8::Object> object () const ;
69+ inline Environment* env () const ;
70+ inline v8::Local<v8::Object> object (v8::Isolate* isolate) const {
71+ return traced_reference_.Get (isolate);
7672 }
7773
78- Environment* env () const { return env_; }
79-
8074 template <typename T>
81- static T* Unwrap (v8::Local<v8::Object> obj) {
82- // We are not using v8::Object::Unwrap currently because that requires
83- // access to isolate which the ASSIGN_OR_RETURN_UNWRAP macro that we'll shim
84- // with ASSIGN_OR_RETURN_UNWRAP_GC doesn't take, and we also want a
85- // signature consistent with BaseObject::Unwrap() to avoid churn. Since
86- // cppgc-managed objects share the same layout as BaseObjects, just unwrap
87- // from the pointer in the internal field, which should be valid as long as
88- // the object is still alive.
89- if (obj->InternalFieldCount () != T::kInternalFieldCount ) {
90- return nullptr ;
91- }
92- T* ptr = static_cast <T*>(obj->GetAlignedPointerFromInternalField (T::kSlot ));
93- return ptr;
94- }
75+ static inline T* Unwrap (v8::Local<v8::Object> obj);
9576
9677 // Subclasses are expected to invoke CppgcMixin::Trace() in their own Trace()
9778 // methods.
9879 void Trace (cppgc::Visitor* visitor) const override {
9980 visitor->Trace (traced_reference_);
10081 }
10182
102- // This implements CppgcWrapperListNode::Clean and is run for all the
103- // remaining Cppgc wrappers tracked in the Environment during Environment
104- // shutdown. The destruction of the wrappers would happen later, when the
105- // final garbage collection is triggered when CppHeap is torn down as part of
106- // the Isolate teardown. If subclasses of CppgcMixin wish to perform cleanups
107- // that depend on the Environment during destruction, they should implment it
108- // in a CleanEnvResource() override, and then call this->Clean() from their
83+ // TODO(joyeecheung): use ObjectSizeTrait;
84+ inline size_t SelfSize () const override { return sizeof (*this ); }
85+ inline bool IsCppgcWrapper () const override { return true ; }
86+
87+ // This is run for all the remaining Cppgc wrappers tracked in the Realm
88+ // during Realm shutdown. The destruction of the wrappers would happen later,
89+ // when the final garbage collection is triggered when CppHeap is torn down as
90+ // part of the Isolate teardown. If subclasses of CppgcMixin wish to perform
91+ // cleanups that depend on the Realm during destruction, they should implment
92+ // it in a CleanEnvResource() override, and then call this->Clean() from their
10993 // destructor. Outside of CleanEnvResource(), subclasses should avoid calling
11094 // into JavaScript or perform any operation that can trigger garbage
11195 // collection during the destruction.
112- void Clean () override {
113- if (env_ == nullptr ) return ;
114- this ->CleanEnvResource (env_ );
115- env_ = nullptr ;
96+ void Clean () {
97+ if (realm_ == nullptr ) return ;
98+ this ->CleanEnvResource (realm_ );
99+ realm_ = nullptr ;
116100 }
117101
118102 // The default implementation of CleanEnvResource() is a no-op. Subclasses
119- // should override it to perform cleanup that require a living Environment ,
103+ // should override it to perform cleanup that require a living Realm ,
120104 // instead of doing these cleanups directly in the destructor.
121- virtual void CleanEnvResource (Environment* env) {}
105+ virtual void CleanEnvResource (Realm* realm) {}
106+
107+ friend class CppgcWrapperList ;
122108
123109 private:
124- Environment* env_ = nullptr ;
110+ Realm* realm_ = nullptr ;
125111 v8::TracedReference<v8::Object> traced_reference_;
112+ ListNode<CppgcMixin> wrapper_list_node_;
126113};
127114
128115// If the class doesn't have additional owned traceable data, use this macro to
@@ -137,7 +124,8 @@ class CppgcMixin : public cppgc::GarbageCollectedMixin,
137124#define SET_CPPGC_NAME (Klass ) \
138125 inline const char * GetHumanReadableName () const final { \
139126 return " Node / " #Klass; \
140- }
127+ } \
128+ inline const char * MemoryInfoName () const override { return #Klass; }
141129
142130/* *
143131 * Similar to ASSIGN_OR_RETURN_UNWRAP() but works on cppgc-managed types
0 commit comments