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

Guarantee trivial copy constructor and destructor for Str and Slice #387

Merged
merged 1 commit into from
Oct 31, 2020

Conversation

dtolnay
Copy link
Owner

@dtolnay dtolnay commented Oct 31, 2020

This enables the System V ABI to pass them in registers. See page 20 of https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf.

If a C++ object has either a non-trivial copy constructor or a non-trivial destructor11, it is passed by invisible reference (the object is replaced in the parameter list by a pointer that has class POINTER)12.

An object with either a non-trivial copy constructor or a non-trivial destructor cannot be passed by value because such objects must have well defined addresses. Similar issues apply when returning an object from a function.

Repro:

const char *ptr(rust::Str str) { return str.repr.ptr; }
size_t len(rust::Str str) { return str.repr.len; }

Before:

ptr(rust::Str):
        mov     rax, qword ptr [rdi]
        ret
len(rust::Str):
        mov     rax, qword ptr [rdi + 8]
        ret

After:

ptr(rust::Str):
        mov     rax, rdi
        ret
len(rust::Str):
        mov     rax, rsi
        ret

This change is also observable by std::is_trivially_copy_constructible<rust::Str>() (https://en.cppreference.com/w/cpp/types/is_copy_constructible) which lets us hit better fastpaths in libraries downstream.

Repro:

    const char *ptr(Str str) { return str.repr.ptr; }
    size_t len(Str str) { return str.repr.len; }

Before:

    ptr(Str):
        mov     rax, qword ptr [rdi]
        ret
    len(Str):
        mov     rax, qword ptr [rdi + 8]
        ret

After:

    ptr(Str):
        mov     rax, rdi
        ret
    len(Str):
        mov     rax, rsi
        ret
@dtolnay dtolnay merged commit a53086b into master Oct 31, 2020
@dtolnay dtolnay deleted the trivial branch October 31, 2020 19:31
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.

1 participant