Skip to content

Commit 5250947

Browse files
joyeecheungRafaelGSS
authored andcommitted
src: track ShadowRealm native objects correctly in the heap snapshot
Previously the native ShadowRealm objects were never actually tracked in the heap snapshot - the tracking starts with the Environment, we don't call the tracking methods unless it's reachable natively from the Environment. This patch adds a set in the Environment for tracking shadow realms in the heap snapshot. Drive-by: remove redundant MemoryInfo() overrides from the derived classes of Realm and remove the tracking of `env` from `Realm::MemoryInfo()` because the realms don't hold the Environment alive (even for the principal realm, it's the other way around). PR-URL: #47389 Reviewed-By: Chengzhong Wu <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Colin Ihrig <[email protected]>
1 parent 9a4d21d commit 5250947

File tree

6 files changed

+30
-9
lines changed

6 files changed

+30
-9
lines changed

src/env.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "node_internals.h"
1212
#include "node_options-inl.h"
1313
#include "node_process-inl.h"
14+
#include "node_shadow_realm.h"
1415
#include "node_v8_platform-inl.h"
1516
#include "node_worker.h"
1617
#include "req_wrap-inl.h"
@@ -226,6 +227,14 @@ void Environment::UntrackContext(Local<Context> context) {
226227
}
227228
}
228229

230+
void Environment::TrackShadowRealm(shadow_realm::ShadowRealm* realm) {
231+
shadow_realms_.insert(realm);
232+
}
233+
234+
void Environment::UntrackShadowRealm(shadow_realm::ShadowRealm* realm) {
235+
shadow_realms_.erase(realm);
236+
}
237+
229238
AsyncHooks::DefaultTriggerAsyncIdScope::DefaultTriggerAsyncIdScope(
230239
Environment* env, double default_trigger_async_id)
231240
: async_hooks_(env->async_hooks()) {
@@ -901,6 +910,10 @@ Environment::~Environment() {
901910
addon.Close();
902911
}
903912
}
913+
914+
for (auto realm : shadow_realms_) {
915+
realm->OnEnvironmentDestruct();
916+
}
904917
}
905918

906919
void Environment::InitializeLibuv() {
@@ -1896,6 +1909,7 @@ void Environment::MemoryInfo(MemoryTracker* tracker) const {
18961909
tracker->TrackField("timeout_info", timeout_info_);
18971910
tracker->TrackField("tick_info", tick_info_);
18981911
tracker->TrackField("principal_realm", principal_realm_);
1912+
tracker->TrackField("shadow_realms", shadow_realms_);
18991913

19001914
// FIXME(joyeecheung): track other fields in Environment.
19011915
// Currently MemoryTracker is unable to track these

src/env.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@
6464

6565
namespace node {
6666

67+
namespace shadow_realm {
68+
class ShadowRealm;
69+
}
6770
namespace contextify {
6871
class ContextifyScript;
6972
class CompiledFnEntry;
@@ -643,6 +646,8 @@ class Environment : public MemoryRetainer {
643646
const ContextInfo& info);
644647
void TrackContext(v8::Local<v8::Context> context);
645648
void UntrackContext(v8::Local<v8::Context> context);
649+
void TrackShadowRealm(shadow_realm::ShadowRealm* realm);
650+
void UntrackShadowRealm(shadow_realm::ShadowRealm* realm);
646651

647652
void StartProfilerIdleNotifier();
648653

@@ -1020,6 +1025,7 @@ class Environment : public MemoryRetainer {
10201025

10211026
size_t async_callback_scope_depth_ = 0;
10221027
std::vector<double> destroy_async_id_list_;
1028+
std::unordered_set<shadow_realm::ShadowRealm*> shadow_realms_;
10231029

10241030
#if HAVE_INSPECTOR
10251031
std::unique_ptr<profiler::V8CoverageConnection> coverage_connection_;

src/node_realm.cc

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ void Realm::MemoryInfo(MemoryTracker* tracker) const {
3333
PER_REALM_STRONG_PERSISTENT_VALUES(V)
3434
#undef V
3535

36-
tracker->TrackField("env", env_);
3736
tracker->TrackField("cleanup_queue", cleanup_queue_);
3837
tracker->TrackField("builtins_with_cache", builtins_with_cache);
3938
tracker->TrackField("builtins_without_cache", builtins_without_cache);
@@ -301,10 +300,6 @@ PrincipalRealm::PrincipalRealm(Environment* env,
301300
}
302301
}
303302

304-
void PrincipalRealm::MemoryInfo(MemoryTracker* tracker) const {
305-
Realm::MemoryInfo(tracker);
306-
}
307-
308303
MaybeLocal<Value> PrincipalRealm::BootstrapRealm() {
309304
HandleScope scope(isolate_);
310305

src/node_realm.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ class PrincipalRealm : public Realm {
165165

166166
SET_MEMORY_INFO_NAME(PrincipalRealm)
167167
SET_SELF_SIZE(PrincipalRealm)
168-
void MemoryInfo(MemoryTracker* tracker) const override;
169168

170169
#define V(PropertyName, TypeName) \
171170
v8::Local<TypeName> PropertyName() const override; \

src/node_shadow_realm.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ void ShadowRealm::WeakCallback(const v8::WeakCallbackInfo<ShadowRealm>& data) {
4646

4747
ShadowRealm::ShadowRealm(Environment* env)
4848
: Realm(env, NewContext(env->isolate()), kShadowRealm) {
49+
env->TrackShadowRealm(this);
4950
context_.SetWeak(this, WeakCallback, v8::WeakCallbackType::kParameter);
5051
CreateProperties();
5152
}
@@ -54,10 +55,15 @@ ShadowRealm::~ShadowRealm() {
5455
while (HasCleanupHooks()) {
5556
RunCleanup();
5657
}
58+
if (env_ != nullptr) {
59+
env_->UntrackShadowRealm(this);
60+
}
5761
}
5862

59-
void ShadowRealm::MemoryInfo(MemoryTracker* tracker) const {
60-
Realm::MemoryInfo(tracker);
63+
void ShadowRealm::OnEnvironmentDestruct() {
64+
CHECK_NOT_NULL(env_);
65+
env_ = nullptr; // This means that the shadow realm has out-lived the
66+
// environment.
6167
}
6268

6369
v8::Local<v8::Context> ShadowRealm::context() const {

src/node_shadow_realm.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ class ShadowRealm : public Realm {
1515

1616
SET_MEMORY_INFO_NAME(ShadowRealm)
1717
SET_SELF_SIZE(ShadowRealm)
18-
void MemoryInfo(MemoryTracker* tracker) const override;
1918

2019
v8::Local<v8::Context> context() const override;
2120

@@ -25,6 +24,8 @@ class ShadowRealm : public Realm {
2524
PER_REALM_STRONG_PERSISTENT_VALUES(V)
2625
#undef V
2726

27+
void OnEnvironmentDestruct();
28+
2829
protected:
2930
v8::MaybeLocal<v8::Value> BootstrapRealm() override;
3031

0 commit comments

Comments
 (0)