-
Notifications
You must be signed in to change notification settings - Fork 286
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
Support for ResourceLimiter
API
#737
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
ResourceLimiter
API
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
BENCHMARKS
|
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
Codecov Report
@@ Coverage Diff @@
## master #737 +/- ##
==========================================
+ Coverage 79.08% 79.25% +0.16%
==========================================
Files 102 104 +2
Lines 8755 9046 +291
==========================================
+ Hits 6924 7169 +245
- Misses 1831 1877 +46
... and 9 files with indirect coverage changes 📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
I tried something different. Just a hunch, but it seemed weird to me that it was doing all that spilling and reloading, when it should store the struct in registers -- one of LLVM's most important passes is "SROA" (scalar replacement of aggregates) where it "scalarizes" the individual fields of structs, breaking them into separate values -- which is how Executor's fields all wind up in registers. I hypothesized that the new reference was pushing the
I'll wait for the benchmark bot to run, but on my workstation it seems to solve the problem. We'll see! |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
I believe I've addressed all the remaining comments and CI failures and this is ready to go now. |
ResourceLimiter
APIResourceLimiter
API
Closes #728.
This implements the
wasmtime
ResourceLimiter
API, as discussed in bug #728 .Current limitations, caveats and points to discuss/review:
Missing testsMissing docsMissing convenience typesStoreLimits
andStoreLimitsBuilder
#[derive(Debug)]
working I had to add a couple wrapper types.As much as possible, I tried to trackwasmtime
's implementation: the{instance,memory,table}_{count,limit}
fields, theStore::bump_resource_counts
method, thelimits.rs
file, the global defaults returned from the default methods, etc. etc. This all feels like a fairly weird design to me (information cached or returned from multiple places) but I figured you'd prefer to follow along their lead rather than make something gratuitously incompatible. Any deviations (see following points) were forced by differences betweenwasmtime
andwasmi
.wasmi
does not thread the full typedStore<T>
into its executor context, onlyStoreInner
, it's not possible to call the typedFnMut(&mut T) -> &mut dyn ResourceLimiter
query API onStoreInner
(it has nodata: T
element to pass as an argument) so I had to hoist the query up the call stack to caller sites that still have aStore<T>
and then pass through a newResourceLimiterRef
type carrying the resulting ref. This seems to work but it's a bit ugly. The other options (refactoringStore
and/orExecutor
) seemed worse.wasmtime
just usesanyhow::Error
everywhere, sowasmi
's specific error types all deviate. I did not do a lot of careful design work on the errors, I just reused those that already seemed to cover the cases and added new ones where necessary. They could theoretically be reorganized or refactored -- I don't care how they're represented at all, happy to do whatever you prefer.wasmtime
ResourceLimiter
API actually seems .. fairly bad? I mean, it operates in terms of bytes (weird) and has the option of both returning anErr(...)
-which-means-trap (which I didn't even try to support) and returningOk(false)
-which-means-return-your-own-error. I am not sure how best to map its seemingly-bad-API-choices ontowasmi
, I did my best.ResourceLimiter
wants to be called both before any inherent checks and after any error occurs (including those resulting from inherent checks) I had to refactor the arithmetic in the memory and table growth functions, and repeat some code between initialization and growth. I believe I kept the logic the same. I might be able to factor some of this more, but it seems like diminishing returns.Anyway, all that aside I think this holds together. Feedback welcome!