From 2fc0e6792f1465d15862047c6e4308590f458ab5 Mon Sep 17 00:00:00 2001 From: Aapo Alasuutari Date: Mon, 9 Feb 2026 21:28:53 +0200 Subject: [PATCH] fix(gc): process PrivateEnvironment marks during GC --- nova_vm/src/heap/heap_gc.rs | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/nova_vm/src/heap/heap_gc.rs b/nova_vm/src/heap/heap_gc.rs index c0113e435..9dae9de49 100644 --- a/nova_vm/src/heap/heap_gc.rs +++ b/nova_vm/src/heap/heap_gc.rs @@ -26,8 +26,9 @@ use crate::{ EmbedderObject, Environments, Error, FinalizationRegistry, FunctionEnvironment, Generator, GlobalEnvironment, HeapBigInt, HeapNumber, HeapString, Map, MapIterator, Module, ModuleEnvironment, ModuleRequest, ObjectEnvironment, ObjectShape, OrdinaryObject, - PrimitiveObject, Promise, PromiseGroup, PromiseReaction, PropertyLookupCache, Proxy, Realm, - Script, SourceCode, SourceTextModule, StringIterator, Symbol, + PrimitiveObject, PrivateEnvironment, Promise, PromiseGroup, PromiseReaction, + PropertyLookupCache, Proxy, Realm, Script, SourceCode, SourceTextModule, StringIterator, + Symbol, }, engine::{Bindable, Executable, GcScope}, heap::{ @@ -167,7 +168,7 @@ pub(crate) fn heap_gc(agent: &mut Agent, root_realms: &mut [Option = + queues.private_environments.drain(..).collect(); + private_environment_marks.sort(); + private_environment_marks.iter().for_each(|&idx| { + let index = idx.get_index(); + if bits.private_environments.set_bit(index, &bits.bits) { + // Did mark. + private_environments.get(index).mark_values(&mut queues); + } + }); + } + if !queues.pending_ephemerons.is_empty() { queues.pending_ephemerons.sort_by_key(|(key, _)| *key); let new_values_to_mark = queues @@ -1295,7 +1309,7 @@ fn sweep( global, module, object, - private: _private_environments, + private, } = environments; let ElementArrays { e2pow1, @@ -1790,6 +1804,16 @@ fn sweep( ); }); } + if !private.is_empty() { + s.spawn(|| { + sweep_heap_vector_values( + private, + &compactions, + &bits.private_environments, + &bits.bits, + ); + }); + } if !object_shapes.is_empty() { s.spawn(|| { sweep_heap_vector_values(