-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Box::new(expr) first puts expr on the stack, then copies. #50047
Comments
1.12.0 was the release that added MIR: "rustc translates code to LLVM IR via its own "middle" IR (MIR)", which seems like the mostly likely cause from that release. |
The corresponding MIR:
|
Can we add a trick to HAIR that treats |
Related: pub fn bar(buf: [u8; 4096]) -> Box<[u8; 4096]> {
Box::new(buf)
} copies buf to the local stack before copying it in the box: example::bar:
push rbx
mov eax, 4096
call __rust_probestack
sub rsp, rax
mov rax, rdi
mov rdi, rsp
mov edx, 4096
mov rsi, rax
call memcpy@PLT
mov edi, 4096
mov esi, 1
call __rust_alloc@PLT
mov rbx, rax
test rbx, rbx
je .LBB2_1
mov rsi, rsp
mov edx, 4096
mov rdi, rbx
call memcpy@PLT
mov rax, rbx
add rsp, 4096
pop rbx
ret
.LBB2_1:
call <alloc::alloc::Global as core::alloc::GlobalAlloc>::oom
ud2 |
So, one interesting fact, it doesn't happen when the object is small enough: pub fn foo() -> Box<[u8; 8]> {
Box::new([0; 8])
}
pub fn bar() -> Box<[u8; 9]> {
Box::new([0; 9])
} example::foo:
push rax
mov edi, 8
mov esi, 1
call __rust_alloc@PLT
test rax, rax
je .LBB1_1
mov qword ptr [rax], 0
pop rcx
ret
.LBB1_1:
call <alloc::alloc::Global as core::alloc::GlobalAlloc>::oom
ud2
example::bar:
sub rsp, 24
mov byte ptr [rsp + 16], 0
mov qword ptr [rsp + 8], 0
mov edi, 9
mov esi, 1
call __rust_alloc@PLT
test rax, rax
je .LBB2_1
mov cl, byte ptr [rsp + 16]
mov byte ptr [rax + 8], cl
mov rcx, qword ptr [rsp + 8]
mov qword ptr [rax], rcx
add rsp, 24
ret
.LBB2_1:
call <alloc::alloc::Global as core::alloc::GlobalAlloc>::oom
ud2 The MIR in both cases looks similar, but the LLVM-IR differs:
|
Related (or dup?) of #41160 |
Yeah, this seems like the same issue as #41160; closing. |
Consider the following code:
(made it big because it's kind of simpler to see the memset and memcpy calls in the resulting asm)
It generates the following assembly:
which does a memset, alloc, memcpy dance.
I was accepting this as a fact of life, but today, I was looking at a random old version of rustc on godbolt, and it turns out before 1.12, the memset, alloc, memcpy dance wasn't happening:
https://godbolt.org/g/J3cy5E
The llvm ir back then looks like the following:
while on nightly, it looks like:
The text was updated successfully, but these errors were encountered: