Skip to content

Avoid double indirection for the "self" arg in methods - #7452

Merged
bors merged 4 commits into
rust-lang:masterfrom
dotdash:self_indirection
Jun 30, 2013
Merged

Avoid double indirection for the "self" arg in methods #7452
bors merged 4 commits into
rust-lang:masterfrom
dotdash:self_indirection

Conversation

@dotdash

Copy link
Copy Markdown
Contributor

Currently we pass all "self" arguments by reference, for the pointer
variants this means that we end up with double indirection which causes
a unnecessary performance hit.

The fix itself is pretty straight-forward and just means that "self"
needs to be handled like any other argument, except for by-value "self"
which still needs to be passed by reference. This is because
non-pointer types can't just be stuffed into the environment slot which
is used to pass "self".

What made things tricky is that there was also a bug in the typechecker
where the method map entries are created. For type impls, that stored
the base type instead of the actual self-type in the method map, e.g.
Foo instead of &Foo for &self. That worked with pass-by-reference, but
fails with pass-by-value which needs the real type.

Code that makes use of methods seems to be about 10% faster with this
change. Also, build times are reduced by about 4%.

Fixes#4355, #4402, #5280, #4406 and #7285

@graydon

Copy link
Copy Markdown
Contributor

Didn't someone just land the exact opposite of this change?

@dotdash

Copy link
Copy Markdown
ContributorAuthor

You're probably referring to #7410 by @luqmana which made "self" (without any sigil) be passed by reference. That's the one I keep as "by reference", as I mentioned in the commit/PR message.

Though I did revert a few changes from that commit that were required to tell the self and &@~self apart.

Edit: @luqmana did that, not @msullivan.

"self" is always passed as an opaque box, so there's no point in using
the concrete self type when translating the argument. All it does it
causing the value to be casted back to an opaque box right away.
The code that tried to revoke the cleanup for the self argument tried
to use "llself" to do so, but the cleanup might actually be registered
with a different ValueRef due to e.g. casting. Currently, this is
worked around by early revocation of the cleanup for self in
trans_self_arg.
To handle this correctly, we have to put the ValueRef for the cleanup
into the MethodData, so trans_call_inner can use it to revoke the
cleanup when it's actually supposed to.
Currently we pass all "self" arguments by reference, for the pointer
variants this means that we end up with double indirection which causes
a unnecessary performance hit.
The fix itself is pretty straight-forward and just means that "self"
needs to be handled like any other argument, except for by-value "self"
which still needs to be passed by reference. This is because
non-pointer types can't just be stuffed into the environment slot which
is used to pass "self".
What made things tricky is that there was also a bug in the typechecker
where the method map entries are created. For type impls, that stored
the base type instead of the actual self-type in the method map, e.g.
Foo instead of &Foo for &self. That worked with pass-by-reference, but
fails with pass-by-value which needs the real type.
Code that makes use of methods seems to be about 10% faster with this
change. Also, build times are reduced by about 4%.
Fixesrust-lang#4355, rust-lang#4402, rust-lang#5280, rust-lang#4406 and rust-lang#7285
@dotdash

Copy link
Copy Markdown
ContributorAuthor

Can't reproduce this failure locally, neither with x86_64 nor with a i686 cross compile. Interestingly, bors didn't add a link to the log of the test run that actually failed, which is http://buildbot.rust-lang.org/builders/auto-linux-32-opt/builds/174/steps/test/logs/stdio. Any ideas?

bors added a commit that referenced this pull request Jun 29, 2013
Currently we pass all "self" arguments by reference, for the pointer
variants this means that we end up with double indirection which causes
a unnecessary performance hit.
The fix itself is pretty straight-forward and just means that "self"
needs to be handled like any other argument, except for by-value "self"
which still needs to be passed by reference. This is because
non-pointer types can't just be stuffed into the environment slot which
is used to pass "self".
What made things tricky is that there was also a bug in the typechecker
where the method map entries are created. For type impls, that stored
the base type instead of the actual self-type in the method map, e.g.
Foo instead of &Foo for &self. That worked with pass-by-reference, but
fails with pass-by-value which needs the real type.
Code that makes use of methods seems to be about 10% faster with this
change. Also, build times are reduced by about 4%.
Fixes#4355, #4402, #5280, #4406 and #7285
@borsbors closed this Jun 30, 2013
@bors
bors merged commit 765a290 into rust-lang:masterJun 30, 2013
flip1995 pushed a commit to flip1995/rust that referenced this pull request Jul 18, 2022
…ffate
Fixes for `branches_sharing_code`
fixesrust-lang#7198fixesrust-lang#7452fixesrust-lang#7555fixesrust-lang#7589
changelog: Don't suggest moving modifications to locals used in any of the condition expressions in `branches_sharing_code`
changelog: Don't suggest moving anything after a local with a significant drop in `branches_sharing_code`
Sign up for freeto 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.

Passing an rvalue as ~self causes double-free

4 participants

@dotdash@graydon@emberian@bors