Stream: git-wasmtime

Topic: wasmtime / PR #12541 Add support for fine-grained operato...


view this post on Zulip Wasmtime GitHub notifications bot (Feb 09 2026 at 13:20):

d-sonuga opened PR #12541 from d-sonuga:custom-operator-cost to bytecodealliance:main:

Closes https://github.com/bytecodealliance/wasmtime/issues/11572.

Adds support for setting custom operator costs per operator.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 09 2026 at 13:20):

d-sonuga requested cfallin for a review on PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 09 2026 at 13:20):

d-sonuga requested wasmtime-compiler-reviewers for a review on PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 09 2026 at 13:20):

d-sonuga requested wasmtime-core-reviewers for a review on PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 09 2026 at 13:32):

d-sonuga updated PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 09 2026 at 13:37):

d-sonuga updated PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 09 2026 at 15:02):

github-actions[bot] added the label wasmtime:config on PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 09 2026 at 15:02):

github-actions[bot] added the label wasmtime:api on PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 09 2026 at 15:02):

github-actions[bot] added the label winch on PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 09 2026 at 15:02):

github-actions[bot] commented on PR #12541:

Subscribe to Label Action

cc @saulecabrera

<details>
This issue or pull request has been labeled: "wasmtime:api", "wasmtime:config", "winch"

Thus the following users have been cc'd because of the following labels:

To subscribe or unsubscribe from this label, edit the <code>.github/subscribe-to-label.json</code> configuration file.

Learn more.
</details>

view this post on Zulip Wasmtime GitHub notifications bot (Feb 09 2026 at 16:03):

github-actions[bot] commented on PR #12541:

Label Messager: wasmtime:config

It looks like you are changing Wasmtime's configuration options. Make sure to
complete this check list:

[fuzzing-config]: https://github.com/bytecodealliance/wasmtime/blob/ca0e8d0a1d8cefc0496dba2f77a670571d8fdcab/crates/fuzzing/src/generators.rs#L182-L194
[fuzzing-docs]: https://docs.wasmtime.dev/contributing-fuzzing.html


<details>

To modify this label's message, edit the <code>.github/label-messager/wasmtime-config.md</code> file.

To add new label messages or remove existing label messages, edit the
<code>.github/label-messager.json</code> configuration file.

Learn more.

</details>

view this post on Zulip Wasmtime GitHub notifications bot (Feb 10 2026 at 08:38):

d-sonuga converted PR #12541 Add support for fine-grained operator costs to a draft.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 10 2026 at 08:38):

d-sonuga has marked PR #12541 as ready for review.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 10 2026 at 08:50):

d-sonuga updated PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 11 2026 at 16:05):

cfallin submitted PR review:

Thanks for this!

I was initially expecting a boxed function closure as part of the Config to query for cost on each Operator but the struct-of-costs approach has merit too -- at the very least, it should be faster. It also gives a nice uniformity between the custom and default cases (we just use our default table).

One high-level issue with this design is that if one ever needs more custom logic that depends on other context -- e.g., adjust the cost of a Call based on what the call target is -- then that is a reasonably straightforward extension with a closure (take another argument with context, or the operand arguments) but not for a table-driven approach. I guess this design must still satisfy your use-case, but I wonder if any others are out there that would need the more generic one?

Anyway, I'm happy to land this as-is if it works for you, modulo a few small comments below. Thanks!

view this post on Zulip Wasmtime GitHub notifications bot (Feb 11 2026 at 16:06):

cfallin created PR review comment:

It's too bad that we don't have lower-case variants of the opcode names available in for_each_operator! (we do have the visit_* forms with lowercased names but not the bare opcodes)

I'm a little uncomfortable with the non-idiomatic camelcasing on struct field names here but maybe it's ok to avoid a wasmparser change. cc @alexcrichton for thoughts on this...

view this post on Zulip Wasmtime GitHub notifications bot (Feb 11 2026 at 16:06):

cfallin created PR review comment:

I see the value in the detailed error message here but it also seems like a bit too much custom macro use, which we generally try to minimize -- could we instead derive Eq on the OperatorCost struct and do a simple structural comparison? Embedders who use this feature can separately print the OperatorCosts in their compilation and execution environments and debug the difference if needed, I think.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 11 2026 at 17:51):

d-sonuga updated PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 11 2026 at 19:15):

alexcrichton submitted PR review:

w.r.t. table-vs-closure, one thought I'd have is that the table approach here is very large at runtime. With 627 opcodes currently and with 8-bytes-per-opcode here that's 5016 bytes for a structure that's an optional feature to move around and manage. That's not the end of the world per se, but it's something I think is worth considering as this is a costly data structure to manage.

This also has the penalty of being serialized into all Wasmtime artifacts, meaning that all *.cwasms would have this table baked in by-default even if it's not actually used.

An upside of tables over closures, however, is that this is more easily serializable. Right now this isn't hooked up to the CLI, but this sort of leaves the door open for eventually doing that.

that is a reasonably straightforward extension with a closure (take another argument with context, or the operand arguments) but not for a table-driven approach

Another possible thing to consider here would be something like memory.copy. The fuel-based cost of that opcode ideally would account for the size of the copy as opposed to just having a static cost for the opcode.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 11 2026 at 19:15):

alexcrichton created PR review comment:

I'm a bit concerned with i64 here as it's a very large value per-opcode (8 bytes per opcode) plus it raises the question of what to do about negative numbers (e.g. should we support negative costs of opcodes?). Could u8 be used here instead?

view this post on Zulip Wasmtime GitHub notifications bot (Feb 11 2026 at 19:15):

alexcrichton created PR review comment:

This is a pretty massive struct which would make this structure I think kilobytes large, so perhaps this could be an Option<Box<OperatorCost>> to reduce its footprint?

view this post on Zulip Wasmtime GitHub notifications bot (Feb 11 2026 at 19:15):

alexcrichton created PR review comment:

Yeah there's unfortunately no easy way to get a snake_case version of the fields from the macro currently. I'd say that's generally fine assuming the struct-based approach is chosen (vs a function-based approach)

view this post on Zulip Wasmtime GitHub notifications bot (Feb 12 2026 at 08:58):

d-sonuga commented on PR #12541:

Maybe we can have both table & closure approaches: there can be two config options: static_operator_cost which takes the OperatorCost table and dynamic_operator_cost which takes the operator + whatever context may be needed.

So, it can be up to the user to decide which one fits their purpose - if the table based approach is enough, they can simply use that or if they need more flexibility, they can use the dynamic one. Then internally, the operator cost used can be an enumeration:

enum OperatorCostStrategy {
    Static(Box<OperatorCost>)
    Dynamic(Box<dyn Fn(&Operator, ctx type) -> u8>)
    Default
}

view this post on Zulip Wasmtime GitHub notifications bot (Feb 16 2026 at 08:30):

d-sonuga updated PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 16 2026 at 09:03):

d-sonuga updated PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 16 2026 at 09:22):

d-sonuga requested cfallin for a review on PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 16 2026 at 09:22):

d-sonuga requested alexcrichton for a review on PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 18 2026 at 23:23):

alexcrichton commented on PR #12541:

Personally I'd say that the current state of the PR is the local maxima to aim for. I think that'll have a reasonable cost when using it and when not using it, and it also doesn't require too much refactoring at this time. A closure-based approach will be tricky from a serializable point of view, but I think it's reasonable to try to cover that later as necessary.

@d-sonuga looks like a merge conflict has snuck in, if you wouldn't mind rebasing I can add this to the merge queue (assuming you don't have anything else you'd like to see @cfallin)

view this post on Zulip Wasmtime GitHub notifications bot (Feb 18 2026 at 23:25):

cfallin commented on PR #12541:

Ah, sorry, I lost track of this one; yes, I'm happy with the current state too. Thanks!

view this post on Zulip Wasmtime GitHub notifications bot (Feb 18 2026 at 23:25):

cfallin submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 19 2026 at 06:07):

d-sonuga updated PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 19 2026 at 06:11):

cfallin has enabled auto merge for PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 19 2026 at 06:15):

cfallin has disabled auto merge for PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 19 2026 at 06:15):

d-sonuga updated PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 19 2026 at 06:21):

cfallin commented on PR #12541:

@d-sonuga I put your updated prior commit (17597cb) on the merge queue but your subsequent force-push overrode that and canceled the merge. Could you let us know when you're ready for final review and merge?

view this post on Zulip Wasmtime GitHub notifications bot (Feb 19 2026 at 06:24):

d-sonuga commented on PR #12541:

I just rebased to remove the conflict and fix a doc comment.
It's ready for the final review and merge now.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 19 2026 at 06:30):

cfallin submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 19 2026 at 06:30):

cfallin added PR #12541 Add support for fine-grained operator costs to the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 19 2026 at 06:54):

github-merge-queue[bot] removed PR #12541 Add support for fine-grained operator costs from the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 19 2026 at 07:36):

d-sonuga updated PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 19 2026 at 07:38):

d-sonuga commented on PR #12541:

@cfallin, just pushed again to fix the Miri test fail.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 19 2026 at 19:37):

alexcrichton added PR #12541 Add support for fine-grained operator costs to the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 19 2026 at 20:02):

alexcrichton merged PR #12541.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 19 2026 at 20:02):

alexcrichton removed PR #12541 Add support for fine-grained operator costs from the merge queue.


Last updated: Feb 24 2026 at 04:36 UTC