Skip to content

Commit 620e3f5

Browse files
authored
Clear trace info on GcHeap::detach (#13423)
The `VMSharedTypeIndex` keys can become stale before re-attachment. Fixes #13417
1 parent 63af868 commit 620e3f5

4 files changed

Lines changed: 43 additions & 9 deletions

File tree

crates/wasmtime/src/runtime/vm/gc/enabled/copying.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -625,10 +625,7 @@ unsafe impl GcHeap for CopyingHeap {
625625
worklist_ptr,
626626
active_extern_ref_set_head,
627627
idle_extern_ref_set_head,
628-
// NB: we will only ever be reused with the same engine, so no need
629-
// to clear out our tracing info just to fill it back in with the
630-
// same exact stuff.
631-
trace_infos: _,
628+
trace_infos,
632629
} = self;
633630

634631
*no_gc_count = 0;
@@ -639,6 +636,7 @@ unsafe impl GcHeap for CopyingHeap {
639636
*worklist_ptr = 0;
640637
*active_extern_ref_set_head = None;
641638
*idle_extern_ref_set_head = None;
639+
trace_infos.clear();
642640

643641
memory.take().unwrap()
644642
}

crates/wasmtime/src/runtime/vm/gc/enabled/drc.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -789,18 +789,15 @@ unsafe impl GcHeap for DrcHeap {
789789
memory,
790790
vmmemory,
791791
allocated_bytes,
792-
793-
// NB: we will only ever be reused with the same engine, so no need
794-
// to clear out our tracing info just to fill it back in with the
795-
// same exact stuff.
796-
trace_infos: _,
792+
trace_infos,
797793
} = self;
798794

799795
*no_gc_count = 0;
800796
**over_approximated_stack_roots = None;
801797
*free_list = None;
802798
*vmmemory = None;
803799
*allocated_bytes = 0;
800+
trace_infos.clear();
804801
debug_assert!(dec_ref_stack.as_ref().is_some_and(|s| s.is_empty()));
805802
debug_assert!(
806803
large_array_dec_ref_stack

crates/wasmtime/src/runtime/vm/gc/enabled/trace_info.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ impl TraceInfos {
106106
self.engine.upgrade().unwrap()
107107
}
108108

109+
/// Remove all trace info from this collection.
110+
pub fn clear(&mut self) {
111+
self.map.clear();
112+
}
113+
109114
/// Index into the trace infos, panicking if the type is not present.
110115
pub fn trace_info(&self, ty: &VMSharedTypeIndex) -> &TraceInfo {
111116
&self.map[ty]
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
;;! gc = true
2+
3+
(module)
4+
5+
(thread $old
6+
(module
7+
;; Register stale trace metadata for a large struct whose final field is a
8+
;; GC reference. The field offset is valid for this type, but not for the
9+
;; smaller type instantiated after this thread's Store is dropped.
10+
(type $old (struct
11+
(field i64) (field i64) (field i64) (field i64)
12+
(field i64) (field i64) (field i64) (field i64)
13+
(field i64) (field i64) (field i64) (field i64)
14+
(field i64) (field i64) (field i64) (field i64)
15+
(field anyref)))
16+
(global (ref null $old)
17+
(struct.new $old
18+
(i64.const 0) (i64.const 0) (i64.const 0) (i64.const 0)
19+
(i64.const 0) (i64.const 0) (i64.const 0) (i64.const 0)
20+
(i64.const 0) (i64.const 0) (i64.const 0) (i64.const 0)
21+
(i64.const 0) (i64.const 0) (i64.const 0) (i64.const 0)
22+
(ref.null any)))))
23+
(wait $old)
24+
25+
(module
26+
(type $new (struct (field (mut i32))))
27+
(global $g (mut (ref null $new))
28+
(struct.new $new (i32.const 1)))
29+
(func (export "trigger")
30+
;; Overwriting the global makes DRC decrement and deallocate the old value,
31+
;; consuming the stale trace metadata without forcing an explicit GC.
32+
(global.set $g (ref.null $new))))
33+
34+
(invoke "trigger")

0 commit comments

Comments
 (0)