Commit e920961
authored
A handful of optimizations for the DRC collector (#12974)
* Cache `TraceInfo` lookups in the DRC collector
Ideally we would just use a `SecondaryMap<VMSharedTypeIndex, TraceInfo>` here
but allocating `O(num engine types)` space inside a store that uses only a
couple types seems not great. So instead, we just have a fixed size cache that
is probably big enough for most things in practice.
* Combine dec_ref, trace, and dealloc into single-pass loop
Inline `dec_ref`, `trace_gc_ref`, and `dealloc` into
`dec_ref_and_maybe_dealloc`'s main loop so that we read the `VMDrcHeader` once
per object to get `ref_count`, type index, and `object_size`, avoiding 3
separate GC heap accesses and bounds checks per freed object.
For struct tracing, read gc_ref fields directly from the heap slice at known
offsets instead of going through gc_object_data → object_range → object_size
which would re-read the object_size from the header.
301,333,979,721 -> 291,038,676,119 instructions (~3.4% improvement)
* Fast-path `gc_alloc_raw` to skip async/fiber machinery when GC store exists
When the GC store is already initialized and the allocation succeeds, avoid
async machinery entirely. This avoids the overhead of taking/restoring fiber
async state pointers on every allocation.
291,038,676,119 -> 230,503,364,489 instructions (~20.8% improvement)
* Pass `VMSharedTypeIndex`es to the `gc_alloc_raw` libcall
Avoids converting `ModuleInternedTypeIndex` to `VMSharedTypeIndex` in host code,
which requires look ups in the instance's module's `TypeCollection`. We already
have helpers to do this conversion inline in JIT code.
230,503,364,489 -> 216,937,168,529 instructions (~5.9% improvement)
* Do not effectively double-test for `externref`s during DRC deallocation
Moves the `externref` host data cleanup inside the `ty.is_none()` branch of
`dec_ref_and_maybe_dealloc`, since only `externref`s have host
data. Additionally the type check is sort of expensive since it involves
additional bounds-checked reads from the GC heap.
* Fix warning
* Update exceptions disas results
* Fix an overflow bug in the free list's bump allocation
* Revert "Cache `TraceInfo` lookups in the DRC collector"
This reverts commit 41dcbd931170c0e510b5baf9e0cafa19a83c0ddd.
* Use a custom hasher for the trace-info hash map
* Fix free list tests
* fix free list tests
* Really fix free list tests this time?
* Fix free list add_capacity on 32-bit architectures
`Layout::from_size_align` rejects sizes greater than `isize::MAX`, causing
`add_capacity` to silently discard new capacity blocks that exceed this
limit. This meant the free list could not grow beyond ~2 GB on 32-bit even
though our `u32` indices can address up to ~4 GB.
Fix by calling `dealloc_impl` directly in add_capacity, bypassing the `Layout`
construction. The block index and size are already properly aligned u32 values,
so the `Layout` validation is unnecessary for internal free list bookkeeping.
Also remove a redundant `debug_assert` in `dealloc_impl` that constructed a
`Layout` (hitting the same `isize::MAX` limitation), since the alignment
invariant is already checked by the adjacent assertions.
* Fix warnings
* fix unused import warning
* Fix `allocated_bytes` accounting after rebase1 parent 7bd61b8 commit e920961
21 files changed
Lines changed: 690 additions & 512 deletions
File tree
- crates
- cranelift/src/func_environ/gc/enabled
- environ/src
- wasmtime
- proptest-regressions/runtime/vm/gc/enabled
- src/runtime
- store
- vm
- gc/enabled
- tests/disas
- gc
- drc
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
364 | 364 | | |
365 | 365 | | |
366 | 366 | | |
367 | | - | |
| 367 | + | |
368 | 368 | | |
369 | 369 | | |
370 | 370 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
86 | 86 | | |
87 | 87 | | |
88 | 88 | | |
89 | | - | |
| 89 | + | |
90 | 90 | | |
91 | 91 | | |
92 | 92 | | |
| |||
Lines changed: 1 addition & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2074 | 2074 | | |
2075 | 2075 | | |
2076 | 2076 | | |
| 2077 | + | |
| 2078 | + | |
| 2079 | + | |
| 2080 | + | |
| 2081 | + | |
| 2082 | + | |
| 2083 | + | |
2077 | 2084 | | |
2078 | 2085 | | |
2079 | 2086 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
| 60 | + | |
60 | 61 | | |
61 | 62 | | |
62 | 63 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
113 | 113 | | |
114 | 114 | | |
115 | 115 | | |
116 | | - | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
117 | 121 | | |
118 | 122 | | |
119 | 123 | | |
| |||
0 commit comments