Description
Proposal
Introduce a new Rvalue
variant, Rvalue::ShallowInitBox
. It accepts an operand and a type, and will convert the operand to a shallowly-initialized box. This design is considered the better approach than a Box
terminator after the Zulip dicussion.
In today's the MIR, box expr
is translated to:
let _1: Box<ty>;
_1 = Box(ty);
(*_1) = expr;
however this does not allow unwind. Unwinding is necessary for rust-lang/rfcs#2116's oom=panic
support (tracked in rust-lang/rust#43596).
Under this proposal, the originally Rvalue::NullaryOp(NullOp::Box, ty)
is split into two operations, first a call to exchange_malloc(size_of::<ty>(), align_of::<ty>())
, then converts it into a shallow-initialized box:
let _1: *mut u8;
let _2: Box<ty>;
bb0: {
_1 = exchange_malloc(SizeOf(ty), AlignOf(ty)) -> [return: bb1, unwind: bb2];
}
bb1: {
_2 = ShallowInitBox(move _1, ty);
(*_2) = expr;
}
with the extra unwinding edge provided by the exchange_malloc
call.
The operational behaviour of ShallowInitBox
is simply transmuting *mut u8
to Box<T>
. The only thing special is that dataflow analysis will treat the content of the box as uninitialized.
An alternative is to remove box_syntax
and Box
nullary op from MIR at all; however, an attempt in rust-lang/rust#87781 shows very significant regression when doing so (perf run). Here is an godbolt snippet shows a case where box
still needs special treatment in the MIR, and thus box_syntax
is still needed at least as an implementation detail of the library.
Another alternative is the original proposal, to add a TerminatorKind::Box
. However adding a new terminator requires much more changes than the current proposal.
The original proposal
Introduce a new terminator, TerminatorKind::Box
to the MIR of form:
_1 = Box(ty) -> [return: bb1, unwind: bb2];
it'll be roughly equivalent to
_1 = Box(ty) // Nullary op Box here
goto -> bb1
in today's MIR, but has an additional unwind edge.
Box
needs to be a special terminator rather than a function call, because a function call will deep-initialize the return place while Box
will only shallow-initialize its return place.
The overall plan is:
- Introduce
TerminatorKind::Box
- Benchmark performance difference from using
Box
terminator vsBox
nullary op - If performance is reasonable, switch
box_syntax
to useBox
terminator instead ofBox
nullary op - Remove
Box
as a nullary op.
Mentors or Reviewers
If you have a reviewer or mentor in mind for this work, mention then
here. You can put your own name here if you are planning to mentor the
work.
Process
The main points of the Major Change Process are as follows:
- File an issue describing the proposal.
- A compiler team member or contributor who is knowledgeable in the area can second by writing
@rustbot second
.- Finding a "second" suffices for internal changes. If however, you are proposing a new public-facing feature, such as a
-C flag
, then full team check-off is required. - Compiler team members can initiate a check-off via
@rfcbot fcp merge
on either the MCP or the PR.
- Finding a "second" suffices for internal changes. If however, you are proposing a new public-facing feature, such as a
- Once an MCP is seconded, the Final Comment Period begins. If no objections are raised after 10 days, the MCP is considered approved.
You can read more about Major Change Proposals on forge.
Comments
This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.