shadow_realm: fix memory leak by removing strong reference tracking #60188
+24
−19
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Eliminate a memory leak in ShadowRealms by removing Environment’s C++-side tracking of realm instances. Storing raw pointers in Environment::shadow_realms_ anchored the native ShadowRealm objects until env teardown. With the realm’s v8::Global set weak, V8 could collect the JS context, but native allocations stuck around because the C++ owner never went away. Removing the C++ lifetime root lets the weak callback + cleanup hook reclaim everything promptly.
What changed
• Remove TrackShadowRealm/UntrackShadowRealm and shadow_realms_ from Environment.
• In the constructor, keep context_.SetWeak(this, WeakCallback, …) and register env->AddCleanupHook(DeleteMe, this). No env-level tracking.
• Drop the DCHECKs/memory accounting related to the set.
Why this is correct
• V8 GC liveness is governed by persistent handles; our Context handle is weak, so it doesn’t hold the realm alive.
• The C++ object’s lifetime must not be independently rooted by the host (env set). Ownership is now: weak handle → WeakCallback → delete C++ realm; env cleanup hook is a safety net.
• This matches Node’s established pattern for leak testing with weak callbacks and forced GC. 
Evidence
• Repro script (100–1000 realms with periodic gc()): before = linear native growth / OOM under small heaps; after = stable RSS, completes.
• This aligns with prior ShadowRealm leak reports and the guidance to avoid anchoring contexts through out-of-band roots. 
Notes
• ShadowRealm is currently a TC39 Stage 2.7 proposal (not Stage 4); updated wording accordingly. 
Tests
• test/parallel/test-shadow-realm-gc.js already exercises GC of many realms under a small heap; it fails before this change and passes after (no OOM). This PR relies on that coverage.
Fixes: #47353.