Skip to content

Avoid cloning and dropping Arcs in LocalMemory::vmmemory #11148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

fitzgen
Copy link
Member

@fitzgen fitzgen commented Jun 27, 2025

Getting the base pointer from the underlying dyn RuntimeLinearMemory involved getting a MemoryBase which is potentially an MmapOffset which itself contains an Arc<Mmap>, and we would then call base.as_non_null() to turn this into a raw pointer, and then we would drop the MemoryBase which ultimately drops the Arc<Mmap>. So that's an Arc clone and drop just to get a VMMemoryDefinition, which is just a pointer and a length, essentially a slice of the linear memory. And, among other places, we call LocalMemory::vmmemory to get the GC heap's memory base and bound every time we access a GC object from Rust (for example, during collections).

Altogether, this removes another 30% of runtime from the testcase in #11141

Getting the base pointer from the underlying `dyn RuntimeLinearMemory` involved
getting a `MemoryBase` which is potentially an `MmapOffset` which itself
contains an `Arc<Mmap>`, and we would then call `base.as_non_null()` to turn
this into a raw pointer, and then we would drop the `MemoryBase` which
ultimately drops the `Arc<Mmap>`. So that's an `Arc` clone and drop just to get
a `VMMemoryDefinition`, which is just a pointer and a length, essentially a
slice of the linear memory. And, among other places, we call
`LocalMemory::vmmemory` to get the GC heap's memory base and bound every time we
access a GC object from Rust (for example, during collections).

Altogether, this removes another 30% of runtime from the testcase in
bytecodealliance#11141
@fitzgen fitzgen requested a review from a team as a code owner June 27, 2025 17:19
@fitzgen fitzgen requested review from dicej and removed request for a team June 27, 2025 17:19
@fitzgen
Copy link
Member Author

fitzgen commented Jun 27, 2025

All that said, I don't love how this PR introduces a second version of the "same" method. It might be nicer to instead add a vmmemory method to RuntimeLinearMemory and push VMMemoryDefinition construction down to implementations of that trait, rather than tying together the results of different RuntimeLinearMemory methods in LocalMemory.

That would actually let us avoid an indirect call too:

  • Now:
    • LocalMemory indirect-calls the byte_size method through a dyn RuntimeLinearMemory
    • LocalMemory indirect-calls the base (now base_non_null in this PR) method through a dyn RuntimeLinearMemory
    • LocalMemory puts them together into a VMMemoryDefinition
  • Alternative:
    • LocalMemory indirect-calls the hypothetical vmmemory method through a dyn RuntimeLinearMemory
    • The RuntimeLinearMemory implementation gets its byte size and base, which can both be done directly/inlined/etc because we aren't crossing a dyn boundary anymore
    • The RuntimeLinearMemory implementation puts them together into a VMMemoryDefinition
    • The VMMemoryDefinition is returned to the LocalMemory, which returns it to its caller in turn

Note that the "now" sequence has two indirect calls while the alternative has only one.

I'm going to whip this alternative up real quick and then update this PR.

…tation

Instead of in `LocalMemory` via calling various `RuntimeLinearMemory` methods,
as `LocalMemory` has a `dyn RuntimeLinearMemory` object so those calls are all
indirect.
@fitzgen
Copy link
Member Author

fitzgen commented Jun 27, 2025

I'm going to whip this alternative up real quick and then update this PR.

I've pushed a commit that implements this.

@alexcrichton alexcrichton added this pull request to the merge queue Jun 27, 2025
Merged via the queue into bytecodealliance:main with commit 046a51c Jun 27, 2025
42 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants