diff --git a/boa_gc/src/internals/ephemeron_box.rs b/boa_gc/src/internals/ephemeron_box.rs index 9c220e1b066..68cbb0af976 100644 --- a/boa_gc/src/internals/ephemeron_box.rs +++ b/boa_gc/src/internals/ephemeron_box.rs @@ -88,6 +88,16 @@ pub(crate) struct EphemeronBox data: Cell>>>, } +impl Drop for EphemeronBox { + fn drop(&mut self) { + if let Some(data) = self.data.take() { + // SAFETY: `data` comes from an `into_raw` call, so this pointer is safe to pass to + // `from_raw`. + drop(unsafe { Box::from_raw(data.as_ptr()) }); + } + } +} + struct Data { key: NonNull>, value: V, diff --git a/boa_gc/src/lib.rs b/boa_gc/src/lib.rs index 87a0b9267bb..49158b19369 100644 --- a/boa_gc/src/lib.rs +++ b/boa_gc/src/lib.rs @@ -451,13 +451,22 @@ impl Collector { // Not initializing a dropguard since this should only be invoked when BOA_GC is being dropped. let _guard = DropGuard::new(); - let sweep_head = &gc.strong_start; - while let Some(node) = sweep_head.get() { + let strong_head = &gc.strong_start; + while let Some(node) = strong_head.get() { // SAFETY: // The `Allocator` must always ensure its start node is a valid, non-null pointer that // was allocated by `Box::from_raw(Box::new(..))`. let unmarked_node = unsafe { Box::from_raw(node.as_ptr()) }; - sweep_head.set(unmarked_node.header.next.take()); + strong_head.set(unmarked_node.header.next.take()); + } + + let eph_head = &gc.weak_start; + while let Some(node) = eph_head.get() { + // SAFETY: + // The `Allocator` must always ensure its start node is a valid, non-null pointer that + // was allocated by `Box::from_raw(Box::new(..))`. + let unmarked_node = unsafe { Box::from_raw(node.as_ptr()) }; + eph_head.set(unmarked_node.header().next.take()); } } }