6
6
#include < type_traits> // std::remove_reference
7
7
#include " cppgc/garbage-collected.h"
8
8
#include " cppgc/name-provider.h"
9
- #include " env.h"
10
9
#include " memory_tracker.h"
10
+ #include " util.h"
11
11
#include " v8-cppgc.h"
12
12
#include " v8-sandbox.h"
13
13
#include " v8.h"
14
14
15
15
namespace node {
16
16
17
+ class Environment ;
18
+ class Realm ;
19
+ class CppgcWrapperList ;
20
+
17
21
/* *
18
22
* This is a helper mixin with a BaseObject-like interface to help
19
23
* implementing wrapper objects managed by V8's cppgc (Oilpan) library.
@@ -47,8 +51,7 @@ namespace node {
47
51
* // Do cleanup that relies on a living Environemnt.
48
52
* }
49
53
*/
50
- class CppgcMixin : public cppgc ::GarbageCollectedMixin,
51
- public CppgcWrapperListNode {
54
+ class CppgcMixin : public cppgc ::GarbageCollectedMixin, public MemoryRetainer {
52
55
public:
53
56
// To help various callbacks access wrapper objects with different memory
54
57
// management, cppgc-managed objects share the same layout as BaseObjects.
@@ -58,71 +61,55 @@ class CppgcMixin : public cppgc::GarbageCollectedMixin,
58
61
// invoked from the child class constructor, per cppgc::GarbageCollectedMixin
59
62
// rules.
60
63
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);
73
67
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);
76
72
}
77
73
78
- Environment* env () const { return env_; }
79
-
80
74
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);
95
76
96
77
// Subclasses are expected to invoke CppgcMixin::Trace() in their own Trace()
97
78
// methods.
98
79
void Trace (cppgc::Visitor* visitor) const override {
99
80
visitor->Trace (traced_reference_);
100
81
}
101
82
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
109
93
// destructor. Outside of CleanEnvResource(), subclasses should avoid calling
110
94
// into JavaScript or perform any operation that can trigger garbage
111
95
// 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 ;
116
100
}
117
101
118
102
// 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 ,
120
104
// 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 ;
122
108
123
109
private:
124
- Environment* env_ = nullptr ;
110
+ Realm* realm_ = nullptr ;
125
111
v8::TracedReference<v8::Object> traced_reference_;
112
+ ListNode<CppgcMixin> wrapper_list_node_;
126
113
};
127
114
128
115
// If the class doesn't have additional owned traceable data, use this macro to
@@ -137,7 +124,8 @@ class CppgcMixin : public cppgc::GarbageCollectedMixin,
137
124
#define SET_CPPGC_NAME (Klass ) \
138
125
inline const char * GetHumanReadableName () const final { \
139
126
return " Node / " #Klass; \
140
- }
127
+ } \
128
+ inline const char * MemoryInfoName () const override { return #Klass; }
141
129
142
130
/* *
143
131
* Similar to ASSIGN_OR_RETURN_UNWRAP() but works on cppgc-managed types
0 commit comments