Skip to content
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() doesn't optimize out stack usage #58570

Closed
upsuper opened this issue Feb 19, 2019 · 3 comments
Closed

Box::new() doesn't optimize out stack usage #58570

upsuper opened this issue Feb 19, 2019 · 3 comments

Comments

@upsuper
Copy link
Contributor

upsuper commented Feb 19, 2019

If you feed the compiler with the following code:

#![feature(box_syntax)]

pub fn foo() -> Box<[i32; 1_000_000]> {
    box [0; 1_000_000]
}

pub fn bar() -> Box<[i32; 1_000_000]> {
    Box::new([0; 1_000_000])
}

The compiler would output (from playground) in release mode:

playground::foo: # @playground::foo
# %bb.0:
	pushq	%rbx
	movl	$4000000, %edi          # imm = 0x3D0900
	movl	$4, %esi
	callq	*__rust_alloc@GOTPCREL(%rip)
	testq	%rax, %rax
	je	.LBB0_1
# %bb.2:
	movq	%rax, %rbx
	movl	$4000000, %edx          # imm = 0x3D0900
	movq	%rax, %rdi
	xorl	%esi, %esi
	callq	*memset@GOTPCREL(%rip)
	movq	%rbx, %rax
	popq	%rbx
	retq

.LBB0_1:
	movl	$4000000, %edi          # imm = 0x3D0900
	movl	$4, %esi
	callq	*alloc::alloc::handle_alloc_error@GOTPCREL(%rip)
	ud2
                                        # -- End function

playground::bar: # @playground::bar
# %bb.0:
	pushq	%rbx
	movl	$4000000, %eax          # imm = 0x3D0900
	callq	__rust_probestack
	subq	%rax, %rsp
	movq	%rsp, %rdi
	movl	$4000000, %edx          # imm = 0x3D0900
	xorl	%esi, %esi
	callq	*memset@GOTPCREL(%rip)
	movl	$4000000, %edi          # imm = 0x3D0900
	movl	$4, %esi
	callq	*__rust_alloc@GOTPCREL(%rip)
	testq	%rax, %rax
	je	.LBB1_1
# %bb.2:
	movq	%rax, %rbx
	movq	%rsp, %rsi
	movl	$4000000, %edx          # imm = 0x3D0900
	movq	%rax, %rdi
	callq	*memcpy@GOTPCREL(%rip)
	movq	%rbx, %rax
	addq	$4000000, %rsp          # imm = 0x3D0900
	popq	%rbx
	retq

.LBB1_1:
	movl	$4000000, %edi          # imm = 0x3D0900
	movl	$4, %esi
	callq	*alloc::alloc::handle_alloc_error@GOTPCREL(%rip)
	ud2
                                        # -- End function

It can be seen clearly that foo does the allocation first and then runs memset, while bar clearly runs the memset before allocation, and it then memcpy the content into the box.

This is not very optimal. Users should be able to expect Box::new() to have no stack allocation.

It seems that Box::new() is implemented via box-syntax, and it even has #[inline(always)], so they shouldn't really have any difference here...

@pnkfelix
Copy link
Member

cc #53827 #49733 #28008

@upsuper
Copy link
Contributor Author

upsuper commented Feb 19, 2019

It's probably just a duplicate of #53827.

@nagisa nagisa closed this as completed Feb 19, 2019
@nagisa
Copy link
Member

nagisa commented Feb 19, 2019

Closing as a duplicate.

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

No branches or pull requests

3 participants