fitzgen opened PR #12441 from fitzgen:more-oom-handling-boxed-slice-ctors to bytecodealliance:main:
Part of https://github.com/bytecodealliance/wasmtime/issues/12069
<!--
Please make sure you include the following information:
If this work has been discussed elsewhere, please include a link to that
conversation. If it was discussed in an issue, just mention "issue #...".Explain why this change is needed. If the details are in an issue already,
this can be brief.Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.htmlPlease ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->
fitzgen requested cfallin for a review on PR #12441.
fitzgen requested wasmtime-compiler-reviewers for a review on PR #12441.
fitzgen requested pchickey for a review on PR #12441.
fitzgen requested wasmtime-core-reviewers for a review on PR #12441.
fitzgen updated PR #12441.
github-actions[bot] added the label cranelift on PR #12441.
alexcrichton submitted PR review:
Another possible idea:
- One function to return
fn(usize) -> Result<Box<[MaybeUninit<T>]>>- Another function
fn(Iterator<T>, Box<[MaybeUninit<T>]>) -> Result<Box<[T]>>- Another function for a fallible iterator
- Helper functions combining these together
alexcrichton created PR review comment:
Once this goes down the route of
double/shrink/realloc, would it be better to useVecdirectly?Or, alternatively, could the
Result-based fallible-collection-version take anExactSizeIteratorto avoid resizing?
fitzgen submitted PR review.
fitzgen created PR review comment:
Once this goes down the route of
double/shrink/realloc, would it be better to useVecdirectly?I considered this, but we would still need some raw pointer handling for the
shrink_to_fitoperation, since there isn't a fallible way to do that withstd::vec::Vec. And deconstructing and reconstructing astd::vec::Vecfelt even more sketchy than what we have here.Or, alternatively, could the
Result-based fallible-collection-version take anExactSizeIteratorto avoid resizing?Unfortunately we have code that needs to call these methods but which doesn't have an
ExactSizeIterator, so we can't replace all these methods with that. Basically, we really do need all the different variants in different places.
alexcrichton submitted PR review.
alexcrichton created PR review comment:
To me I would naively weigh this implementation as "a greater evil" than assuming
shrink_to_fitis infallible. I understand thatshrink_to_fitis technically fallible but it's hard to imagine how any realistic allocator would do anything other than succeed at shrinking the allocation. I think I'd almost prefer to make that gamble than to half-build our own customVecinternally.
fitzgen commented on PR #12441:
Another possible idea:
* One function to return `fn(usize) -> Result<Box<[MaybeUninit<T>]>>` * Another function `fn(Iterator<T>, Box<[MaybeUninit<T>]>) -> Result<Box<[T]>>` * Another function for a fallible iterator * Helper functions combining these togetherThis is sort of what we have, except we don't expose the second function publicly, just as an implementation detail.
What these proposed functions don't collectively cover, however, is when you have an unknown-length iterator, unless I am misunderstanding.
fitzgen edited a comment on PR #12441:
Another possible idea:
One function to return
fn(usize) -> Result<Box<[MaybeUninit<T>]>>Another function
fn(Iterator<T>, Box<[MaybeUninit<T>]>) -> Result<Box<[T]>>Another function for a fallible iterator
Helper functions combining these together
This is sort of what we have, except we don't expose the second function publicly, just as an implementation detail.
What these proposed functions don't collectively cover, however, is when you have an unknown-length iterator, unless I am misunderstanding.
fitzgen submitted PR review.
fitzgen created PR review comment:
I understand that
shrink_to_fitis technically fallible but it's hard to imagine how any realistic allocator would do anything other than succeed at shrinking the allocation.If the allocation can't be shrunk in place (e.g. due to size classes) then it must allocate a new block of memory and copy the contents of the old block over. That allocation, despite being smaller than the existing one, can certainly fail.
I think I'd almost prefer to make that gamble than to half-build our own custom
Vecinternally.I can refactor this to build on top of https://github.com/bytecodealliance/wasmtime/pull/12440 and do some unsafe bits to fallibly shrink in place.
alexcrichton submitted PR review.
alexcrichton created PR review comment:
Also, technically, like
Boxwe can convert aVec<T>to its raw parts and callreallocmanually to handle the edge case it returns null? (and return oom)
fitzgen submitted PR review.
fitzgen created PR review comment:
Also, technically, like
Boxwe can convert aVec<T>to its raw parts and callreallocmanually to handle the edge case it returns null? (and return oom)Yeah this is the "unsafe bits to fallibly shrink in place" stuff
fitzgen edited PR review comment.
fitzgen edited PR review comment.
alexcrichton submitted PR review.
alexcrichton created PR review comment:
Oh sorry yeah I think we raced to the same realization, but yeah building this on
Vecwith a custom hand-writtenshrink_to_fitsounds good to me :+1:
fitzgen submitted PR review.
fitzgen created PR review comment:
I haven't done this change yet, but it will require https://github.com/bytecodealliance/wasmtime/pull/12448 to land first.
fitzgen updated PR #12441.
fitzgen commented on PR #12441:
Okay the boxed slice helpers are now implemented on top of our OOM-handling
Vecand this PR now depends on https://github.com/bytecodealliance/wasmtime/pull/12452 (and therefore also https://github.com/bytecodealliance/wasmtime/pull/12448)
fitzgen requested alexcrichton for a review on PR #12441.
fitzgen updated PR #12441.
cfallin submitted PR review:
This looks correct to me; I think my main question (in addition to the one naming thought below) is why we need to define an error case
TooFewItems. I suppose I'm not seeing the callsite(s) here but naively I would expect, given that we've implemented theshrink_to_fitlogic, we could always use that if an iterator returns fewer items than expected; do we have cases where we want to guard against that (reallocation) wastefulness and flag a logic error instead?
cfallin created PR review comment:
The name
DropGuardis throwing me off a bit -- yes it exists to drop theVec<T>but usually (in my experience) a drop-guard is a thing that just handles drops (whether via explicit/customimpl Dropor not), nothing else, while the drop here is incidental (it owns theVecso everything cleans up as expected) and the real meat is in the other logic. The "cleans up already-initialized elements" suggests something like aMaybeUninitsomewhere but that's not the case either. MaybeBoxedSliceBuilderor something?
fitzgen commented on PR #12441:
do we have cases where we want to guard against that (reallocation) wastefulness and flag a logic error instead?
Basically, yes. We have call sites that know the exact length of various things but which also do not have
ExactSizeIterators for Reasons.
fitzgen updated PR #12441.
fitzgen submitted PR review.
fitzgen created PR review comment:
Done in f9076a506c
fitzgen has enabled auto merge for PR #12441.
fitzgen updated PR #12441.
fitzgen updated PR #12441.
fitzgen added PR #12441 Add some more OOM-handling Box<[T]> constructor variants to the merge queue.
github-merge-queue[bot] removed PR #12441 Add some more OOM-handling Box<[T]> constructor variants from the merge queue.
fitzgen added PR #12441 Add some more OOM-handling Box<[T]> constructor variants to the merge queue.
fitzgen merged PR #12441.
fitzgen removed PR #12441 Add some more OOM-handling Box<[T]> constructor variants from the merge queue.
Last updated: Jan 29 2026 at 13:25 UTC