Skip to content

Add separate libcalls for array.copy w/ vs. w/out GC ref elems#13312

Open
fitzgen wants to merge 1 commit intobytecodealliance:mainfrom
fitzgen:wasmtime-array-copy-non-gc-ref
Open

Add separate libcalls for array.copy w/ vs. w/out GC ref elems#13312
fitzgen wants to merge 1 commit intobytecodealliance:mainfrom
fitzgen:wasmtime-array-copy-non-gc-ref

Conversation

@fitzgen
Copy link
Copy Markdown
Member

@fitzgen fitzgen commented May 6, 2026

Addresses a long-standing TODO comment whose performance implications were also observed in #13279

(Still investigating the panic that issue's benchmarks trigger in the copying collector, however.)

Addresses a long-standing `TODO` comment whose performance implications were
also observed in bytecodealliance#13279
@fitzgen fitzgen requested review from a team as code owners May 6, 2026 23:09
@fitzgen fitzgen requested review from alexcrichton and removed request for a team May 6, 2026 23:09
Copy link
Copy Markdown
Member

@alexcrichton alexcrichton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a test as well that takes ~little time with this PR but maybe ~many seconds without this PR? Out of curiosity, how much does this help #13279?

Also, as a separate question, would it make sense to delete one or both of these libcalls eventually? For example with GC arrays I figure it'd be best to just do the loop in Cranelift, and for non-GC arrays I figure it might be best to have a single memcpy libcall that's pretty raw and that way we could funnel memory.copy through there too. That way we could const-propagate a lot of things here like the checked_mul and array offsets and such which might be a noticable boost.

Comment on lines +1235 to +1243
// SAFETY: Both pointers are derived from the same `VMGcObjectData`
// and are within the bounds we already checked. `core::ptr::copy`
// handles the overlapping case correctly, and no GC can occur
// because we are only copying non-GC-ref elements.
unsafe {
let src_ptr = data.slice(src_byte_start, byte_len).as_ptr();
let dst_ptr = data.slice_mut(dst_byte_start, byte_len).as_mut_ptr();
core::ptr::copy(src_ptr, dst_ptr, usize::try_from(byte_len).unwrap());
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Were we to run this through miri I think it would flag this as a violation as data.slice_mut I believe invalidates the previous src_ptr derived. Would it be possible to use copy_within here?

@github-actions github-actions Bot added the wasmtime:api Related to the API of the `wasmtime` crate itself label May 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

wasmtime:api Related to the API of the `wasmtime` crate itself

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants