-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Unwrap call of function passed to move_only_function
#5808
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
base: main
Are you sure you want to change the base?
Conversation
tests/std/tests/GH_005504_avoid_function_call_wrapping/test.cpp
Outdated
Show resolved
Hide resolved
|
Thanks! 😻 I've fully reviewed the product code, pushed a |
and mitigate possible future combinatorial explosion not fusing moves and destroys as they are distinct enough
I've pushed some simplifications to product code, and also expanded test coverage to actually test null functions and count allocations. |
Towards #5504.
One of the parts of the issue that can be addressed without having
copyable_function.✅ Coverage
Added just copy counter to see that the optimization works. It is copied zero times due to some core language optimization, but without the optimization it is copied once in the cases where it was missing.
Also added allocation counters to see that the other part of the optimization works.
Exercise different wrapping and also null functions.
⚙️ Optimization
Extract the inner
_Func_impl/_Func_impl_no_allocand use directly it without the containingfunction. This both gets call unwrapping and allocation avoidance.This change is only complicated in the current ABI. If in a future ABI it is possible to implement
functionthe same way thatmove_only_functionis implemented, things would be way easier.For 32-bit we can't easily avoid allocation of small function. The buffer of
functionis aligned tomax_align_tand the buffer insidemove_only_functionis aligned only asvoid*if it is next to vTable.move_only_functioncan contain objects ofmax_align_talignment, but in that case the buffer size would be smaller. As type erasure already happened by the time we havefunction, we can't query actual size or alignment.We probably could change
move_only_functionto make is emulated vtable the last pointer instead of the first, as we're not ABI-bound for/std:c++latestyet. But it doesn't look like a good idea, considering other, more commonmove_only_functionusage.❄️ Special cases
We throw
bad_function_call, and don't makemove_only_functioncontaining nullfunctionnull itself. Because the Standard is spelled out this way currently.If
functionis constructed insidemove_only_functionusingin_place_type, this optimization is not engaged.Also see #5806