A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/nodejs/node/commit/a35cc216e5 below:

track cppgc wrappers with a list in Realm · nodejs/node@a35cc21 · GitHub

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"

9 +

#include "cppgc/persistent.h"

10 10

#include "memory_tracker.h"

11 +

#include "util.h"

11 12

#include "v8-cppgc.h"

12 13

#include "v8-sandbox.h"

13 14

#include "v8.h"

14 15 15 16

namespace node {

16 17 18 +

class Environment;

19 +

class Realm;

20 +

class CppgcWrapperListNode;

21 + 17 22

/**

18 23

* This is a helper mixin with a BaseObject-like interface to help

19 24

* implementing wrapper objects managed by V8's cppgc (Oilpan) library.

@@ -25,20 +30,29 @@ namespace node {

25 30

* with V8's GC scheduling.

26 31

*

27 32

* A cppgc-managed native wrapper should look something like this, note

28 -

* that per cppgc rules, CPPGC_MIXIN(Klass) must be at the left-most

33 +

* that per cppgc rules, CPPGC_MIXIN(MyWrap) must be at the left-most

29 34

* position in the hierarchy (which ensures cppgc::GarbageCollected

30 35

* is at the left-most position).

31 36

*

32 -

* class Klass final : CPPGC_MIXIN(Klass) {

37 +

* class MyWrap final : CPPGC_MIXIN(MyWrap) {

33 38

* public:

34 -

* SET_CPPGC_NAME(Klass) // Sets the heap snapshot name to "Node / Klass"

39 +

* SET_CPPGC_NAME(MyWrap) // Sets the heap snapshot name to "Node / MyWrap"

35 40

* void Trace(cppgc::Visitor* visitor) const final {

36 41

* CppgcMixin::Trace(visitor);

37 42

* visitor->Trace(...); // Trace any additional owned traceable data

38 43

* }

39 44

* }

45 +

*

46 +

* If the wrapper needs to perform cleanups when it's destroyed and that

47 +

* cleanup relies on a living Node.js `Realm`, it should implement a

48 +

* pattern like this:

49 +

*

50 +

* ~MyWrap() { this->Destroy(); }

51 +

* void Clean(Realm* env) override {

52 +

* // Do cleanup that relies on a living Environemnt.

53 +

* }

40 54

*/

41 -

class CppgcMixin : public cppgc::GarbageCollectedMixin {

55 +

class CppgcMixin : public cppgc::GarbageCollectedMixin, public MemoryRetainer {

42 56

public:

43 57

// To help various callbacks access wrapper objects with different memory

44 58

// management, cppgc-managed objects share the same layout as BaseObjects.

@@ -48,48 +62,58 @@ class CppgcMixin : public cppgc::GarbageCollectedMixin {

48 62

// invoked from the child class constructor, per cppgc::GarbageCollectedMixin

49 63

// rules.

50 64

template <typename T>

51 -

static void Wrap(T* ptr, Environment* env, v8::Local<v8::Object> obj) {

52 -

CHECK_GE(obj->InternalFieldCount(), T::kInternalFieldCount);

53 -

ptr->env_ = env;

54 -

v8::Isolate* isolate = env->isolate();

55 -

ptr->traced_reference_ = v8::TracedReference<v8::Object>(isolate, obj);

56 -

v8::Object::Wrap<v8::CppHeapPointerTag::kDefaultTag>(isolate, obj, ptr);

57 -

// Keep the layout consistent with BaseObjects.

58 -

obj->SetAlignedPointerInInternalField(

59 -

kEmbedderType, env->isolate_data()->embedder_id_for_cppgc());

60 -

obj->SetAlignedPointerInInternalField(kSlot, ptr);

61 -

}

65 +

static inline void Wrap(T* ptr, Realm* realm, v8::Local<v8::Object> obj);

66 +

template <typename T>

67 +

static inline void Wrap(T* ptr, Environment* env, v8::Local<v8::Object> obj);

62 68 63 -

v8::Local<v8::Object> object() const {

64 -

return traced_reference_.Get(env_->isolate());

69 +

inline v8::Local<v8::Object> object() const;

70 +

inline Environment* env() const;

71 +

inline Realm* realm() const { return realm_; }

72 +

inline v8::Local<v8::Object> object(v8::Isolate* isolate) const {

73 +

return traced_reference_.Get(isolate);

65 74

}

66 75 67 -

Environment* env() const { return env_; }

68 - 69 76

template <typename T>

70 -

static T* Unwrap(v8::Local<v8::Object> obj) {

71 -

// We are not using v8::Object::Unwrap currently because that requires

72 -

// access to isolate which the ASSIGN_OR_RETURN_UNWRAP macro that we'll shim

73 -

// with ASSIGN_OR_RETURN_UNWRAP_GC doesn't take, and we also want a

74 -

// signature consistent with BaseObject::Unwrap() to avoid churn. Since

75 -

// cppgc-managed objects share the same layout as BaseObjects, just unwrap

76 -

// from the pointer in the internal field, which should be valid as long as

77 -

// the object is still alive.

78 -

if (obj->InternalFieldCount() != T::kInternalFieldCount) {

79 -

return nullptr;

80 -

}

81 -

T* ptr = static_cast<T*>(obj->GetAlignedPointerFromInternalField(T::kSlot));

82 -

return ptr;

83 -

}

77 +

static inline T* Unwrap(v8::Local<v8::Object> obj);

84 78 85 79

// Subclasses are expected to invoke CppgcMixin::Trace() in their own Trace()

86 80

// methods.

87 81

void Trace(cppgc::Visitor* visitor) const override {

88 82

visitor->Trace(traced_reference_);

89 83

}

90 84 85 +

// TODO(joyeecheung): use ObjectSizeTrait;

86 +

inline size_t SelfSize() const override { return sizeof(*this); }

87 +

inline bool IsCppgcWrapper() const override { return true; }

88 + 89 +

// This is run for all the remaining Cppgc wrappers tracked in the Realm

90 +

// during Realm shutdown. The destruction of the wrappers would happen later,

91 +

// when the final garbage collection is triggered when CppHeap is torn down as

92 +

// part of the Isolate teardown. If subclasses of CppgcMixin wish to perform

93 +

// cleanups that depend on the Realm during destruction, they should implment

94 +

// it in a Clean() override, and then call this->Finalize() from their

95 +

// destructor. Outside of Finalize(), subclasses should avoid calling

96 +

// into JavaScript or perform any operation that can trigger garbage

97 +

// collection during the destruction.

98 +

void Finalize() {

99 +

if (realm_ == nullptr) return;

100 +

this->Clean(realm_);

101 +

realm_ = nullptr;

102 +

}

103 + 104 +

// The default implementation of Clean() is a no-op. If subclasses wish

105 +

// to perform cleanup that require a living Realm, they should

106 +

// should put the cleanups in a Clean() override, and call this->Finalize()

107 +

// in the destructor, instead of doing those cleanups directly in the

108 +

// destructor.

109 +

virtual void Clean(Realm* realm) {}

110 + 111 +

inline ~CppgcMixin();

112 + 113 +

friend class CppgcWrapperListNode;

114 + 91 115

private:

92 -

Environment* env_;

116 +

Realm* realm_ = nullptr;

93 117

v8::TracedReference<v8::Object> traced_reference_;

94 118

};

95 119

@@ -105,7 +129,8 @@ class CppgcMixin : public cppgc::GarbageCollectedMixin {

105 129

#define SET_CPPGC_NAME(Klass) \

106 130

inline const char* GetHumanReadableName() const final { \

107 131

return "Node / " #Klass; \

108 -

}

132 +

} \

133 +

inline const char* MemoryInfoName() const override { return #Klass; }

109 134 110 135

/**

111 136

* Similar to ASSIGN_OR_RETURN_UNWRAP() but works on cppgc-managed types


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4