Skip to content

deserialization code leaves much to be desired #206

Closed
@jrmuizel

Description

@jrmuizel

The following rust code gives us a lot of per field overhead:

#[derive(Deserialize)]
pub struct P {
       x: u32,
       y: u32,
       z: u32,
       w: u32
}

pub fn moo(encoded: Vec<u8>) -> P {
    let mut s :&[u8] = &encoded;
    deserialize_from(&mut s, bincode::Infinite).unwrap()
}

I'd ideally want this to compile to some length checks and a single memcpy for all of the fields. Instead I get something that looks like a memcpy loop per field.

I suspect there are a number of things contributing to the problem here. The full assembly of moo follows:

	.globl	__ZN11serde_deser3moo17hd4391294d14f34bdE
	.p2align	4, 0x90
__ZN11serde_deser3moo17hd4391294d14f34bdE:
	.cfi_startproc
	pushq	%rbp
Lcfi16:
	.cfi_def_cfa_offset 16
Lcfi17:
	.cfi_offset %rbp, -16
	movq	%rsp, %rbp
Lcfi18:
	.cfi_def_cfa_register %rbp
	pushq	%r15
	pushq	%r14
	pushq	%r13
	pushq	%r12
	pushq	%rbx
	subq	$72, %rsp
Lcfi19:
	.cfi_offset %rbx, -56
Lcfi20:
	.cfi_offset %r12, -48
Lcfi21:
	.cfi_offset %r13, -40
Lcfi22:
	.cfi_offset %r14, -32
Lcfi23:
	.cfi_offset %r15, -24
	movq	%rdi, -112(%rbp)
	movq	(%rsi), %r15
	movq	8(%rsi), %rax
	movq	%rax, -104(%rbp)
	movq	16(%rsi), %r12
	leaq	-68(%rbp), %r13
	movl	$0, -68(%rbp)
	movl	$4, %ebx
	movq	%r15, -80(%rbp)
	.p2align	4, 0x90
LBB4_1:
	cmpq	%rbx, %r12
	movq	%r12, %r14
	cmovaeq	%rbx, %r14
	cmpq	$1, %r14
	jne	LBB4_3
	movzbl	(%r15), %eax
	movb	%al, (%r13)
	jmp	LBB4_4
	.p2align	4, 0x90
LBB4_3:
	movq	%r13, %rdi
	movq	%r15, %rsi
	movq	%r14, %rdx
	callq	_memcpy
	testq	%r14, %r14
	je	LBB4_23
LBB4_4:
	addq	%r14, %r15
	subq	%r14, %r12
	addq	%r14, %r13
	subq	%r14, %rbx
	jne	LBB4_1
	movl	-68(%rbp), %eax
	movl	%eax, -72(%rbp)
	leaq	-68(%rbp), %r13
	movl	$0, -68(%rbp)
	movl	$4, %r14d
	.p2align	4, 0x90
LBB4_6:
	cmpq	%r14, %r12
	movq	%r12, %rbx
	cmovaeq	%r14, %rbx
	cmpq	$1, %rbx
	jne	LBB4_8
	movzbl	(%r15), %eax
	movb	%al, (%r13)
	jmp	LBB4_9
	.p2align	4, 0x90
LBB4_8:
	movq	%r13, %rdi
	movq	%r15, %rsi
	movq	%rbx, %rdx
	callq	_memcpy
	testq	%rbx, %rbx
	je	LBB4_23
LBB4_9:
	addq	%rbx, %r15
	subq	%rbx, %r12
	addq	%rbx, %r13
	subq	%rbx, %r14
	jne	LBB4_6
	movl	-68(%rbp), %eax
	movq	%rax, -96(%rbp)
	leaq	-68(%rbp), %r13
	movl	$0, -68(%rbp)
	movl	$4, %r14d
	.p2align	4, 0x90
LBB4_11:
	cmpq	%r14, %r12
	movq	%r12, %rbx
	cmovaeq	%r14, %rbx
	cmpq	$1, %rbx
	jne	LBB4_13
	movzbl	(%r15), %eax
	movb	%al, (%r13)
	jmp	LBB4_14
	.p2align	4, 0x90
