peterhuene opened PR #2736 from limiter to main:
This PR adds a
ResourceLimitertrait to the Wasmtime API.When used in conjunction with
Store::new_with_limiter, this can be used to
monitor and prevent WebAssembly code from growing linear memories and tables.This is particularly useful when hosts need to take into account host resource
usage to determine if WebAssembly code can consume more resources.A simple
StaticResourceLimiteris also included with these changes that will
simply limit the size of linear memories or tables for all instances created in
the store based on static values.
peterhuene requested pchickey for a review on PR #2736.
peterhuene updated PR #2736 from limiter to main.
peterhuene updated PR #2736 from limiter to main.
peterhuene updated PR #2736 from limiter to main.
peterhuene updated PR #2736 from limiter to main.
alexcrichton submitted PR Review.
alexcrichton created PR Review Comment:
If this ends up being stored in individual tables/memories then this could probably turn into
&'a Arc<dyn ...>
alexcrichton created PR Review Comment:
To make sure I understand this right, if any
maximumis in play then this field is set to the minimum of all those maximums? The sources ofmaximumare:
- The actual wasm type itself
- The pooling allocator's configured maximum
- A custom implementation of
RuntimeMemoryhas a configured maximumIf my understanding is right, could this be clarified a bit? Basically
Noneis only returned if literally nothing is limiting the memory growth, but otherwiseSomedoesn't imply that the wasm type itself had a maximum listed, just that something else somewhere is placing a constraint.Also, presumably, this function isn't called unless
desiredis already known to be less thanmaximum, right? (or is it called even in those cases?)
alexcrichton created PR Review Comment:
Would it be possible to store the
limiterinto theMemoryitself rather than in theInstance?
alexcrichton created PR Review Comment:
Could the docs here clarify that this is about the runtime limit maximum of the memory, not the maximum size as prescribed by the type in wasm?
alexcrichton submitted PR Review.
alexcrichton created PR Review Comment:
This structure looks ripe for expansion to limiting other resources in the future, so perhaps this could use a builder-api pattern to avoid future API breakage?
alexcrichton created PR Review Comment:
I think this needs to be specified? Otherwise are memories created via
Memory::new(or tables) limited via the limiter?
alexcrichton created PR Review Comment:
It looks like this value doesn't change over time, so I don't think it needs to be backed by a
RefCell?
alexcrichton created PR Review Comment:
To avoid double-allocations and double-indirection could
ResourceLimiterProxyhave a type variable perhaps?
peterhuene submitted PR Review.
peterhuene created PR Review Comment:
Your understanding is correct and I can expand upon it in the docs for clarity.
The function is called even when desired exceeds the maximum as some implementers will want to know when the maximum was reached even if it was not directly limited by the limiter.
If that feels a little strange, perhaps a different function with the intention that it is only called when the memory couldn't grow due to it exceeding the maximum (from wasm / pooling allocator / custom runtime memory)?
peterhuene submitted PR Review.
peterhuene created PR Review Comment:
Good idea. I'll implement a builder.
peterhuene submitted PR Review.
peterhuene created PR Review Comment:
Good point. I'll fix.
peterhuene submitted PR Review.
peterhuene created PR Review Comment:
It currently does as it needs to sit on
innerwhich is behindRcand there's a circular reference between the proxy and theStore, which is why there is ugliness inStore::new_with_limiterto set this thing.I'm not happy about it at all, so if there's a better way to do this such that the limiter can pass the store along in the callbacks, I'm definitely open to it.
peterhuene edited PR Review Comment.
peterhuene submitted PR Review.
peterhuene created PR Review Comment:
I will expand these docs.
peterhuene submitted PR Review.
peterhuene created PR Review Comment:
Can do.
peterhuene submitted PR Review.
peterhuene created PR Review Comment:
I'll change this, no reason to clone it for the request until a memory / table needs it.
alexcrichton submitted PR Review.
alexcrichton created PR Review Comment:
Ah ok nah I think for now this is fine. It runs a possible risk of making it difficult to optimize
memory.growortable.growin the future but I don't think that's going to be the bottleneck of anything for a long time.
peterhuene edited PR #2736 from limiter to main:
This PR adds a
ResourceLimitertrait to the Wasmtime API.When used in conjunction with
Store::new_with_limiter, this can be used to
monitor and prevent WebAssembly code from growing linear memories and tables.This is particularly useful when hosts need to take into account host resource
usage to determine if WebAssembly code can consume more resources.A simple
Limiteris also included with these changes that will
simply limit the size of linear memories or tables for all instances created in
the store based on static values.
peterhuene updated PR #2736 from limiter to main.
peterhuene updated PR #2736 from limiter to main.
peterhuene updated PR #2736 from limiter to main.
peterhuene has marked PR #2736 as ready for review.
peterhuene requested alexcrichton and pchickey for a review on PR #2736.
alexcrichton submitted PR Review.
alexcrichton created PR Review Comment:
Arcis used here but I thinkRcmay suffice? (I didn't see any location that seemed to require thread-safety here)
alexcrichton created PR Review Comment:
One alternative design perhaps is that the
Storeisn't passed as an argument here and users manuallyRefCellandWeakthemselves with theStore. Do you think, though, that this will be commonly desired such that we may as well go ahead and expose it?
alexcrichton submitted PR Review.
alexcrichton created PR Review Comment:
Hm ok, I had a question above about the
Storeargument and whether we can possibly remove that, but also here do you think it would make sense to remove theOptionto effectively always have a limiting strategy?
alexcrichton created PR Review Comment:
Could the tests here be expanded with tests where the initial memory/table size exceed the maximum? Additionally API requests like
Memory::newandTable::newshould fail as well if they exceed the maximum? (ideally also tests where API-created objects will also fail togrowpast the maximum)
peterhuene submitted PR Review.
peterhuene created PR Review Comment:
Okay, getting back to this PR: I guess we don't have to expose the
Storeand let them capture whatever context they want since it's a custom implementation anyway.I'll remove the
Storeparameter and that'll simplify things a bit.
peterhuene submitted PR Review.
peterhuene created PR Review Comment:
The limiter needs to be an
Optionin the runtime for both table and memory so that the pooling allocator is able to "take" the memory/table when deallocating the instance (swaps inNone).I don't think having it also
OptioninStoremakes it that much worse and it does have the benefit of not boxing a new trait object every time aStoreis created just to returntrueon memory/table grow operations.If you're okay with it, I'd like to leave this one as-is.
peterhuene edited PR Review Comment.
peterhuene updated PR #2736 from limiter to main.
peterhuene requested alexcrichton and pchickey for a review on PR #2736.
peterhuene updated PR #2736 from limiter to main.
alexcrichton submitted PR Review.
alexcrichton submitted PR Review.
alexcrichton created PR Review Comment:
To confirm, are there tests for this? It seems a bit fishy that we're deallocating a half-initialized instance without many modifications below. I'd expect, for example
decommit_memory_pagesto fail one one way or another if called on an othewise unmapped region?
alexcrichton created PR Review Comment:
I suppose one other possible option is to store
*mut dyn ResourceLimiterin the*mut VMContextso we can useBoxhere instead ofRc, but let's only do that if the need actually arises.
alexcrichton created PR Review Comment:
Could the documentation here be expanded to indicate that the created
Storehas no limits on usage of memory and such in wasm modules?
alexcrichton created PR Review Comment:
Could this link to the
new_with_limitsAPI?
alexcrichton created PR Review Comment:
Could the documentation here link to the
ResourceLimitertrait which discussed which limits can be configured?
alexcrichton created PR Review Comment:
Oh also, could this link to
StoreLimitsandStoreLimitsBuilderfor a built-in way to limit resources?
peterhuene submitted PR Review.
peterhuene created PR Review Comment:
The
test_pooling_allocator_initial_limits_exceededtest does cover this, albeit with empty memory/table lists ondeallocate, as that test is what caught the problem: with an instance limit of 1, it failed to allocate any more instances because it wasn't being added back to the free list. I will add another memory to the module definition such that the list of initialized memories isn't empty, just in case.While the instance isn't completely initialized, it should be safe to call
deallocateon it as we iterate back through only initializedMemoryandTableto calldecommit_memory_pageson pages that were either made accessible (forMemory) or explicitly committed (forTable) prior to inserting into those lists.
peterhuene updated PR #2736 from limiter to main.
peterhuene submitted PR Review.
peterhuene created PR Review Comment:
:+1: I'm going to leave this as-is and we can revisit in the the future if needed.
alexcrichton submitted PR Review.
alexcrichton merged PR #2736.
Last updated: Dec 13 2025 at 19:03 UTC