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

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

Merged
merged 4 commits into from
Jun 30, 2013

Conversation

dotdash
Copy link
Contributor

@dotdash dotdash commented Jun 28, 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

@graydon
Copy link
Contributor

graydon commented Jun 28, 2013

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

@dotdash
Copy link
Contributor Author

dotdash commented Jun 28, 2013

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%.

Fixes rust-lang#4355, rust-lang#4402, rust-lang#5280, rust-lang#4406 and rust-lang#7285
@dotdash
Copy link
Contributor Author

dotdash commented Jun 29, 2013

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
@bors bors closed this Jun 30, 2013
@bors bors merged commit 765a290 into rust-lang:master Jun 30, 2013
flip1995 pushed a commit to flip1995/rust that referenced this pull request Jul 18, 2022
…ffate

Fixes for `branches_sharing_code`

fixes rust-lang#7198
fixes rust-lang#7452
fixes rust-lang#7555
fixes rust-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 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.

Passing an rvalue as ~self causes double-free
4 participants