LBB4_13:
	movq	%r13, %rdi
	movq	%r15, %rsi
	movq	%rbx, %rdx
	callq	_memcpy
	testq	%rbx, %rbx
	je	LBB4_23
LBB4_14:
	addq	%rbx, %r15
	subq	%rbx, %r12
	addq	%rbx, %r13
	subq	%rbx, %r14
	jne	LBB4_11
	movl	-68(%rbp), %eax
	movq	%rax, -88(%rbp)
	leaq	-68(%rbp), %r13
	movl	$0, -68(%rbp)
	movl	$4, %r14d
	.p2align	4, 0x90
LBB4_16:
	cmpq	%r14, %r12
	movq	%r12, %rbx
	cmovaeq	%r14, %rbx
	cmpq	$1, %rbx
	jne	LBB4_18
	movzbl	(%r15), %eax
	movb	%al, (%r13)
	jmp	LBB4_19
	.p2align	4, 0x90
LBB4_18:
	movq	%r13, %rdi
	movq	%r15, %rsi
	movq	%rbx, %rdx
	callq	_memcpy
	testq	%rbx, %rbx
	je	LBB4_23
LBB4_19:
	addq	%rbx, %r15
	subq	%rbx, %r12
	addq	%rbx, %r13
	subq	%rbx, %r14
	jne	LBB4_16
	movl	-68(%rbp), %eax
	movq	-88(%rbp), %rcx
	movq	%rcx, %rdx
	shlq	$32, %rdx
	addq	-96(%rbp), %rdx
	movq	-112(%rbp), %rbx
	movl	-72(%rbp), %ecx
	movl	%ecx, (%rbx)
	movq	%rdx, 4(%rbx)
	movl	%eax, 12(%rbx)
	movq	-104(%rbp), %rsi
	testq	%rsi, %rsi
	je	LBB4_22
	movl	$1, %edx
	movq	-80(%rbp), %rdi
	callq	___rust_dealloc
LBB4_22:
	movq	%rbx, %rax
	addq	$72, %rsp
	popq	%rbx
	popq	%r12
	popq	%r13
	popq	%r14
	popq	%r15
	popq	%rbp
	retq
LBB4_23:
	leaq	_str.6(%rip), %rdi
	movl	$27, %esi
	callq	__ZN3std5error205_$LT$impl$u20$core..convert..From$LT$$RF$$u27$b$u20$str$GT$$u20$for$u20$alloc..boxed..Box$LT$std..error..Error$u20$$u2b$$u20$core..marker..Send$u20$$u2b$$u20$core..marker..Sync$u20$$u2b$$u20$$u27$a$GT$$GT$4from17h4799454266726278E
	movq	%rdx, %rcx
	leaq	-64(%rbp), %rdi
	movl	$17, %esi
	movq	%rax, %rdx
	callq	__ZN3std2io5error5Error4_new17h85c79fbf3c4b32d5E
	movb	-64(%rbp), %al
	movb	-57(%rbp), %cl
	movb	%cl, -42(%rbp)
	movzwl	-59(%rbp), %ecx
	movw	%cx, -44(%rbp)
	movl	-63(%rbp), %ecx
	movl	%ecx, -48(%rbp)
	movq	-56(%rbp), %rcx
	movb	%al, -64(%rbp)
	movb	-42(%rbp), %al
	movb	%al, -57(%rbp)
	movzwl	-44(%rbp), %eax
	movw	%ax, -59(%rbp)
	movl	-48(%rbp), %eax
	movl	%eax, -63(%rbp)
	movq	%rcx, -56(%rbp)
	leaq	-64(%rbp), %rdi
	callq	__ZN7bincode8internal132_$LT$impl$u20$core..convert..From$LT$std..io..error..Error$GT$$u20$for$u20$alloc..boxed..Box$LT$bincode..internal..ErrorKind$GT$$GT$4from17hcfbfdc14cc272f8bE
	movq	%rax, %rdi
	callq	__ZN4core6result13unwrap_failed17h7caf794916bf7f7dE
	.cfi_endproc

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions