Skip to content

Preserve the allocator in From<SmallVec> for Box<[T], A> - #732

Open
HarshRajSinghania wants to merge 1 commit into
servo:v2from
HarshRajSinghania:fix-box-allocator-conversion
Open

HarshRajSinghania wants to merge 1 commit into
servo:v2from
HarshRajSinghania:fix-box-allocator-conversion

Conversation

@HarshRajSinghania

Copy link
Copy Markdown

Summary

From<SmallVec<T, N, A>> for Box<[T]> rebuilt the box through Vec, which always uses the global allocator. With the allocator API enabled, the conversion is now From<SmallVec<T, N, A>> for Box<[T], A> and releases spilled storage with the same allocator.

Motivation

Requested in #714. The previous impl changed the allocator before boxing, and used an intermediary Vec.

Implementation

  • Without allocator-api, Box is still Box<[T]> and the existing Vec path remains.
  • With allocator-api / allocator-api2, elements are copied into Box::new_uninit_slice_in owned by A. If the SmallVec had spilled, the old heap buffer is deallocated with A.
  • into_boxed_slice still returns a global Box<[T]> via Vec, so the deprecated helper keeps its signature.

Testing

  • cargo +nightly test --tests — 74 passed
  • cargo +nightly test --features allocator-api --test main into_box_from_inline_and_spilled — passed
  • cargo +nightly test --features allocator-api2 --test main into_box_from_inline_and_spilled — passed
  • cargo +nightly test --features allocator-api2 --tests — 74 passed

Fixes #714

The previous conversion rebuilt the box through Vec, which always uses the
global allocator. With the allocator API enabled, convert into Box<[T], A>
and release spilled storage with the same allocator.

Fixes servo#714

Signed-off-by: Harsh Raj Singhania <harshrajsinghania@proton.me>
Comment thread src/conversions.rs

let mut boxed = Box::<[MaybeUninit<T>], A>::new_uninit_slice_in(length, allocator);
unsafe {
copy_nonoverlapping(source, boxed.as_mut_ptr().cast(), length);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This copy/realloc can be avoided if on_heap && length == capacity. In that case, this whole function could just be Vec::from(this).into_boxed_slice() again (once I finish implementing #702).

@alejandro-vaz alejandro-vaz Oct 4, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but we can remove the intermediate Vec conversion

why would we want it there

I'm not sure but probably our desired behavior is to always have it on the heap when converting it from a box

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but we can remove the intermediate Vec conversion

Is there any overhead to that conversion? It seems like that would do the exact same things that a manual implementation would do.

I'm not sure but probably our desired behavior is to always have it on the heap when converting it from a box

This is converting to a box, not from.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, sorry

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any overhead to that conversion? It seems like that would do the exact same things that a manual implementation would do.

yeah it's basically the same now that I think about it

after optimizations it probably compiles to the same thing

@alejandro-vaz

Copy link
Copy Markdown
Collaborator

why is this 100 LOC

it shouldn't be that big

@alejandro-vaz alejandro-vaz left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah... but this looks overengineered at best

@alejandro-vaz

Copy link
Copy Markdown
Collaborator

oh the issue is that #702 is pending I see

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.

correct From<SmallVec<T, N, A>> for Box<[T]> implementation

3 participants